diff --git a/src/adapters/mod.rs b/src/adapters/mod.rs index 43b686e..af5fa2b 100644 --- a/src/adapters/mod.rs +++ b/src/adapters/mod.rs @@ -1,8 +1,8 @@ pub use self::{ btreemap::ParkingLotRwLockBTreeMapTable, btreemap::StdRwLockBTreeMapTable, chashmap::CHashMapTable, contrie::ContrieTable, crossbeam_skiplist::CrossbeamSkipMapTable, - dashmap::DashMapTable, evmap::EvmapTable, flurry::FlurryTable, scc::SccMapTable, - std::ParkingLotRwLockStdHashMapTable, std::StdRwLockStdHashMapTable, + dashmap::DashMapTable, evmap::EvmapTable, flurry::FlurryTable, scc::SccIndexTable, + scc::SccMapTable, std::ParkingLotRwLockStdHashMapTable, std::StdRwLockStdHashMapTable, }; mod btreemap; diff --git a/src/adapters/scc.rs b/src/adapters/scc.rs index 7c26889..0af4e3f 100644 --- a/src/adapters/scc.rs +++ b/src/adapters/scc.rs @@ -1,25 +1,23 @@ +use bustle::*; use std::hash::{BuildHasher, Hash}; use std::sync::Arc; use super::Value; -use bustle::*; -use scc::hash_map::{Entry, HashMap}; #[derive(Clone)] -pub struct SccMapTable(Arc>) -where - K: Eq + Hash, - H: BuildHasher; +pub struct SccMapTable( + Arc>, +); impl Collection for SccMapTable where - K: Send + Sync + From + Copy + 'static + Hash + Eq + std::fmt::Debug, - H: BuildHasher + Default + Send + Sync + 'static + Clone, + K: Send + Sync + From + Copy + Hash + Ord + 'static, + H: BuildHasher + Default + Send + Sync + Clone + 'static, { type Handle = Self; fn with_capacity(capacity: usize) -> Self { - Self(Arc::new(HashMap::with_capacity_and_hasher( + Self(Arc::new(scc::HashMap::with_capacity_and_hasher( capacity, H::default(), ))) @@ -32,13 +30,13 @@ where impl CollectionHandle for SccMapTable where - K: Send + Sync + From + Copy + 'static + Hash + Eq + std::fmt::Debug, - H: BuildHasher + Default + Send + Sync + 'static + Clone, + K: Send + Sync + From + Copy + Hash + Ord + 'static, + H: BuildHasher + Default + Send + Sync + Clone + 'static, { type Key = K; fn get(&mut self, key: &Self::Key) -> bool { - self.0.read(key, |_, v| *v).is_some() + self.0.read(key, |_, _| ()).is_some() } fn insert(&mut self, key: &Self::Key) -> bool { @@ -50,12 +48,62 @@ where } fn update(&mut self, key: &Self::Key) -> bool { - match self.0.entry(*key) { - Entry::Occupied(mut v) => { - *v.get_mut() += 1; - true + self.0.update(key, |_, v| *v += 1).is_some() + } +} + +#[derive(Clone)] +pub struct SccIndexTable( + Arc>, +); + +impl Collection for SccIndexTable +where + K: Send + Sync + From + Copy + Hash + Ord + 'static, + H: BuildHasher + Default + Send + Sync + Clone + 'static, +{ + type Handle = Self; + + fn with_capacity(capacity: usize) -> Self { + Self(Arc::new(scc::HashIndex::with_capacity_and_hasher( + capacity, + H::default(), + ))) + } + + fn pin(&self) -> Self::Handle { + self.clone() + } +} + +impl CollectionHandle for SccIndexTable +where + K: Send + Sync + From + Copy + Hash + Ord + 'static, + H: BuildHasher + Default + Send + Sync + Clone + 'static, +{ + type Key = K; + + fn get(&mut self, key: &Self::Key) -> bool { + self.0.peek_with(key, |_, _| ()).is_some() + } + + fn insert(&mut self, key: &Self::Key) -> bool { + self.0.insert(*key, 0).is_ok() + } + + fn remove(&mut self, key: &Self::Key) -> bool { + self.0.remove(key) + } + + fn update(&mut self, key: &Self::Key) -> bool { + if let scc::hash_index::Entry::Occupied(mut o) = self.0.entry(*key) { + unsafe { + let val = o.get_mut(); + *val += 1; } - Entry::Vacant(_) => false, + true + } else { + false } } } diff --git a/src/bench.rs b/src/bench.rs index 7f7541e..a9a549c 100644 --- a/src/bench.rs +++ b/src/bench.rs @@ -121,6 +121,7 @@ where case::>("Evmap", options, h); case::>("Contrie", options, h); case::>("SccMap", options, h); + case::>("SccIndex", options, h); } pub fn bench(options: &Options) {