-use std::hash::{Hasher, Hash};
-use std::mem;
+use crate::fx::{FxHashMap, FxHasher};
+use crate::sync::{Lock, LockGuard};
+use smallvec::SmallVec;
use std::borrow::Borrow;
use std::collections::hash_map::RawEntryMut;
-use smallvec::SmallVec;
-use crate::fx::{FxHasher, FxHashMap};
-use crate::sync::{Lock, LockGuard};
+use std::hash::{Hash, Hasher};
+use std::mem;
#[derive(Clone, Default)]
#[cfg_attr(parallel_compiler, repr(align(64)))]
#[inline]
pub fn new(mut value: impl FnMut() -> T) -> Self {
// Create a vector of the values we want
- let mut values: SmallVec<[_; SHARDS]> = (0..SHARDS).map(|_| {
- CacheAligned(Lock::new(value()))
- }).collect();
+ let mut values: SmallVec<[_; SHARDS]> =
+ (0..SHARDS).map(|_| CacheAligned(Lock::new(value()))).collect();
// Create an unintialized array
let mut shards: mem::MaybeUninit<[CacheAligned<Lock<T>>; SHARDS]> =
// Ignore the content of the vector
values.set_len(0);
- Sharded {
- shards: shards.assume_init(),
- }
+ Sharded { shards: shards.assume_init() }
}
}
+ /// The shard is selected by hashing `val` with `FxHasher`.
#[inline]
pub fn get_shard_by_value<K: Hash + ?Sized>(&self, val: &K) -> &Lock<T> {
- if SHARDS == 1 {
- &self.shards[0].0
- } else {
- self.get_shard_by_hash(make_hash(val))
- }
+ if SHARDS == 1 { &self.shards[0].0 } else { self.get_shard_by_hash(make_hash(val)) }
}
+ /// Get a shard with a pre-computed hash value. If `get_shard_by_value` is
+ /// ever used in combination with `get_shard_by_hash` on a single `Sharded`
+ /// instance, then `hash` must be computed with `FxHasher`. Otherwise,
+ /// `hash` can be computed with any hasher, so long as that hasher is used
+ /// consistently for each `Sharded` instance.
#[inline]
pub fn get_shard_by_hash(&self, hash: u64) -> &Lock<T> {
let hash_len = mem::size_of::<usize>();
impl<K: Eq + Hash + Copy> ShardedHashMap<K, ()> {
#[inline]
pub fn intern_ref<Q: ?Sized>(&self, value: &Q, make: impl FnOnce() -> K) -> K
- where K: Borrow<Q>,
- Q: Hash + Eq
+ where
+ K: Borrow<Q>,
+ Q: Hash + Eq,
{
let hash = make_hash(value);
let mut shard = self.get_shard_by_hash(hash).lock();
#[inline]
pub fn intern<Q>(&self, value: Q, make: impl FnOnce(Q) -> K) -> K
- where K: Borrow<Q>,
- Q: Hash + Eq
+ where
+ K: Borrow<Q>,
+ Q: Hash + Eq,
{
let hash = make_hash(&value);
let mut shard = self.get_shard_by_hash(hash).lock();