use crate::utils::{db_put_simple, open_database, tmpdir};
use leveldb::database::slice::Slice;
use leveldb::iterator::{
BoundedKeyPolicy, Context, EntryIterator, EntryIteratorRev, Iterable, KeyIterator,
LevelDBIterator, ValueIterator,
};
use leveldb::options::ReadOptions;
#[test]
fn test_iterator() {
let tmp = tmpdir("iter");
let database = &mut open_database(tmp.path(), true);
db_put_simple(database, &[1], &[1]);
db_put_simple(database, &[2], &[2]);
let mut iter: EntryIterator<'_> = database.iter(ReadOptions::new());
let entry = iter.next();
assert!(entry.is_some());
let (key1, val1) = entry.unwrap();
assert_eq!(key1.as_bytes(), &[1]);
assert_eq!(val1.as_bytes(), &[1]);
let entry2 = iter.next();
assert!(entry2.is_some());
let (key2, val2) = entry2.unwrap();
assert_eq!(key2.as_bytes(), &[2]);
assert_eq!(val2.as_bytes(), &[2]);
assert!(iter.next().is_none());
assert!(iter.get_error().is_none());
}
#[test]
fn test_iterator_reverse() {
let tmp = tmpdir("iter");
let database = &mut open_database(tmp.path(), true);
db_put_simple(database, &[1], &[1]);
db_put_simple(database, &[2], &[2]);
let mut iter: EntryIteratorRev<'_> = database.iter(ReadOptions::new());
let entry = iter.next();
assert!(entry.is_some());
let (key1, val1) = entry.unwrap();
assert_eq!(key1.as_bytes(), &[2]);
assert_eq!(val1.as_bytes(), &[2]);
let entry2 = iter.next();
assert!(entry2.is_some());
let (key2, val2) = entry2.unwrap();
assert_eq!(key2.as_bytes(), &[1]);
assert_eq!(val2.as_bytes(), &[1]);
assert!(iter.next().is_none());
}
#[test]
fn test_iterator_last() {
let tmp = tmpdir("iter_last");
let database = &mut open_database(tmp.path(), true);
db_put_simple(database, &[1], &[1]);
db_put_simple(database, &[2], &[2]);
let iter: EntryIterator<'_> = database.iter(ReadOptions::new());
let last_entry = iter.last();
assert!(last_entry.is_some());
let (key, value) = last_entry.unwrap();
assert_eq!(key.as_bytes(), &[2]);
assert_eq!(value.as_bytes(), &[2]);
}
#[test]
fn test_key_iterator_last() {
let tmp = tmpdir("key_iter_last");
let database = &mut open_database(tmp.path(), true);
db_put_simple(database, &[1], b"a");
db_put_simple(database, &[2], b"b");
let iter: KeyIterator<'_> = database.iter(ReadOptions::new());
let last_key = iter.last();
assert!(last_key.is_some());
let key = last_key.unwrap();
assert_eq!(key.as_bytes(), &[2]);
}
#[test]
fn test_value_iterator_last() {
let tmp = tmpdir("value_iter_last");
let database = &mut open_database(tmp.path(), true);
db_put_simple(database, &[1], b"a");
db_put_simple(database, &[2], b"b");
let iter: ValueIterator<'_> = database.iter(ReadOptions::new());
let last_value = iter.last();
assert!(last_value.is_some());
let value = last_value.unwrap();
assert_eq!(value.as_bytes(), b"b");
}
#[test]
fn test_iterator_error_handling() {
let tmp = tmpdir("iter_error");
let database = &mut open_database(tmp.path(), true);
db_put_simple(database, &[1], b"test");
let read_opts: ReadOptions<'_> = ReadOptions::new();
let mut iter: EntryIterator<'_> = database.iter(read_opts);
assert!(iter.get_error().is_none());
while iter.next().is_some() {}
assert!(iter.get_error().is_none());
}
#[test]
fn test_iterator_from_to() {
let tmp = tmpdir("from_to");
let database = &mut open_database(tmp.path(), true);
db_put_simple(database, &[1], &[1]);
db_put_simple(database, &[2], &[2]);
db_put_simple(database, &[3], &[3]);
db_put_simple(database, &[4], &[4]);
db_put_simple(database, &[5], &[5]);
let begin = &[2][..];
let end = &[4][..];
let policy = BoundedKeyPolicy::new(Some(Slice::from(begin)), Some(Slice::from(end)));
let mut iter: EntryIterator<'_, _> = database.iter_with_policy(ReadOptions::new(), policy);
iter.seek(&Slice::from(begin));
let (key1, val1) = iter.next().unwrap();
assert_eq!(key1.as_bytes(), &[2]);
assert_eq!(val1.as_bytes(), &[2]);
let (key2, val2) = iter.last().unwrap();
assert_eq!(key2.as_bytes(), &[3]);
assert_eq!(val2.as_bytes(), &[3]);
}
#[test]
fn test_iterator_bounded_next() {
let tmp = tmpdir("from_to");
let database = &mut open_database(tmp.path(), true);
db_put_simple(database, &[1], &[1]);
db_put_simple(database, &[2], &[2]);
db_put_simple(database, &[3], &[3]);
db_put_simple(database, &[4], &[4]);
db_put_simple(database, &[5], &[5]);
let begin = &[2][..];
let end = &[4][..];
let policy = BoundedKeyPolicy::new(Some(Slice::from(begin)), Some(Slice::from(end)));
let iter: EntryIterator<'_, _> = database.iter_with_policy(ReadOptions::new(), policy);
iter.seek(&Slice::from(begin));
let mut keys = vec![];
for (k, _) in iter {
let mut bytes = [0];
bytes.copy_from_slice(k.as_bytes());
keys.push(bytes);
}
assert_eq!(keys, vec![[2], [3]]);
}
#[test]
fn test_iterator_bounded_next_2() {
let tmp = tmpdir("from_to");
let database = &mut open_database(tmp.path(), true);
db_put_simple(database, &[1], &[1]);
db_put_simple(database, &[3], &[3]);
db_put_simple(database, &[5], &[5]);
db_put_simple(database, &[7], &[7]);
db_put_simple(database, &[9], &[9]);
let begin = &[2][..];
let end = &[6][..];
let policy = BoundedKeyPolicy::new(Some(Slice::from(begin)), Some(Slice::from(end)));
let iter: EntryIterator<'_, _> = database.iter_with_policy(ReadOptions::new(), policy);
iter.seek(&Slice::from(begin));
let mut keys = vec![];
for (k, _) in iter {
let mut bytes = [0];
bytes.copy_from_slice(k.as_bytes());
keys.push(bytes);
}
assert_eq!(keys, vec![[3], [5]]);
}
#[test]
fn test_iterator_bounded_next_3() {
let tmp = tmpdir("from_to");
let database = &mut open_database(tmp.path(), true);
db_put_simple(database, &[2], &[2]);
db_put_simple(database, &[3], &[3]);
db_put_simple(database, &[4], &[4]);
db_put_simple(database, &[5], &[5]);
db_put_simple(database, &[6], &[6]);
let begin = &[1][..];
let end = &[7][..];
let policy = BoundedKeyPolicy::new(Some(Slice::from(begin)), Some(Slice::from(end)));
let iter: EntryIterator<'_, _> = database.iter_with_policy(ReadOptions::new(), policy);
iter.seek(&Slice::from(begin));
let mut keys = vec![];
for (k, _) in iter {
let mut bytes = [0];
bytes.copy_from_slice(k.as_bytes());
keys.push(bytes);
}
assert_eq!(keys, vec![[2], [3], [4], [5], [6]]);
}
#[test]
fn test_iterator_bounded_next_4() {
let tmp = tmpdir("from_to");
let database = &mut open_database(tmp.path(), true);
db_put_simple(database, &[2], &[2]);
db_put_simple(database, &[3], &[3]);
db_put_simple(database, &[4], &[4]);
db_put_simple(database, &[5], &[5]);
db_put_simple(database, &[6], &[6]);
let begin = &[1][..];
let end = &[5][..];
let policy = BoundedKeyPolicy::new(Some(Slice::from(begin)), Some(Slice::from(end)));
let iter: EntryIterator<'_, _> = database.iter_with_policy(ReadOptions::new(), policy);
iter.seek(&Slice::from(begin));
let mut keys = vec![];
for (k, _) in iter {
let mut bytes = [0];
bytes.copy_from_slice(k.as_bytes());
keys.push(bytes);
}
assert_eq!(keys, vec![[2], [3], [4]]);
}
#[test]
fn test_iterator_bounded_next_5() {
let tmp = tmpdir("from_to");
let database = &mut open_database(tmp.path(), true);
db_put_simple(database, &[2], &[2]);
db_put_simple(database, &[3], &[3]);
db_put_simple(database, &[4], &[4]);
db_put_simple(database, &[5], &[5]);
db_put_simple(database, &[6], &[6]);
let begin = &[4][..];
let end = &[7][..];
let policy = BoundedKeyPolicy::new(Some(Slice::from(begin)), Some(Slice::from(end)));
let iter: EntryIterator<'_, _> = database.iter_with_policy(ReadOptions::new(), policy);
iter.seek(&Slice::from(begin));
let mut keys = vec![];
for (k, _) in iter {
let mut bytes = [0];
bytes.copy_from_slice(k.as_bytes());
keys.push(bytes);
}
assert_eq!(keys, vec![[4], [5], [6]]);
}
#[test]
fn test_iterator_bounded_next_6() {
let tmp = tmpdir("from_to");
let database = &mut open_database(tmp.path(), true);
db_put_simple(database, &[1], &[1]);
let begin = &[2][..];
let end = &[3][..];
let policy = BoundedKeyPolicy::new(Some(Slice::from(begin)), Some(Slice::from(end)));
let iter: EntryIterator<'_, _> = database.iter_with_policy(ReadOptions::new(), policy);
iter.seek(&Slice::from(begin));
let mut keys = vec![];
for (k, _) in iter {
let mut bytes = [0];
bytes.copy_from_slice(k.as_bytes());
keys.push(bytes);
}
assert!(keys.is_empty());
}
#[test]
fn test_iterator_bounded_next_7() {
let tmp = tmpdir("from_to");
let database = &mut open_database(tmp.path(), true);
db_put_simple(database, &[3], &[3]);
let begin = &[1][..];
let end = &[2][..];
let policy = BoundedKeyPolicy::new(Some(Slice::from(begin)), Some(Slice::from(end)));
let iter: EntryIterator<'_, _> = database.iter_with_policy(ReadOptions::new(), policy);
iter.seek(&Slice::from(begin));
let mut keys = vec![];
for (k, _) in iter {
let mut bytes = [0];
bytes.copy_from_slice(k.as_bytes());
keys.push(bytes);
}
assert!(keys.is_empty());
}
#[test]
fn test_key_iterator() {
let tmp = tmpdir("key_iter");
let database = &mut open_database(tmp.path(), true);
db_put_simple(database, &[1], &[1]);
db_put_simple(database, &[2], &[2]);
let mut iter: KeyIterator<'_> = database.iter(ReadOptions::new());
let value = iter.next().unwrap();
assert_eq!(value.as_bytes(), &[1]);
}
#[test]
fn test_value_iterator() {
let tmp = tmpdir("value_iter");
let database = &mut open_database(tmp.path(), true);
db_put_simple(database, &[1], &[1]);
db_put_simple(database, &[2], &[2]);
let mut iter: ValueIterator<'_> = database.iter(ReadOptions::new());
let value = iter.next().unwrap();
assert_eq!(value.as_bytes(), &[1]);
}
#[test]
fn test_seek_before_inserted() {
let tmp = tmpdir("iter");
let database = &mut open_database(tmp.path(), true);
db_put_simple(database, &[1], &[1]);
db_put_simple(database, &[2], &[2]);
let iter: EntryIterator<'_> = database.iter(ReadOptions::new());
iter.seek(&Slice::from(&[0][..]));
assert!(iter.valid());
assert_eq!(unsafe { iter.key() }.unwrap().as_bytes(), &[1][..]);
}
#[test]
fn test_seek_after_inserted() {
let tmp = tmpdir("iter");
let database = &mut open_database(tmp.path(), true);
db_put_simple(database, &[1], &[1]);
db_put_simple(database, &[2], &[2]);
let iter: EntryIterator<'_> = database.iter(ReadOptions::new());
iter.seek(&Slice::from(&[3][..]));
assert!(!iter.valid());
}