persy 1.5.2

Transactional Persistence Engine
Documentation
use super::{Journal, JournalId, StartList};
use crate::journal::{
    records::{
        Commit, CreateSegment, DeleteRecord, DropSegment, InsertRecord, Metadata, NewSegmentPage, PrepareCommit,
        ReadRecord, RollbackPage, UpdateRecord,
    },
    recover_impl::RecoverImpl,
    JournalEntry,
};
use crate::{
    allocator::Allocator,
    config::Config,
    config::TxStrategy,
    device::MemoryDevice,
    id::{RecRef, SegmentId},
    io::ArcSliceRead,
};

use std::sync::Arc;

#[test]
fn start_list_add_remove() {
    let mut start = StartList::new();
    start.push(&JournalId::new(1, 2));
    start.push(&JournalId::new(1, 4));
    assert!(start.remove(&JournalId::new(1, 2)));
    assert!(start.remove(&JournalId::new(1, 4)));

    start.push(&JournalId::new(1, 2));
    start.push(&JournalId::new(1, 4));
    assert!(!start.remove(&JournalId::new(1, 4)));
    assert!(start.remove(&JournalId::new(1, 2)));
}

#[test]
fn start_list_add_remove_other_order() {
    let mut start = StartList::new();
    start.push(&JournalId::new(1, 1));
    start.push(&JournalId::new(1, 2));
    assert!(!start.remove(&JournalId::new(1, 2)));
    start.push(&JournalId::new(1, 3));
    assert!(!start.remove(&JournalId::new(1, 3)));
    assert!(start.remove(&JournalId::new(1, 1)));
}

#[test]
fn journal_log_and_recover() {
    let disc = Box::new(MemoryDevice::new(None).unwrap());
    let (_, allocator) = Allocator::init(disc, &Config::new()).unwrap();
    let rp = Journal::init(&allocator).unwrap();
    allocator.disc_sync().unwrap();
    let journal = Journal::new(&Arc::new(allocator), rp).unwrap();
    let seg_id = SegmentId::new(10);
    let rec = InsertRecord::new(seg_id, &RecRef::new(1, 1), 1);
    let id = journal.start().unwrap();
    journal.log(&rec, &id).unwrap();
    journal.log(&rec, &id).unwrap();
    journal.log(&PrepareCommit::new(), &id).unwrap();
    journal.end(&Commit::new(), &id).unwrap();
    let mut recover = RecoverImpl::default();
    journal.recover(&mut recover).unwrap();
    recover.finish_journal_read();
    assert_eq!(recover.list_transactions().len(), 1);
}

#[test]
fn read_write_insert_record() {
    let mut buffer = Vec::<u8>::new();
    let seg_id = SegmentId::new(10);
    let to_write = InsertRecord::new(seg_id, &RecRef::new(20, 10), 3);

    to_write.write(&mut buffer).unwrap();

    let mut to_read = InsertRecord::default();
    let len = buffer.len();
    let mut reader = ArcSliceRead::new_vec(buffer);
    to_read.read(&mut reader).unwrap();
    assert_eq!(reader.cursor(), len);
    assert_eq!(to_read.segment, seg_id);
    assert_eq!(to_read.recref.page, 20);
    assert_eq!(to_read.recref.pos, 10);
    assert_eq!(to_read.record_page, 3);
}

#[test]
fn read_write_insert_read() {
    let mut buffer = Vec::<u8>::new();
    let seg_id = SegmentId::new(10);
    let to_write = ReadRecord::new(seg_id, &RecRef::new(20, 10), 3);

    to_write.write(&mut buffer).unwrap();

    let mut to_read = ReadRecord::default();
    let len = buffer.len();
    let mut reader = ArcSliceRead::new_vec(buffer);
    to_read.read(&mut reader).unwrap();
    assert_eq!(reader.cursor(), len);
    assert_eq!(to_read.segment, seg_id);
    assert_eq!(to_read.recref.page, 20);
    assert_eq!(to_read.recref.pos, 10);
    assert_eq!(to_read.version, 3);
}

#[test]
fn read_write_update_record() {
    let mut buffer = Vec::<u8>::new();
    let seg_id = SegmentId::new(10);
    let to_write = UpdateRecord::new(seg_id, &RecRef::new(20, 10), 3, 1);

    to_write.write(&mut buffer).unwrap();

    let mut to_read = UpdateRecord::default();
    let len = buffer.len();
    let mut reader = ArcSliceRead::new_vec(buffer);
    to_read.read(&mut reader).unwrap();
    assert_eq!(reader.cursor(), len);
    assert_eq!(to_read.segment, seg_id);
    assert_eq!(to_read.recref.page, 20);
    assert_eq!(to_read.recref.pos, 10);
    assert_eq!(to_read.record_page, 3);
    assert_eq!(to_read.version, 1);
}

