diff --git a/presets/stores/mutex_btreemap.toml b/presets/stores/mutex_btreemap.toml new file mode 100644 index 0000000..4467454 --- /dev/null +++ b/presets/stores/mutex_btreemap.toml @@ -0,0 +1,2 @@ +[map] +name = "mutex_btreemap" diff --git a/presets/stores/rwlock_btreemap.toml b/presets/stores/rwlock_btreemap.toml new file mode 100644 index 0000000..59111b7 --- /dev/null +++ b/presets/stores/rwlock_btreemap.toml @@ -0,0 +1,2 @@ +[map] +name = "rwlock_btreemap" diff --git a/src/bench.rs b/src/bench.rs index 361ec71..f286fc9 100644 --- a/src/bench.rs +++ b/src/bench.rs @@ -902,7 +902,7 @@ mod tests { } #[test] - fn example_mutex() { + fn example_mutex_hashmap() { const OPT: &str = include_str!(concat!( env!("CARGO_MANIFEST_DIR"), "/presets/stores/mutex_hashmap.toml" @@ -911,7 +911,7 @@ mod tests { } #[test] - fn example_rwlock() { + fn example_rwlock_hashmap() { const OPT: &str = include_str!(concat!( env!("CARGO_MANIFEST_DIR"), "/presets/stores/rwlock_hashmap.toml" @@ -972,6 +972,24 @@ mod tests { )); example(OPT); } + + #[test] + fn example_mutex_btreemap() { + const OPT: &str = include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/presets/stores/mutex_btreemap.toml" + )); + example(OPT); + } + + #[test] + fn example_rwlock_btreemap() { + const OPT: &str = include_str!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/presets/stores/rwlock_btreemap.toml" + )); + example(OPT); + } } // }}} tests diff --git a/src/server.rs b/src/server.rs index 61069e5..8055a4e 100644 --- a/src/server.rs +++ b/src/server.rs @@ -905,14 +905,14 @@ mod tests { } #[test] - fn batch_mutex() { + fn batch_mutex_hashmap() { let opt = hashmap::MutexHashMapOpt { shards: 512 }; let map = BenchKVMap::Regular(Box::new(hashmap::MutexHashMap::new(&opt))); batch(map); } #[test] - fn batch_rwlock() { + fn batch_rwlock_hashmap() { let opt = hashmap::RwLockHashMapOpt { shards: 512 }; let map = BenchKVMap::Regular(Box::new(hashmap::RwLockHashMap::new(&opt))); batch(map); @@ -953,4 +953,16 @@ mod tests { let map = BenchKVMap::Regular(Box::new(papaya::Papaya::new())); batch(map); } + + #[test] + fn batch_mutex_btreemap() { + let map = BenchKVMap::Regular(Box::new(btreemap::MutexBTreeMap::new())); + batch(map); + } + + #[test] + fn batch_rwlock_btreemap() { + let map = BenchKVMap::Regular(Box::new(btreemap::RwLockBTreeMap::new())); + batch(map); + } } diff --git a/src/stores/btreemap.rs b/src/stores/btreemap.rs new file mode 100644 index 0000000..d709f2c --- /dev/null +++ b/src/stores/btreemap.rs @@ -0,0 +1,109 @@ +//! Adapter implementation of [`std::collections::BTreeMap`]. +//! +//! ## Configuration Format +//! +//! ### [`Mutex`]-based: +//! +//! ``` toml +//! [map] +//! name = "mutex_btreemap" +//! ``` +//! +//! This store is [`KVMap`]. +//! +//! ### [`RwLock`]-based: +//! ``` toml +//! [map] +//! name = "rwlock_btreemap" +//! ``` +//! +//! This store is [`KVMap`]. + +use crate::stores::*; +use parking_lot::{Mutex, RwLock}; +use std::collections::BTreeMap; +use std::sync::Arc; + +#[derive(Clone)] +pub struct MutexBTreeMap(Arc, Box<[u8]>>>>); + +impl MutexBTreeMap { + pub fn new() -> Self { + Self(Arc::new( + Mutex::new(BTreeMap::, Box<[u8]>>::new()), + )) + } + + pub fn new_benchkvmap(_opt: &toml::Table) -> BenchKVMap { + BenchKVMap::Regular(Box::new(Self::new())) + } +} + +impl KVMap for MutexBTreeMap { + fn handle(&self) -> Box { + Box::new(self.clone()) + } +} + +impl KVMapHandle for MutexBTreeMap { + fn set(&mut self, key: &[u8], value: &[u8]) { + self.0.lock().insert(key.into(), value.into()); + } + + fn get(&mut self, key: &[u8]) -> Option> { + match self.0.lock().get(key) { + Some(v) => Some(v.clone()), + None => None, + } + } + + fn delete(&mut self, key: &[u8]) { + self.0.lock().remove(key); + } +} + +inventory::submit! { + Registry::new("mutex_btreemap", MutexBTreeMap::new_benchkvmap) +} + +#[derive(Clone)] +pub struct RwLockBTreeMap(Arc, Box<[u8]>>>>); + +impl RwLockBTreeMap { + pub fn new() -> Self { + Self(Arc::new(RwLock::new( + BTreeMap::, Box<[u8]>>::new(), + ))) + } + + pub fn new_benchkvmap(_opt: &toml::Table) -> BenchKVMap { + BenchKVMap::Regular(Box::new(Self::new())) + } +} + +impl KVMap for RwLockBTreeMap { + fn handle(&self) -> Box { + Box::new(self.clone()) + } +} + +impl KVMapHandle for RwLockBTreeMap { + fn set(&mut self, key: &[u8], value: &[u8]) { + self.0.write().insert(key.into(), value.into()); + } + + fn get(&mut self, key: &[u8]) -> Option> { + match self.0.read().get(key) { + Some(v) => Some(v.clone()), + None => None, + } + } + + fn delete(&mut self, key: &[u8]) { + self.0.write().remove(key); + } +} + +inventory::submit! { + Registry::new("rwlock_btreemap", RwLockBTreeMap::new_benchkvmap) +} diff --git a/src/stores/hashmap.rs b/src/stores/hashmap.rs index e4c031f..489037c 100644 --- a/src/stores/hashmap.rs +++ b/src/stores/hashmap.rs @@ -1,5 +1,4 @@ -//! Adapter implementation of [`hashbrown::HashMap`]. Sharded, and in flavors of both [`Mutex`] and -//! [`RwLock`]. +//! Adapter implementation of [`hashbrown::HashMap`]. Internally sharded. //! //! ## Configuration Format //! diff --git a/src/stores/mod.rs b/src/stores/mod.rs index 0630cd2..dd54520 100644 --- a/src/stores/mod.rs +++ b/src/stores/mod.rs @@ -114,6 +114,7 @@ impl BenchKVMap { } } +pub mod btreemap; pub mod chashmap; pub mod contrie; pub mod dashmap; @@ -199,4 +200,16 @@ mod tests { let mut map = papaya::Papaya::new(); map_test(&mut map); } + + #[test] + fn mutex_btreemap() { + let mut map = btreemap::MutexBTreeMap::new(); + map_test(&mut map); + } + + #[test] + fn rwlock_btreemap() { + let mut map = btreemap::RwLockBTreeMap::new(); + map_test(&mut map); + } }