diff --git a/src/stores.rs b/src/stores.rs index a062a61..8e98fed 100644 --- a/src/stores.rs +++ b/src/stores.rs @@ -38,25 +38,10 @@ use crate::bench::Benchmark; use crate::*; -use ahash::AHasher; use hashbrown::HashMap; use log::debug; -use std::hash::Hasher; use toml::Table; -pub fn hash(key: &[u8]) -> u64 { - let mut hasher = AHasher::default(); - hasher.write(key); - u64::from(hasher.finish()) -} - -pub fn find_shard(key: &[u8], nr_shards: usize) -> usize { - let mut hasher = AHasher::default(); - hasher.write(key); - let hash = u64::from(hasher.finish()); - usize::try_from(hash).unwrap() % nr_shards -} - /// A unified enum for a created key-value store that is ready to run. pub enum BenchKVMap { Regular(Box), diff --git a/src/stores/hashmap.rs b/src/stores/hashmap.rs index 489037c..1719fde 100644 --- a/src/stores/hashmap.rs +++ b/src/stores/hashmap.rs @@ -21,12 +21,27 @@ //! //! This store is [`KVMap`]. -use crate::stores::*; +use crate::stores::{BenchKVMap, Registry}; +use crate::*; use ::hashbrown::HashMap; +use ahash::AHasher; use parking_lot::{Mutex, RwLock}; use serde::Deserialize; +use std::hash::Hasher; use std::sync::Arc; +/// Calculate the [`u64`] hash value of a given key using [`AHasher`]. +pub fn hash(key: &[u8]) -> u64 { + let mut hasher = AHasher::default(); + hasher.write(key); + u64::from(hasher.finish()) +} + +pub fn shard(key: &[u8], nr_shards: usize) -> usize { + let hash = hash(key); + usize::try_from(hash).unwrap() % nr_shards +} + /// A wrapper around raw [`HashMap`] with variable-sized keys and values. /// /// It is used as the building block of other types. Note that this is not [`KVMap`]. @@ -68,12 +83,12 @@ impl KVMap for MutexHashMap { impl KVMapHandle for MutexHashMap { fn set(&mut self, key: &[u8], value: &[u8]) { - let sid = find_shard(key, self.nr_shards); + let sid = shard(key, self.nr_shards); self.shards[sid].lock().insert(key.into(), value.into()); } fn get(&mut self, key: &[u8]) -> Option> { - let sid = find_shard(key, self.nr_shards); + let sid = shard(key, self.nr_shards); match self.shards[sid].lock().get(key) { Some(v) => Some(v.clone()), None => None, @@ -81,7 +96,7 @@ impl KVMapHandle for MutexHashMap { } fn delete(&mut self, key: &[u8]) { - let sid = find_shard(key, self.nr_shards); + let sid = shard(key, self.nr_shards); self.shards[sid].lock().remove(key); } } @@ -130,12 +145,12 @@ impl KVMap for RwLockHashMap { impl KVMapHandle for RwLockHashMap { fn set(&mut self, key: &[u8], value: &[u8]) { - let sid = find_shard(key, self.nr_shards); + let sid = shard(key, self.nr_shards); self.shards[sid].write().insert(key.into(), value.into()); } fn get(&mut self, key: &[u8]) -> Option> { - let sid = find_shard(key, self.nr_shards); + let sid = shard(key, self.nr_shards); match self.shards[sid].read().get(key) { Some(v) => Some(v.clone()), None => None, @@ -143,7 +158,7 @@ impl KVMapHandle for RwLockHashMap { } fn delete(&mut self, key: &[u8]) { - let sid = find_shard(key, self.nr_shards); + let sid = shard(key, self.nr_shards); self.shards[sid].write().remove(key); } } diff --git a/src/thread.rs b/src/thread.rs index de61924..ceebc9b 100644 --- a/src/thread.rs +++ b/src/thread.rs @@ -4,8 +4,8 @@ //! //! A key-value store is generally passive. However, some store may act like a server with //! active threads. In that case, one may employ its own implementation of spawn-join. If that is -//! the case, their join handle (like `[std::thread::JoinHandle`]) should implement the -//! [`JoinHandle`] trait and the spawn struct needs to implement `[Spawn]`. +//! the case, their join handle (like [`std::thread::JoinHandle`]) should implement the +//! [`JoinHandle`] trait and the spawn struct needs to implement [`Spawn]`. //! //! Note that for simplicity, the function spawn is generic over should not have a return value. So //! it is with the [`JoinHandle`]. Because the purpose is not general spawn-join but solely for