use ahash::{AHashMap, AHashSet};
use parking_lot::RwLock;
pub type I64Map<V> = crate::common::i64_map::I64Map<V>;
pub type I64Set = crate::common::i64_map::I64Set;
pub type StringMap<V> = AHashMap<String, V>;
pub type StringSet = AHashSet<String>;
pub type CowBTreeMap<V> = RwLock<crate::common::CowBTree<V>>;
#[inline]
pub fn new_i64_map<V>() -> I64Map<V> {
crate::common::i64_map::I64Map::new()
}
#[inline]
pub fn new_i64_map_with_capacity<V>(capacity: usize) -> I64Map<V> {
crate::common::i64_map::I64Map::with_capacity(capacity)
}
#[inline]
pub fn new_cow_btree_map<V: Clone>() -> CowBTreeMap<V> {
RwLock::new(crate::common::CowBTree::new())
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Arc;
use std::thread;
#[test]
fn test_i64_map_basic() {
let mut map: I64Map<String> = new_i64_map();
map.insert(1, "one".to_string());
map.insert(2, "two".to_string());
map.insert(-1, "negative".to_string());
map.insert(i64::MIN + 1, "near_min".to_string());
map.insert(i64::MAX, "max".to_string());
assert_eq!(map.get(1), Some(&"one".to_string()));
assert_eq!(map.get(-1), Some(&"negative".to_string()));
assert_eq!(map.get(i64::MIN + 1), Some(&"near_min".to_string()));
assert_eq!(map.get(i64::MAX), Some(&"max".to_string()));
map.remove(2);
assert!(!map.contains_key(2));
assert_eq!(map.len(), 4);
}
#[test]
fn test_i64_map_with_capacity() {
let map: I64Map<i32> = new_i64_map_with_capacity(100);
assert!(map.capacity() >= 100);
}
#[test]
fn test_i64_set() {
let mut set = I64Set::default();
set.insert(1);
set.insert(2);
set.insert(3);
assert!(set.contains(1));
assert!(set.contains(2));
assert!(!set.contains(4));
set.remove(2);
assert!(!set.contains(2));
}
#[test]
fn test_cow_btree_map() {
let map: CowBTreeMap<String> = new_cow_btree_map();
map.write().insert(3, "three".to_string());
map.write().insert(1, "one".to_string());
map.write().insert(2, "two".to_string());
assert_eq!(map.read().get(1), Some(&"one".to_string()));
assert_eq!(map.read().len(), 3);
let snapshot = map.read().clone(); let keys: Vec<i64> = snapshot.keys().collect();
assert_eq!(keys, vec![1, 2, 3]);
map.write().insert(4, "four".to_string());
assert_eq!(snapshot.len(), 3); assert_eq!(map.read().len(), 4); }
#[test]
fn test_cow_btree_map_multithreaded() {
let map: Arc<CowBTreeMap<i64>> = Arc::new(new_cow_btree_map());
let num_threads: i64 = 4;
let ops_per_thread: i64 = 100;
let write_handles: Vec<_> = (0..num_threads)
.map(|t| {
let map = Arc::clone(&map);
thread::spawn(move || {
let base = t * ops_per_thread;
for i in 0..ops_per_thread {
map.write().insert(base + i, (base + i) * 2);
}
})
})
.collect();
let read_handles: Vec<_> = (0..num_threads)
.map(|_| {
let map = Arc::clone(&map);
thread::spawn(move || {
for _ in 0..100 {
let snapshot = map.read().clone(); let _count = snapshot.iter().count(); }
})
})
.collect();
for handle in write_handles {
handle.join().unwrap();
}
for handle in read_handles {
handle.join().unwrap();
}
assert_eq!(map.read().len(), (num_threads * ops_per_thread) as usize);
}
}