#[cfg(feature = "var-collections")]
use armdb::VarTree;
use armdb::{Config, ConstTree};
use tempfile::tempdir;
#[test]
fn test_const_put_get() {
let dir = tempdir().unwrap();
let tree = ConstTree::<[u8; 8], 8>::open(dir.path(), Config::test()).unwrap();
for i in 0..10u64 {
let key = i.to_be_bytes();
let value = (i * 100).to_be_bytes();
tree.put(&key, &value).unwrap();
}
for i in 0..10u64 {
let key = i.to_be_bytes();
let expected = (i * 100).to_be_bytes();
let got = tree.get(&key).expect("key should exist");
assert_eq!(got, expected, "mismatch at key {i}");
}
}
#[test]
fn test_const_overwrite() {
let dir = tempdir().unwrap();
let tree = ConstTree::<[u8; 8], 8>::open(dir.path(), Config::test()).unwrap();
let key = 1u64.to_be_bytes();
let value_a = 100u64.to_be_bytes();
let value_b = 200u64.to_be_bytes();
tree.put(&key, &value_a).unwrap();
assert_eq!(tree.get(&key).unwrap(), value_a);
tree.put(&key, &value_b).unwrap();
assert_eq!(tree.get(&key).unwrap(), value_b);
}
#[test]
fn test_const_delete() {
let dir = tempdir().unwrap();
let tree = ConstTree::<[u8; 8], 8>::open(dir.path(), Config::test()).unwrap();
let key = 42u64.to_be_bytes();
let value = 99u64.to_be_bytes();
tree.put(&key, &value).unwrap();
assert!(tree.get(&key).is_some());
let deleted = tree.delete(&key).unwrap();
assert!(
deleted.is_some(),
"delete should return Some for existing key"
);
assert_eq!(deleted.unwrap(), value);
assert!(tree.get(&key).is_none(), "get after delete should be None");
}
#[test]
fn test_const_delete_missing() {
let dir = tempdir().unwrap();
let tree = ConstTree::<[u8; 8], 8>::open(dir.path(), Config::test()).unwrap();
let key = 999u64.to_be_bytes();
let deleted = tree.delete(&key).unwrap();
assert!(
deleted.is_none(),
"delete of missing key should return None"
);
}
#[test]
fn test_const_contains() {
let dir = tempdir().unwrap();
let tree = ConstTree::<[u8; 8], 8>::open(dir.path(), Config::test()).unwrap();
let key = 7u64.to_be_bytes();
let value = 77u64.to_be_bytes();
assert!(!tree.contains(&key), "should not contain before put");
tree.put(&key, &value).unwrap();
assert!(tree.contains(&key), "should contain after put");
tree.delete(&key).unwrap();
assert!(!tree.contains(&key), "should not contain after delete");
}
#[test]
fn test_const_prefix_iter() {
let dir = tempdir().unwrap();
let tree = ConstTree::<[u8; 8], 8>::open(dir.path(), Config::test()).unwrap();
let key1: [u8; 8] = [0x00, 0x01, 0, 0, 0, 0, 0, 0];
let key2: [u8; 8] = [0x00, 0x02, 0, 0, 0, 0, 0, 0];
let key3: [u8; 8] = [0x01, 0x01, 0, 0, 0, 0, 0, 0];
let val1 = 1u64.to_be_bytes();
let val2 = 2u64.to_be_bytes();
let val3 = 3u64.to_be_bytes();
tree.put(&key1, &val1).unwrap();
tree.put(&key2, &val2).unwrap();
tree.put(&key3, &val3).unwrap();
let entries = tree.prefix_iter(&[0x00]).collect_vec();
assert_eq!(entries.len(), 2, "prefix 0x00 should match 2 entries");
let keys: Vec<[u8; 8]> = entries.iter().map(|(k, _)| *k).collect();
assert!(keys.contains(&key1));
assert!(keys.contains(&key2));
let entries_01 = tree.prefix_iter(&[0x01]).collect_vec();
assert_eq!(entries_01.len(), 1, "prefix 0x01 should match 1 entry");
assert_eq!(entries_01[0].0, key3);
}
#[test]
fn test_const_len() {
let dir = tempdir().unwrap();
let tree = ConstTree::<[u8; 8], 8>::open(dir.path(), Config::test()).unwrap();
assert_eq!(tree.len(), 0);
assert!(tree.is_empty());
for i in 0..5u64 {
let key = i.to_be_bytes();
let value = i.to_be_bytes();
tree.put(&key, &value).unwrap();
}
assert_eq!(tree.len(), 5);
assert!(!tree.is_empty());
let key = 2u64.to_be_bytes();
let new_value = 222u64.to_be_bytes();
tree.put(&key, &new_value).unwrap();
assert_eq!(tree.len(), 5, "overwrite should not change len");
tree.delete(&0u64.to_be_bytes()).unwrap();
assert_eq!(tree.len(), 4);
}
#[cfg(feature = "var-collections")]
#[test]
fn test_var_put_get() {
let dir = tempdir().unwrap();
let tree = VarTree::<[u8; 8]>::open(dir.path(), Config::test()).unwrap();
for i in 0..10u64 {
let key = i.to_be_bytes();
let value: Vec<u8> = vec![i as u8; (i as usize) + 1];
tree.put(&key, &value).unwrap();
}
for i in 0..10u64 {
let key = i.to_be_bytes();
let expected: Vec<u8> = vec![i as u8; (i as usize) + 1];
let got = tree.get(&key).expect("key should exist");
assert_eq!(got.as_bytes(), expected.as_slice(), "mismatch at key {i}");
}
}
#[cfg(feature = "var-collections")]
#[test]
fn test_var_overwrite() {
let dir = tempdir().unwrap();
let tree = VarTree::<[u8; 8]>::open(dir.path(), Config::test()).unwrap();
let key = 1u64.to_be_bytes();
let value_a = b"hello";
let value_b = b"world!!!";
tree.put(&key, value_a).unwrap();
assert_eq!(tree.get(&key).unwrap().as_bytes(), value_a);
tree.put(&key, value_b).unwrap();
assert_eq!(tree.get(&key).unwrap().as_bytes(), value_b);
}
#[cfg(feature = "var-collections")]
#[test]
fn test_var_delete() {
let dir = tempdir().unwrap();
let tree = VarTree::<[u8; 8]>::open(dir.path(), Config::test()).unwrap();
let key = 42u64.to_be_bytes();
let value = b"to be deleted";
tree.put(&key, value).unwrap();
assert!(tree.get(&key).is_some());
let deleted = tree.delete(&key).unwrap();
assert!(deleted, "delete should return true for existing key");
assert!(tree.get(&key).is_none(), "get after delete should be None");
}
#[cfg(feature = "var-collections")]
#[test]
fn test_var_contains() {
let dir = tempdir().unwrap();
let tree = VarTree::<[u8; 8]>::open(dir.path(), Config::test()).unwrap();
let key = 7u64.to_be_bytes();
let value = b"present";
assert!(!tree.contains(&key), "should not contain before put");
tree.put(&key, value).unwrap();
assert!(tree.contains(&key), "should contain after put");
tree.delete(&key).unwrap();
assert!(!tree.contains(&key), "should not contain after delete");
}
#[cfg(feature = "var-collections")]
#[test]
fn test_var_prefix_iter() {
let dir = tempdir().unwrap();
let tree = VarTree::<[u8; 8]>::open(dir.path(), Config::test()).unwrap();
let key1: [u8; 8] = [0x00, 0x01, 0, 0, 0, 0, 0, 0];
let key2: [u8; 8] = [0x00, 0x02, 0, 0, 0, 0, 0, 0];
let key3: [u8; 8] = [0x01, 0x01, 0, 0, 0, 0, 0, 0];
tree.put(&key1, b"val1").unwrap();
tree.put(&key2, b"val2").unwrap();
tree.put(&key3, b"val3").unwrap();
let keys = tree.prefix_iter(&[0x00]).collect_keys();
assert_eq!(keys.len(), 2, "prefix 0x00 should match 2 keys");
assert!(keys.contains(&key1));
assert!(keys.contains(&key2));
let entries = tree.prefix_iter(&[0x00]).collect_entries();
assert_eq!(entries.len(), 2, "prefix 0x00 should match 2 entries");
let entry_keys: Vec<[u8; 8]> = entries.iter().map(|(k, _)| *k).collect();
assert!(entry_keys.contains(&key1));
assert!(entry_keys.contains(&key2));
for (k, v) in &entries {
if *k == key1 {
assert_eq!(v.as_bytes(), b"val1");
} else if *k == key2 {
assert_eq!(v.as_bytes(), b"val2");
}
}
let keys_01 = tree.prefix_iter(&[0x01]).collect_keys();
assert_eq!(keys_01.len(), 1);
assert_eq!(keys_01[0], key3);
}
#[cfg(feature = "var-collections")]
#[test]
fn test_var_large_value() {
let dir = tempdir().unwrap();
let tree = VarTree::<[u8; 8]>::open(dir.path(), Config::test()).unwrap();
let key = 1u64.to_be_bytes();
let value: Vec<u8> = (0..1000).map(|i| (i % 256) as u8).collect();
tree.put(&key, &value).unwrap();
let got = tree.get(&key).expect("large value should be retrievable");
assert_eq!(got.len(), 1000);
assert_eq!(got.as_bytes(), value.as_slice());
}
#[cfg(feature = "var-collections")]
#[test]
fn test_var_inline_value() {
let dir = tempdir().unwrap();
let tree = VarTree::<[u8; 8]>::open(dir.path(), Config::test()).unwrap();
let key = 2u64.to_be_bytes();
let value: [u8; 10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
tree.put(&key, &value).unwrap();
let got = tree.get(&key).expect("inline value should be retrievable");
assert_eq!(got.len(), 10);
assert_eq!(got.as_bytes(), &value);
}