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);
}