use crate::{
id::{RecRef, SegmentId},
journal::{records::FreedPage, JournalId},
snapshot::data::{Change, CleanInfo, EntryCase, RecordVersion, SegmentSnapshot, SnapshotEntry},
snapshots::{search, to_mapping, InternalSnapshots},
};
use std::cmp::Ordering;
#[test]
fn test_search() {
assert_eq!(search(10, 20, 40), Ordering::Less);
assert_eq!(search(20, 10, 40), Ordering::Greater);
assert_eq!(search(10, 30, 20), Ordering::Greater);
assert_eq!(search(30, 10, 20), Ordering::Less);
assert_eq!(search(20, 20, 20), Ordering::Equal);
assert_eq!(search(20, 19, 20), Ordering::Greater);
assert_eq!(search(20, 21, 20), Ordering::Greater);
assert_eq!(search(21, 21, 20), Ordering::Equal);
assert_eq!(search(19, 19, 20), Ordering::Equal);
}
#[test]
fn add_and_read() {
let mut snap = InternalSnapshots::default();
let mut records = Vec::new();
let mut freed_pages = Vec::new();
for x in 0..3 {
records.push(SnapshotEntry::change(&RecRef::new(10, x), x as u64, x as u16));
freed_pages.push(FreedPage::new(x as u64));
}
let tx = snap.snapshot(
records.clone(),
CleanInfo::new(freed_pages.clone(), Vec::new()),
JournalId::new(0, 0),
);
snap.clear_from(tx);
let tx = snap.snapshot(records, CleanInfo::new(freed_pages, Vec::new()), JournalId::new(0, 0));
assert_eq!(
snap.read(tx - 1, &RecRef::new(10, 2)),
Some(RecordVersion::new(1, EntryCase::Change(Change { pos: 2, version: 2 }),))
);
assert_eq!(
snap.read(tx - 1, &RecRef::new(10, 1)),
Some(RecordVersion::new(1, EntryCase::Change(Change { pos: 1, version: 1 }),))
);
assert_eq!(
snap.read(tx, &RecRef::new(10, 2)),
Some(RecordVersion::new(1, EntryCase::Change(Change { pos: 2, version: 2 }),))
);
assert_eq!(snap.read(tx + 1, &RecRef::new(10, 2)), None);
assert_eq!(snap.read(tx + 1, &RecRef::new(10, 10)), None);
}
#[test]
fn add_and_read_multiple_tx() {
let mut snap = InternalSnapshots::default();
let mut txs = Vec::new();
for t in 0..5 {
let mut records = Vec::new();
let mut freed_pages = Vec::new();
for x in 0..10 {
if x != t {
records.push(SnapshotEntry::change(
&RecRef::new(10, x),
(10 * t + x) as u64,
(10 * t + x) as u16,
));
freed_pages.push(FreedPage::new((10 * t + x) as u64));
}
}
txs.push(snap.snapshot(records, CleanInfo::new(freed_pages, Vec::new()), JournalId::new(0, 0)));
}
assert_eq!(
snap.read(txs[2], &RecRef::new(10, 2)),
Some(RecordVersion::new(
txs[3],
EntryCase::Change(Change { pos: 32, version: 32 })
),)
);
assert_eq!(
snap.read(txs[3], &RecRef::new(10, 3)),
Some(RecordVersion::new(
txs[4],
EntryCase::Change(Change { pos: 43, version: 43 }),
))
);
}
#[test]
fn test_snapshot_reference_count() {
let mut snap = InternalSnapshots::default();
let mut records = Vec::new();
let mut freed_pages = Vec::new();
for x in 0..3 {
records.push(SnapshotEntry::change(&RecRef::new(10, x), x as u64, x as u16));
freed_pages.push(FreedPage::new(x as u64));
}
let first = snap.read_snapshot();
let tx = snap.snapshot(
records.clone(),
CleanInfo::new(freed_pages, Vec::new()),
JournalId::new(0, 0),
);
let last = snap.read_snapshot();
snap.release(tx);
assert_eq!(
snap.read(first, &RecRef::new(10, 2)),
Some(RecordVersion::new(1, EntryCase::Change(Change { pos: 2, version: 2 }),))
);
snap.release(first);
assert_eq!(snap.read(last, &RecRef::new(10, 2)), None);
}
#[test]
fn test_clanup_after_release() {
let mut snap = InternalSnapshots::default();
let mut snapshots_id = Vec::new();
for s in 0..100 {
let mut records = Vec::new();
let mut freed_pages = Vec::new();
for x in 0..3 {
records.push(SnapshotEntry::change(&RecRef::new(s % 10, x), x as u64, x as u16));
freed_pages.push(FreedPage::new(x as u64));
}
let tx = snap.snapshot(
records.clone(),
CleanInfo::new(freed_pages, Vec::new()),
JournalId::new(0, 0),
);
snapshots_id.push(tx);
}
for s in snapshots_id.into_iter().rev() {
snap.release(s);
}
{
assert_eq!(snap.active_snapshots(), 0);
assert_eq!(snap.mapping_count(), 0);
}
let mut snapshots_id = Vec::new();
for s in 0..100 {
let mut records = Vec::new();
let mut freed_pages = Vec::new();
for x in 0..3 {
records.push(SnapshotEntry::change(&RecRef::new(s % 10, x), x as u64, x as u16));
freed_pages.push(FreedPage::new(x as u64));
}
let tx = snap.snapshot(
records.clone(),
CleanInfo::new(freed_pages, Vec::new()),
JournalId::new(0, 0),
);
snapshots_id.push(tx);
}
for s in snapshots_id {
snap.release(s);
}
assert_eq!(snap.active_snapshots(), 0);
assert_eq!(snap.mapping_count(), 0);
}
#[test]
fn test_snapshot_release_clear() {
let mut snap = InternalSnapshots::default();
let mut snaps = Vec::new();
for i in 0..10 {
let id = snap.read_snapshot();
let mut segments = Vec::new();
let seg_id = SegmentId::new(i);
segments.push(SegmentSnapshot::new("one", seg_id, i.into()));
segments.push(SegmentSnapshot::new("two", seg_id, i.into()));
let (segments_id, segments_name) = to_mapping(&segments);
snap.fill_segments(id, segments_id, segments_name);
snaps.push(id);
}
snap.release(snaps[0]);
snap.release(snaps[1]);
snap.release(snaps[2]);
let solved = snap.solve_segment_id(snaps[3], "one");
assert_eq!(solved, Some(SegmentId::new(3)));
assert_eq!(snap.active_snapshots(), 7);
}
#[test]
pub fn test_segment_snapshot_fill() {
let mut snap = InternalSnapshots::default();
let id = snap.read_snapshot();
let mut segments = Vec::new();
let seg_id = SegmentId::new(10);
segments.push(SegmentSnapshot::new("one", seg_id, 10));
let (segments_id, segments_name) = to_mapping(&segments);
snap.fill_segments(id, segments_id, segments_name);
let solved = snap.solve_segment_id(id, "one");
assert_eq!(solved, Some(seg_id));
let solved = snap.solve_segment_name(id, seg_id);
assert_eq!(solved, Some("one".to_string()));
let solved = snap.solve_segment_id(id, "two");
assert_eq!(solved, None);
let solved = snap.scan(id, seg_id);
assert!(solved.is_some());
snap.release(id);
}
#[test]
pub fn test_segment_snapshot_fill_multiple() {
let mut snap = InternalSnapshots::default();
let mut snaps = Vec::new();
for i in 0..10 {
let id = snap.read_snapshot();
let mut segments = Vec::new();
let seg_id = SegmentId::new(i);
segments.push(SegmentSnapshot::new("one", seg_id, i.into()));
segments.push(SegmentSnapshot::new("two", seg_id, i.into()));
let (segments_id, segments_name) = to_mapping(&segments);
snap.fill_segments(id, segments_id, segments_name);
snaps.push(id);
}
let solved = snap.solve_segment_id(snaps[3], "one");
assert_eq!(solved, Some(SegmentId::new(3)));
let solved = snap.solve_segment_id(snaps[3], "two");
assert_eq!(solved, Some(SegmentId::new(3)));
let solved = snap.solve_segment_id(snaps[6], "one");
assert_eq!(solved, Some(SegmentId::new(6)));
let solved = snap.solve_segment_id(snaps[6], "two");
assert_eq!(solved, Some(SegmentId::new(6)));
}