persy 1.5.2

Transactional Persistence Engine
Documentation
use super::Address;
use crate::id::SegmentId;
use crate::journal::records::{CreateSegment, DeleteRecord, InsertRecord, UpdateRecord};
use crate::transaction::tx_impl::SegmentOperation;
use crate::{
    address::SegmentPageRead,
    allocator::Allocator,
    config::Config,
    device::{MemoryDevice, ReadPage},
};
use std::collections::HashMap;
use std::sync::Arc;

fn init_test_address() -> (Address, SegmentId) {
    let config = Arc::new(Config::new());
    let disc = Box::new(MemoryDevice::new(None).unwrap());
    let (_, allocator) = Allocator::init(disc, &config).unwrap();
    let page = Address::init(&allocator).unwrap();
    allocator.disc_sync().unwrap();
    let addr = Address::new(&Arc::new(allocator), &config, page).unwrap();
    let seg = addr.create_temp_segment("def").unwrap();
    let id = seg.get_segment_id();
    addr.segments.write().unwrap().finalize_create_segment(seg);
    (addr, id)
}

#[test]
fn test_init_and_new_address() {
    let (add, segment_id) = init_test_address();
    assert_eq!(
        add.segments
            .read()
            .unwrap()
            .segment_by_id(segment_id)
            .unwrap()
            .last_page,
        1152
    );
    assert_eq!(
        add.segments.read().unwrap().segment_by_id(segment_id).unwrap().last_pos,
        26
    );
}

#[test]
fn test_insert_update_delete_read_apply_pointer() {
    let (add, segment_id) = init_test_address();
    let (recref, _) = add.allocate(segment_id).unwrap();
    add.insert(segment_id, &recref, 10).unwrap();
    let (recref_1, _) = add.allocate(segment_id).unwrap();
    add.insert(segment_id, &recref_1, 20).unwrap();

    let mut inserted = Vec::new();
    let (recref_2, _) = add.allocate(segment_id).unwrap();
    inserted.push(InsertRecord::new(segment_id, &recref_2, 30));

    let mut updated = Vec::new();
    updated.push(UpdateRecord::new(segment_id, &recref_1, 40, 1));

    let mut deleted = Vec::new();

    deleted.push(DeleteRecord::new(segment_id, &recref, 1));
    let mut seg_ops = Vec::new();
    seg_ops.push(SegmentOperation::Create(CreateSegment::new(
        "def",
        SegmentId::new(20),
        20,
    )));
    let mut c = HashMap::new();
    add.apply(&[], &inserted, &updated, &deleted, &seg_ops, &mut c, false)
        .unwrap();

    let read = add.read(&recref, segment_id).unwrap();
    let read_1 = add.read(&recref_1, segment_id).unwrap();
    let read_2 = add.read(&recref_2, segment_id).unwrap();
    match read {
        Some(_) => assert!(false),
        None => assert!(true),
    }
    match read_1 {
        Some(val) => assert_eq!(val.0, 40),
        None => assert!(false),
    }
    match read_2 {
        Some(val) => assert_eq!(val.0, 30),
        None => assert!(false),
    }
}

#[test]
fn test_insert_scan() {
    let (add, segment_id) = init_test_address();
    let (recref, _) = add.allocate(segment_id).unwrap();
    add.insert(segment_id, &recref, 10).unwrap();
    let (recref_1, _) = add.allocate(segment_id).unwrap();
    add.insert(segment_id, &recref_1, 20).unwrap();
    let mut to_iter = add.scan(segment_id).unwrap();
    let mut count = 0;
    while to_iter.next(&add).is_some() {
        count += 1;
    }
    assert_eq!(count, 2);
    let mut iter = add.scan(segment_id).unwrap();
    let re = iter.next(&add).unwrap();
    assert_eq!(re.page, recref.page);
    assert_eq!(re.pos, recref.pos);
    let re_1 = iter.next(&add).unwrap();
    assert_eq!(re_1.page, recref_1.page);
    assert_eq!(re_1.pos, recref_1.pos);
}

#[test]
fn test_insert_over_page() {
    let (add, segment_id) = init_test_address();
    for z in 0..1000 {
        let (recref, _) = add.allocate(segment_id).unwrap();
        add.insert(segment_id, &recref, z).unwrap();
    }
    let mut to_iter = add.scan(segment_id).unwrap();
    let mut count = 0;
    while to_iter.next(&add).is_some() {
        count += 1;
    }
    assert_eq!(count, 1000);
}

#[test]
fn test_page_correct_size() {
    let page = ReadPage::new(Arc::new(Vec::new()), 2, 1024, 10);
    assert_eq!(page.possible_entries(), 90);
}