blob: 3addb18759ab3c1e617d599d307e4b0b56e174c3 [file] [log] [blame]
use {
crate::{
lsm_tree::{
merge::{MergeIterator, MergeResult},
skip_list_layer::SkipListLayer,
types::{Item, Layer, MutableLayer, OrdLowerBound},
LSMTree,
},
testing::fake_object::{FakeObject, FakeObjectHandle},
},
anyhow::Error,
fuchsia_async as fasync,
std::{
ops::Bound,
rc::Rc,
sync::{Arc, Mutex},
},
};
fn merge<K: std::fmt::Debug, V: std::fmt::Debug>(
_left: &MergeIterator<'_, K, V>,
_right: &MergeIterator<'_, K, V>,
) -> MergeResult<K, V> {
MergeResult::EmitLeft
}
#[derive(Eq, PartialEq, PartialOrd, Ord, Debug, serde::Serialize, serde::Deserialize)]
struct TestKey(i32);
impl OrdLowerBound for TestKey {
fn cmp_lower_bound(&self, other: &Self) -> std::cmp::Ordering {
std::cmp::Ord::cmp(self, other)
}
}
#[fasync::run_singlethreaded(test)]
async fn test_lsm_tree_commit() -> Result<(), Error> {
let object1 = Arc::new(Mutex::new(FakeObject::new()));
let object2 = Arc::new(Mutex::new(FakeObject::new()));
let tree = LSMTree::<TestKey, u8>::new(merge);
tree.insert(Item::new(TestKey(1), 2)).await;
tree.insert(Item::new(TestKey(3), 4)).await;
let object_handle = FakeObjectHandle::new(object1.clone());
tree.seal();
tree.compact(object_handle).await?;
tree.insert(Item::new(TestKey(2), 5)).await;
let object_handle = FakeObjectHandle::new(object2.clone());
tree.seal();
tree.compact(object_handle).await?;
let mut merger = tree.range_from(std::ops::Bound::Unbounded).await?;
assert_eq!(merger.get().unwrap().key, &TestKey(1));
merger.advance().await?;
assert_eq!(merger.get().unwrap().key, &TestKey(2));
merger.advance().await?;
assert_eq!(merger.get().unwrap().key, &TestKey(3));
merger.advance().await?;
assert!(merger.get().is_none());
Ok(())
}
#[fasync::run_singlethreaded(test)]
async fn test_skip_list() -> Result<(), Error> {
let mut skip_list = Rc::new(SkipListLayer::new(100));
let sl = Rc::get_mut(&mut skip_list).unwrap();
sl.merge_into(Item::new(TestKey(1), 1), &TestKey(1), merge).await;
{
let mut iter = sl.get_iterator();
iter.seek(Bound::Included(&TestKey(1))).await?;
assert_eq!(iter.get().unwrap().key, &TestKey(1));
}
sl.merge_into(Item::new(TestKey(2), 1), &TestKey(2), merge).await;
sl.merge_into(Item::new(TestKey(3), 1), &TestKey(3), merge).await;
let mut iter = skip_list.get_iterator();
iter.seek(Bound::Included(&TestKey(2))).await?;
assert_eq!(iter.get().unwrap().key, &TestKey(2));
iter.advance().await?;
assert_eq!(iter.get().unwrap().key, &TestKey(3));
iter.advance().await?;
assert!(iter.get().is_none());
let mut iter = skip_list.get_iterator();
iter.seek(Bound::Included(&TestKey(1))).await?;
assert_eq!(iter.get().unwrap().key, &TestKey(1));
Ok(())
}
#[fasync::run_singlethreaded(test)]
async fn test_skip_list_with_large_number_of_items() -> Result<(), Error> {
let mut skip_list = Rc::new(SkipListLayer::new(100));
let sl = Rc::get_mut(&mut skip_list).unwrap();
let item_count = 10;
for i in 1..item_count {
sl.merge_into(Item::new(TestKey(i), 1), &TestKey(i), merge).await;
}
let mut iter = skip_list.get_iterator();
iter.seek(Bound::Included(&TestKey(item_count - 2))).await?;
for i in item_count - 2..item_count {
assert_eq!(iter.get().unwrap().key, &TestKey(i));
iter.advance().await?;
}
assert!(iter.get().is_none());
Ok(())
}