use seerdb::{DBOptions, DB};
use tempfile::TempDir;
#[test]
fn test_empty_iteration() {
let temp_dir = TempDir::new().unwrap();
let db = DB::open(temp_dir.path()).unwrap();
let mut iter = db.iter().unwrap();
assert!(iter.next().is_none());
}
#[test]
fn test_single_item_iteration() {
let temp_dir = TempDir::new().unwrap();
let db = DB::open(temp_dir.path()).unwrap();
db.put(b"key1", b"value1").unwrap();
let mut iter = db.iter().unwrap();
let (k, v) = iter.next().unwrap().unwrap();
assert_eq!(k, b"key1".as_slice());
assert_eq!(v, b"value1".as_slice());
assert!(iter.next().is_none());
}
#[test]
fn test_ordered_iteration() {
let temp_dir = TempDir::new().unwrap();
let db = DB::open(temp_dir.path()).unwrap();
db.put(b"key3", b"value3").unwrap();
db.put(b"key1", b"value1").unwrap();
db.put(b"key2", b"value2").unwrap();
let items: Vec<_> = db.iter().unwrap().map(|r| r.unwrap()).collect();
assert_eq!(items.len(), 3);
assert_eq!(items[0].0, b"key1".as_slice());
assert_eq!(items[1].0, b"key2".as_slice());
assert_eq!(items[2].0, b"key3".as_slice());
}
#[test]
fn test_range_scan() {
let temp_dir = TempDir::new().unwrap();
let db = DB::open(temp_dir.path()).unwrap();
for i in b'a'..=b'z' {
let key = vec![i];
let value = vec![i; 10];
db.put(&key, &value).unwrap();
}
let items: Vec<_> = db
.range(b"d", Some(b"g"))
.unwrap()
.map(|r| r.unwrap())
.collect();
assert_eq!(items.len(), 3); assert_eq!(items[0].0, b"d".as_slice());
assert_eq!(items[2].0, b"f".as_slice());
}
#[test]
fn test_iteration_across_sstables() {
let temp_dir = TempDir::new().unwrap();
let db = DBOptions::default()
.memtable_capacity(1024)
.open(temp_dir.path())
.unwrap();
for i in 0..1000 {
let key = format!("key_{:04}", i);
let value = vec![b'v'; 100];
db.put(key.as_bytes(), &value).unwrap();
}
db.flush().unwrap();
let count = db.iter().unwrap().count();
assert_eq!(count, 1000);
}
#[test]
fn test_iteration_includes_memtable() {
let temp_dir = TempDir::new().unwrap();
let db = DB::open(temp_dir.path()).unwrap();
db.put(b"key1", b"value1").unwrap();
db.flush().unwrap();
db.put(b"key2", b"value2").unwrap();
let items: Vec<_> = db.iter().unwrap().map(|r| r.unwrap()).collect();
assert_eq!(items.len(), 2);
}
#[test]
fn test_iteration_with_deletes() {
let temp_dir = TempDir::new().unwrap();
let db = DB::open(temp_dir.path()).unwrap();
db.put(b"key1", b"value1").unwrap();
db.put(b"key2", b"value2").unwrap();
db.put(b"key3", b"value3").unwrap();
db.delete(b"key2").unwrap();
let items: Vec<_> = db.iter().unwrap().map(|r| r.unwrap()).collect();
assert_eq!(items.len(), 2); assert_eq!(items[0].0, b"key1".as_slice());
assert_eq!(items[1].0, b"key3".as_slice());
}
#[test]
fn test_concurrent_iteration_and_writes() {
let temp_dir = TempDir::new().unwrap();
let db = DB::open(temp_dir.path()).unwrap();
for i in 0..100 {
db.put(format!("key_{:03}", i).as_bytes(), b"value")
.unwrap();
}
let iter = db.iter().unwrap();
for i in 100..200 {
db.put(format!("key_{:03}", i).as_bytes(), b"new_value")
.unwrap();
}
let count = iter.count();
assert!(count >= 100); }
#[test]
fn test_iteration_during_compaction() {
let temp_dir = TempDir::new().unwrap();
let db = DBOptions::default()
.memtable_capacity(1024)
.background_compaction(true)
.open(temp_dir.path())
.unwrap();
for i in 0..5000 {
db.put(format!("key_{:05}", i).as_bytes(), &vec![b'v'; 100])
.unwrap();
}
let count = db.iter().unwrap().count();
assert_eq!(count, 5000);
}
#[test]
fn test_iterator_invalidation_on_flush() {
let temp_dir = TempDir::new().unwrap();
let db = DB::open(temp_dir.path()).unwrap();
db.put(b"key1", b"value1").unwrap();
let mut iter = db.iter().unwrap();
db.flush().unwrap();
let (k, v) = iter.next().unwrap().unwrap();
assert_eq!(k, b"key1".as_slice());
assert_eq!(v, b"value1".as_slice());
}