#[test]
fn read_write_delete_record() {
    let mut buffer = Vec::<u8>::new();
    let seg_id = SegmentId::new(10);
    let to_write = DeleteRecord::new(seg_id, &RecRef::new(20, 10), 1);

    to_write.write(&mut buffer).unwrap();

    let mut to_read = DeleteRecord::default();
    let len = buffer.len();
    let mut reader = ArcSliceRead::new_vec(buffer);
    to_read.read(&mut reader).unwrap();
    assert_eq!(reader.cursor(), len);
    assert_eq!(to_read.segment, seg_id);
    assert_eq!(to_read.recref.page, 20);
    assert_eq!(to_read.recref.pos, 10);
    assert_eq!(to_read.version, 1);
}

#[test]
fn read_write_create_segment() {
    let mut buffer = Vec::<u8>::new();
    let seg_id = SegmentId::new(10);
    let to_write = CreateSegment::new("some", seg_id, 20);
    to_write.write(&mut buffer).unwrap();
    let mut to_read = CreateSegment::default();
    let len = buffer.len();
    let mut reader = ArcSliceRead::new_vec(buffer);
    to_read.read(&mut reader).unwrap();
    assert_eq!(reader.cursor(), len);
    assert_eq!(to_read.name, "some");
    assert_eq!(to_read.segment_id, seg_id);
    assert_eq!(to_read.first_page, 20);
}

#[test]
fn read_write_drop_segment() {
    let mut buffer = Vec::<u8>::new();
    let seg_id = SegmentId::new(20);
    let to_write = DropSegment::new("some", seg_id);
    to_write.write(&mut buffer).unwrap();
    let mut to_read = DropSegment::default();
    let len = buffer.len();
    let mut reader = ArcSliceRead::new_vec(buffer);
    to_read.read(&mut reader).unwrap();
    assert_eq!(reader.cursor(), len);
    assert_eq!(to_read.name, "some");
    assert_eq!(to_read.segment_id, seg_id);
}

#[test]
fn read_write_metadata() {
    let mut buffer = Vec::<u8>::new();
    let meta_id = vec![10, 3];
    let to_write = Metadata::new(&TxStrategy::VersionOnWrite, meta_id.clone());
    to_write.write(&mut buffer).unwrap();
    let mut to_read = Metadata::new(&TxStrategy::LastWin, Vec::new());
    let len = buffer.len();
    let mut reader = ArcSliceRead::new_vec(buffer);
    to_read.read(&mut reader).unwrap();
    assert_eq!(reader.cursor(), len);
    assert_eq!(to_read.strategy, TxStrategy::VersionOnWrite);
    assert_eq!(to_read.meta_id, meta_id);
}

#[test]
fn read_write_new_segment_page() {
    let mut buffer = Vec::<u8>::new();
    let seg_id = SegmentId::new(10);
    let to_write = NewSegmentPage::new(seg_id, 20, 30);
    to_write.write(&mut buffer).unwrap();
    let mut to_read = NewSegmentPage::default();
    let len = buffer.len();
    let mut reader = ArcSliceRead::new_vec(buffer);
    to_read.read(&mut reader).unwrap();
    assert_eq!(reader.cursor(), len);
    assert_eq!(to_read.segment, seg_id);
    assert_eq!(to_read.page, 20);
    assert_eq!(to_read.previous, 30);
}

#[test]
fn read_write_rollback_page() {
    let mut buffer = Vec::<u8>::new();
    let seg_id = SegmentId::new(10);
    let to_write = RollbackPage::new(seg_id, &RecRef::new(20, 10), 3);

    to_write.write(&mut buffer).unwrap();

    let mut to_read = RollbackPage::default();
    let len = buffer.len();
    let mut reader = ArcSliceRead::new_vec(buffer);
    to_read.read(&mut reader).unwrap();
    assert_eq!(reader.cursor(), len);
    assert_eq!(to_read.segment, seg_id);
    assert_eq!(to_read.recref.page, 20);
    assert_eq!(to_read.recref.pos, 10);
    assert_eq!(to_read.record_page, 3);
}