mirror of https://github.com/xacrimon/dashmap
fix: remove manual inline attributes, llvm knows this better than me and this will reduce binary size by a decent amount where not needed
This commit is contained in:
parent
aff9eb407f
commit
64e4e960db
|
@ -51,7 +51,6 @@ type GuardOwningIter<K, V> = hash_map::IntoIter<K, SharedValue<V>>;
|
|||
impl<K: Eq + Hash, V, S: BuildHasher + Clone> Iterator for OwningIter<K, V, S> {
|
||||
type Item = (K, V);
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
loop {
|
||||
if let Some(current) = self.current.as_mut() {
|
||||
|
@ -153,7 +152,6 @@ impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> Iter
|
|||
{
|
||||
type Item = RefMulti<'a, K, V, S>;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
loop {
|
||||
if let Some(current) = self.current.as_mut() {
|
||||
|
@ -229,7 +227,6 @@ impl<'a, K: Eq + Hash, V, S: 'a + BuildHasher + Clone, M: Map<'a, K, V, S>> Iter
|
|||
{
|
||||
type Item = RefMutMulti<'a, K, V, S>;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
loop {
|
||||
if let Some(current) = self.current.as_mut() {
|
||||
|
|
|
@ -15,7 +15,6 @@ impl<K: Eq + Hash, S: BuildHasher + Clone> OwningIter<K, S> {
|
|||
impl<K: Eq + Hash, S: BuildHasher + Clone> Iterator for OwningIter<K, S> {
|
||||
type Item = K;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.inner.next().map(|(k, _)| k)
|
||||
}
|
||||
|
@ -66,7 +65,6 @@ impl<'a, K: Eq + Hash, S: 'a + BuildHasher + Clone, M: Map<'a, K, (), S>> Iterat
|
|||
{
|
||||
type Item = RefMulti<'a, K, S>;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.inner.next().map(RefMulti::new)
|
||||
}
|
||||
|
|
85
src/lib.rs
85
src/lib.rs
|
@ -50,12 +50,10 @@ cfg_if! {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn shard_amount() -> usize {
|
||||
(num_cpus::get() * 4).next_power_of_two()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn ncb(shard_amount: usize) -> usize {
|
||||
shard_amount.trailing_zeros() as usize
|
||||
}
|
||||
|
@ -94,7 +92,6 @@ where
|
|||
K: Eq + Hash,
|
||||
S: Default + BuildHasher + Clone,
|
||||
{
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
Self::with_hasher(Default::default())
|
||||
}
|
||||
|
@ -111,7 +108,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a> DashMap<K, V, RandomState> {
|
|||
/// let reviews = DashMap::new();
|
||||
/// reviews.insert("Veloren", "What a fantastic game!");
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn new() -> Self {
|
||||
DashMap::with_hasher(RandomState::default())
|
||||
}
|
||||
|
@ -127,7 +124,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a> DashMap<K, V, RandomState> {
|
|||
/// mappings.insert(2, 4);
|
||||
/// mappings.insert(8, 16);
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn with_capacity(capacity: usize) -> Self {
|
||||
DashMap::with_capacity_and_hasher(capacity, RandomState::default())
|
||||
}
|
||||
|
@ -135,7 +132,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a> DashMap<K, V, RandomState> {
|
|||
|
||||
impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
||||
/// Wraps this `DashMap` into a read-only view. This view allows to obtain raw references to the stored values.
|
||||
#[inline]
|
||||
|
||||
pub fn into_read_only(self) -> ReadOnlyView<K, V, S> {
|
||||
ReadOnlyView::new(self)
|
||||
}
|
||||
|
@ -152,7 +149,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// let reviews = DashMap::with_hasher(s);
|
||||
/// reviews.insert("Veloren", "What a fantastic game!");
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn with_hasher(hasher: S) -> Self {
|
||||
Self::with_capacity_and_hasher(0, hasher)
|
||||
}
|
||||
|
@ -170,7 +167,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// mappings.insert(2, 4);
|
||||
/// mappings.insert(8, 16);
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn with_capacity_and_hasher(mut capacity: usize, hasher: S) -> Self {
|
||||
let shard_amount = shard_amount();
|
||||
let shift = util::ptr_size_bits() - ncb(shard_amount);
|
||||
|
@ -192,7 +189,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
|
||||
/// Hash a given item to produce a usize.
|
||||
/// Uses the provided or default HashBuilder.
|
||||
#[inline]
|
||||
|
||||
pub fn hash_usize<T: Hash>(&self, item: &T) -> usize {
|
||||
let mut hasher = self.hasher.build_hasher();
|
||||
item.hash(&mut hasher);
|
||||
|
@ -214,13 +211,13 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// let map = DashMap::<(), ()>::new();
|
||||
/// println!("Amount of shards: {}", map.shards().len());
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn shards(&self) -> &[RwLock<HashMap<K, V, S>>] {
|
||||
&self.shards
|
||||
}
|
||||
} else {
|
||||
#[allow(dead_code)]
|
||||
#[inline]
|
||||
|
||||
pub(crate) fn shards(&self) -> &[RwLock<HashMap<K, V, S>>] {
|
||||
&self.shards
|
||||
}
|
||||
|
@ -244,7 +241,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// map.insert("coca-cola", 1.4);
|
||||
/// println!("coca-cola is stored in shard: {}", map.determine_map("coca-cola"));
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn determine_map<Q>(&self, key: &Q) -> usize
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
|
@ -272,13 +269,13 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// let hash = map.hash_usize(&key);
|
||||
/// println!("hash is stored in shard: {}", map.determine_shard(hash));
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn determine_shard(&self, hash: usize) -> usize {
|
||||
// Leave the high 7 bits for the HashBrown SIMD tag.
|
||||
(hash << 7) >> self.shift
|
||||
}
|
||||
} else {
|
||||
#[inline]
|
||||
|
||||
pub(crate) fn determine_shard(&self, hash: usize) -> usize {
|
||||
// Leave the high 7 bits for the HashBrown SIMD tag.
|
||||
(hash << 7) >> self.shift
|
||||
|
@ -300,7 +297,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// ```
|
||||
///
|
||||
/// [`BuildHasher`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
|
||||
#[inline]
|
||||
|
||||
pub fn hasher(&self) -> &S {
|
||||
&self.hasher
|
||||
}
|
||||
|
@ -317,7 +314,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// let map = DashMap::new();
|
||||
/// map.insert("I am the key!", "And I am the value!");
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn insert(&self, key: K, value: V) -> Option<V> {
|
||||
self._insert(key, value)
|
||||
}
|
||||
|
@ -335,7 +332,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// soccer_team.insert("Jack", "Goalie");
|
||||
/// assert_eq!(soccer_team.remove("Jack").unwrap().1, "Goalie");
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn remove<Q>(&self, key: &Q) -> Option<(K, V)>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
|
@ -365,7 +362,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// soccer_team.remove_if("Sam", |_, position| position == &"Forward");
|
||||
/// assert!(!soccer_team.contains_key("Sam"));
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn remove_if<Q>(&self, key: &Q, f: impl FnOnce(&K, &V) -> bool) -> Option<(K, V)>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
|
@ -387,7 +384,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// words.insert("hello", "world");
|
||||
/// assert_eq!(words.iter().count(), 1);
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn iter(&'a self) -> Iter<'a, K, V, S, DashMap<K, V, S>> {
|
||||
self._iter()
|
||||
}
|
||||
|
@ -406,7 +403,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// map.iter_mut().for_each(|mut r| *r += 1);
|
||||
/// assert_eq!(*map.get("Johnny").unwrap(), 22);
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn iter_mut(&'a self) -> IterMut<'a, K, V, S, DashMap<K, V, S>> {
|
||||
self._iter_mut()
|
||||
}
|
||||
|
@ -424,7 +421,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// youtubers.insert("Bosnian Bill", 457000);
|
||||
/// assert_eq!(*youtubers.get("Bosnian Bill").unwrap(), 457000);
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn get<Q>(&'a self, key: &Q) -> Option<Ref<'a, K, V, S>>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
|
@ -447,7 +444,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// *class.get_mut("Albin").unwrap() -= 1;
|
||||
/// assert_eq!(*class.get("Albin").unwrap(), 14);
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn get_mut<Q>(&'a self, key: &Q) -> Option<RefMut<'a, K, V, S>>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
|
@ -459,7 +456,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// Remove excess capacity to reduce memory usage.
|
||||
///
|
||||
/// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map.
|
||||
#[inline]
|
||||
|
||||
pub fn shrink_to_fit(&self) {
|
||||
self._shrink_to_fit();
|
||||
}
|
||||
|
@ -481,7 +478,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// people.retain(|_, v| *v > 20);
|
||||
/// assert_eq!(people.len(), 2);
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn retain(&self, f: impl FnMut(&K, &mut V) -> bool) {
|
||||
self._retain(f);
|
||||
}
|
||||
|
@ -501,7 +498,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// people.insert("Charlie", 27);
|
||||
/// assert_eq!(people.len(), 3);
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self._len()
|
||||
}
|
||||
|
@ -518,7 +515,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// let map = DashMap::<(), ()>::new();
|
||||
/// assert!(map.is_empty());
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self._is_empty()
|
||||
}
|
||||
|
@ -538,7 +535,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// stats.clear();
|
||||
/// assert!(stats.is_empty());
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn clear(&self) {
|
||||
self._clear();
|
||||
}
|
||||
|
@ -546,7 +543,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// Returns how many key-value pairs the map can store without reallocating.
|
||||
///
|
||||
/// **Locking behaviour:** May deadlock if called when holding a mutable reference into the map.
|
||||
#[inline]
|
||||
|
||||
pub fn capacity(&self) -> usize {
|
||||
self._capacity()
|
||||
}
|
||||
|
@ -569,7 +566,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// # Panics
|
||||
///
|
||||
/// If the given closure panics, then `alter_all` will abort the process
|
||||
#[inline]
|
||||
|
||||
pub fn alter<Q>(&self, key: &Q, f: impl FnOnce(&K, V) -> V)
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
|
@ -598,7 +595,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// # Panics
|
||||
///
|
||||
/// If the given closure panics, then `alter_all` will abort the process
|
||||
#[inline]
|
||||
|
||||
pub fn alter_all(&self, f: impl FnMut(&K, V) -> V) {
|
||||
self._alter_all(f);
|
||||
}
|
||||
|
@ -616,7 +613,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// team_sizes.insert("Dakota Cherries", 23);
|
||||
/// assert!(team_sizes.contains_key("Dakota Cherries"));
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn contains_key<Q>(&self, key: &Q) -> bool
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
|
@ -629,7 +626,7 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
/// See the documentation on `dashmap::mapref::entry` for more details.
|
||||
///
|
||||
/// **Locking behaviour:** May deadlock if called when holding any sort of reference into the map.
|
||||
#[inline]
|
||||
|
||||
pub fn entry(&'a self, key: K) -> Entry<'a, K, V, S> {
|
||||
self._entry(key)
|
||||
}
|
||||
|
@ -638,30 +635,25 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> DashMap<K, V, S> {
|
|||
impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
|
||||
for DashMap<K, V, S>
|
||||
{
|
||||
#[inline]
|
||||
fn _shard_count(&self) -> usize {
|
||||
self.shards.len()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn _get_read_shard(&'a self, i: usize) -> &'a HashMap<K, V, S> {
|
||||
debug_assert!(i < self.shards.len());
|
||||
self.shards.get_unchecked(i).get()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn _yield_read_shard(&'a self, i: usize) -> RwLockReadGuard<'a, HashMap<K, V, S>> {
|
||||
debug_assert!(i < self.shards.len());
|
||||
self.shards.get_unchecked(i).read()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn _yield_write_shard(&'a self, i: usize) -> RwLockWriteGuard<'a, HashMap<K, V, S>> {
|
||||
debug_assert!(i < self.shards.len());
|
||||
self.shards.get_unchecked(i).write()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _insert(&self, key: K, value: V) -> Option<V> {
|
||||
let hash = self.hash_usize(&key);
|
||||
let idx = self.determine_shard(hash);
|
||||
|
@ -671,7 +663,6 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
|
|||
.map(|v| v.into_inner())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _remove<Q>(&self, key: &Q) -> Option<(K, V)>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
|
@ -683,7 +674,6 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
|
|||
shard.remove_entry(key).map(|(k, v)| (k, v.into_inner()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _remove_if<Q>(&self, key: &Q, f: impl FnOnce(&K, &V) -> bool) -> Option<(K, V)>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
|
@ -703,17 +693,14 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _iter(&'a self) -> Iter<'a, K, V, S, DashMap<K, V, S>> {
|
||||
Iter::new(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _iter_mut(&'a self) -> IterMut<'a, K, V, S, DashMap<K, V, S>> {
|
||||
IterMut::new(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _get<Q>(&'a self, key: &Q) -> Option<Ref<'a, K, V, S>>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
|
@ -733,7 +720,6 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _get_mut<Q>(&'a self, key: &Q) -> Option<RefMut<'a, K, V, S>>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
|
@ -753,29 +739,24 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _shrink_to_fit(&self) {
|
||||
self.shards.iter().for_each(|s| s.write().shrink_to_fit());
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _retain(&self, mut f: impl FnMut(&K, &mut V) -> bool) {
|
||||
self.shards
|
||||
.iter()
|
||||
.for_each(|s| s.write().retain(|k, v| f(k, v.get_mut())));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _len(&self) -> usize {
|
||||
self.shards.iter().map(|s| s.read().len()).sum()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _capacity(&self) -> usize {
|
||||
self.shards.iter().map(|s| s.read().capacity()).sum()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _alter<Q>(&self, key: &Q, f: impl FnOnce(&K, V) -> V)
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
|
@ -786,7 +767,6 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _alter_all(&self, mut f: impl FnMut(&K, V) -> V) {
|
||||
self.shards.iter().for_each(|s| {
|
||||
s.write()
|
||||
|
@ -795,7 +775,6 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
|
|||
});
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _entry(&'a self, key: K) -> Entry<'a, K, V, S> {
|
||||
let hash = self.hash_usize(&key);
|
||||
let idx = self.determine_shard(hash);
|
||||
|
@ -811,7 +790,6 @@ impl<'a, K: 'a + Eq + Hash, V: 'a, S: 'a + BuildHasher + Clone> Map<'a, K, V, S>
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _hasher(&self) -> S {
|
||||
self.hasher.clone()
|
||||
}
|
||||
|
@ -833,7 +811,6 @@ impl<K: Eq + Hash + fmt::Debug, V: fmt::Debug, S: BuildHasher + Clone> fmt::Debu
|
|||
impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> Shl<(K, V)> for &'a DashMap<K, V, S> {
|
||||
type Output = Option<V>;
|
||||
|
||||
#[inline]
|
||||
fn shl(self, pair: (K, V)) -> Self::Output {
|
||||
self.insert(pair.0, pair.1)
|
||||
}
|
||||
|
@ -846,7 +823,6 @@ where
|
|||
{
|
||||
type Output = Ref<'a, K, V, S>;
|
||||
|
||||
#[inline]
|
||||
fn shr(self, key: &Q) -> Self::Output {
|
||||
self.get(key).unwrap()
|
||||
}
|
||||
|
@ -859,7 +835,6 @@ where
|
|||
{
|
||||
type Output = RefMut<'a, K, V, S>;
|
||||
|
||||
#[inline]
|
||||
fn bitor(self, key: &Q) -> Self::Output {
|
||||
self.get_mut(key).unwrap()
|
||||
}
|
||||
|
@ -872,7 +847,6 @@ where
|
|||
{
|
||||
type Output = Option<(K, V)>;
|
||||
|
||||
#[inline]
|
||||
fn sub(self, key: &Q) -> Self::Output {
|
||||
self.remove(key)
|
||||
}
|
||||
|
@ -885,7 +859,6 @@ where
|
|||
{
|
||||
type Output = bool;
|
||||
|
||||
#[inline]
|
||||
fn bitand(self, key: &Q) -> Self::Output {
|
||||
self.contains_key(key)
|
||||
}
|
||||
|
|
26
src/lock.rs
26
src/lock.rs
|
@ -48,14 +48,13 @@ unsafe impl<T: ?Sized + Send> Send for RwLock<T> {}
|
|||
unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
|
||||
|
||||
impl<T> RwLock<T> {
|
||||
#[inline]
|
||||
pub const fn new(user_data: T) -> RwLock<T> {
|
||||
RwLock {
|
||||
lock: AtomicUsize::new(0),
|
||||
data: UnsafeCell::new(user_data),
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
|
||||
pub fn into_inner(self) -> T {
|
||||
let RwLock { data, .. } = self;
|
||||
data.into_inner()
|
||||
|
@ -63,7 +62,6 @@ impl<T> RwLock<T> {
|
|||
}
|
||||
|
||||
impl<T: ?Sized> RwLock<T> {
|
||||
#[inline]
|
||||
pub fn read(&self) -> RwLockReadGuard<T> {
|
||||
loop {
|
||||
match self.try_read() {
|
||||
|
@ -73,7 +71,6 @@ impl<T: ?Sized> RwLock<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_read(&self) -> Option<RwLockReadGuard<T>> {
|
||||
let value = self.lock.fetch_add(READER, Ordering::Acquire);
|
||||
|
||||
|
@ -91,7 +88,6 @@ impl<T: ?Sized> RwLock<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// # Safety
|
||||
///
|
||||
/// This is only safe if the lock is currently locked in read mode and the number of readers is not 0.
|
||||
|
@ -100,7 +96,6 @@ impl<T: ?Sized> RwLock<T> {
|
|||
self.lock.fetch_sub(READER, Ordering::Release);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// # Safety
|
||||
///
|
||||
/// The lock must be locked in write mode.
|
||||
|
@ -109,7 +104,6 @@ impl<T: ?Sized> RwLock<T> {
|
|||
self.lock.fetch_and(!(WRITER | UPGRADED), Ordering::Release);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn try_write_internal(&self, strong: bool) -> Option<RwLockWriteGuard<T>> {
|
||||
if compare_exchange(
|
||||
&self.lock,
|
||||
|
@ -131,7 +125,6 @@ impl<T: ?Sized> RwLock<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn write(&self) -> RwLockWriteGuard<T> {
|
||||
loop {
|
||||
match self.try_write_internal(false) {
|
||||
|
@ -141,12 +134,10 @@ impl<T: ?Sized> RwLock<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_write(&self) -> Option<RwLockWriteGuard<T>> {
|
||||
self.try_write_internal(true)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn upgradeable_read(&self) -> RwLockUpgradeableGuard<T> {
|
||||
loop {
|
||||
match self.try_upgradeable_read() {
|
||||
|
@ -156,7 +147,6 @@ impl<T: ?Sized> RwLock<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_upgradeable_read(&self) -> Option<RwLockUpgradeableGuard<T>> {
|
||||
if self.lock.fetch_or(UPGRADED, Ordering::Acquire) & (WRITER | UPGRADED) == 0 {
|
||||
Some(RwLockUpgradeableGuard {
|
||||
|
@ -190,14 +180,12 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for RwLock<T> {
|
|||
}
|
||||
|
||||
impl<T: ?Sized + Default> Default for RwLock<T> {
|
||||
#[inline]
|
||||
fn default() -> RwLock<T> {
|
||||
RwLock::new(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'rwlock, T: ?Sized> RwLockUpgradeableGuard<'rwlock, T> {
|
||||
#[inline(always)]
|
||||
fn try_upgrade_internal(self, strong: bool) -> Result<RwLockWriteGuard<'rwlock, T>, Self> {
|
||||
if compare_exchange(
|
||||
&self.lock,
|
||||
|
@ -223,7 +211,6 @@ impl<'rwlock, T: ?Sized> RwLockUpgradeableGuard<'rwlock, T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn upgrade(mut self) -> RwLockWriteGuard<'rwlock, T> {
|
||||
loop {
|
||||
self = match self.try_upgrade_internal(false) {
|
||||
|
@ -235,12 +222,10 @@ impl<'rwlock, T: ?Sized> RwLockUpgradeableGuard<'rwlock, T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_upgrade(self) -> Result<RwLockWriteGuard<'rwlock, T>, Self> {
|
||||
self.try_upgrade_internal(true)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn downgrade(self) -> RwLockReadGuard<'rwlock, T> {
|
||||
self.lock.fetch_add(READER, Ordering::Acquire);
|
||||
|
||||
|
@ -252,7 +237,6 @@ impl<'rwlock, T: ?Sized> RwLockUpgradeableGuard<'rwlock, T> {
|
|||
}
|
||||
|
||||
impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
|
||||
#[inline]
|
||||
pub fn downgrade(self) -> RwLockReadGuard<'rwlock, T> {
|
||||
self.lock.fetch_add(READER, Ordering::Acquire);
|
||||
|
||||
|
@ -266,7 +250,6 @@ impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
|
|||
impl<'rwlock, T: ?Sized> Deref for RwLockReadGuard<'rwlock, T> {
|
||||
type Target = T;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &T {
|
||||
unsafe { self.data.as_ref() }
|
||||
}
|
||||
|
@ -275,7 +258,6 @@ impl<'rwlock, T: ?Sized> Deref for RwLockReadGuard<'rwlock, T> {
|
|||
impl<'rwlock, T: ?Sized> Deref for RwLockUpgradeableGuard<'rwlock, T> {
|
||||
type Target = T;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &T {
|
||||
unsafe { self.data.as_ref() }
|
||||
}
|
||||
|
@ -284,21 +266,18 @@ impl<'rwlock, T: ?Sized> Deref for RwLockUpgradeableGuard<'rwlock, T> {
|
|||
impl<'rwlock, T: ?Sized> Deref for RwLockWriteGuard<'rwlock, T> {
|
||||
type Target = T;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &T {
|
||||
unsafe { self.data.as_ref() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'rwlock, T: ?Sized> DerefMut for RwLockWriteGuard<'rwlock, T> {
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
unsafe { self.data.as_mut() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'rwlock, T: ?Sized> Drop for RwLockReadGuard<'rwlock, T> {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
debug_assert!(self.lock.load(Ordering::Relaxed) & !(WRITER | UPGRADED) > 0);
|
||||
self.lock.fetch_sub(READER, Ordering::Release);
|
||||
|
@ -306,7 +285,6 @@ impl<'rwlock, T: ?Sized> Drop for RwLockReadGuard<'rwlock, T> {
|
|||
}
|
||||
|
||||
impl<'rwlock, T: ?Sized> Drop for RwLockUpgradeableGuard<'rwlock, T> {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
debug_assert_eq!(
|
||||
self.lock.load(Ordering::Relaxed) & (WRITER | UPGRADED),
|
||||
|
@ -317,14 +295,12 @@ impl<'rwlock, T: ?Sized> Drop for RwLockUpgradeableGuard<'rwlock, T> {
|
|||
}
|
||||
|
||||
impl<'rwlock, T: ?Sized> Drop for RwLockWriteGuard<'rwlock, T> {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
debug_assert_eq!(self.lock.load(Ordering::Relaxed) & WRITER, WRITER);
|
||||
self.lock.fetch_and(!(WRITER | UPGRADED), Ordering::Release);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn compare_exchange(
|
||||
atomic: &AtomicUsize,
|
||||
current: usize,
|
||||
|
|
|
@ -15,7 +15,7 @@ pub enum Entry<'a, K, V, S = RandomState> {
|
|||
|
||||
impl<'a, K: Eq + Hash, V, S: BuildHasher> Entry<'a, K, V, S> {
|
||||
/// Apply a function to the stored value if it exists.
|
||||
#[inline]
|
||||
|
||||
pub fn and_modify(self, f: impl FnOnce(&mut V)) -> Self {
|
||||
match self {
|
||||
Entry::Occupied(mut entry) => {
|
||||
|
@ -28,7 +28,7 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> Entry<'a, K, V, S> {
|
|||
}
|
||||
|
||||
/// Get the key of the entry.
|
||||
#[inline]
|
||||
|
||||
pub fn key(&self) -> &K {
|
||||
match *self {
|
||||
Entry::Occupied(ref entry) => entry.key(),
|
||||
|
@ -37,7 +37,7 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> Entry<'a, K, V, S> {
|
|||
}
|
||||
|
||||
/// Into the key of the entry.
|
||||
#[inline]
|
||||
|
||||
pub fn into_key(self) -> K {
|
||||
match self {
|
||||
Entry::Occupied(entry) => entry.into_key(),
|
||||
|
@ -47,7 +47,7 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> Entry<'a, K, V, S> {
|
|||
|
||||
/// Return a mutable reference to the element if it exists,
|
||||
/// otherwise insert the default and return a mutable reference to that.
|
||||
#[inline]
|
||||
|
||||
pub fn or_default(self) -> RefMut<'a, K, V, S>
|
||||
where
|
||||
V: Default,
|
||||
|
@ -60,7 +60,7 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> Entry<'a, K, V, S> {
|
|||
|
||||
/// Return a mutable reference to the element if it exists,
|
||||
/// otherwise a provided value and return a mutable reference to that.
|
||||
#[inline]
|
||||
|
||||
pub fn or_insert(self, value: V) -> RefMut<'a, K, V, S> {
|
||||
match self {
|
||||
Entry::Occupied(entry) => entry.into_ref(),
|
||||
|
@ -70,7 +70,7 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> Entry<'a, K, V, S> {
|
|||
|
||||
/// Return a mutable reference to the element if it exists,
|
||||
/// otherwise insert the result of a provided function and return a mutable reference to that.
|
||||
#[inline]
|
||||
|
||||
pub fn or_insert_with(self, value: impl FnOnce() -> V) -> RefMut<'a, K, V, S> {
|
||||
match self {
|
||||
Entry::Occupied(entry) => entry.into_ref(),
|
||||
|
@ -78,7 +78,6 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> Entry<'a, K, V, S> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn or_try_insert_with<E>(
|
||||
self,
|
||||
value: impl FnOnce() -> Result<V, E>,
|
||||
|
@ -102,12 +101,10 @@ unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + Sync, S: BuildHasher> Sync
|
|||
}
|
||||
|
||||
impl<'a, K: Eq + Hash, V, S: BuildHasher> VacantEntry<'a, K, V, S> {
|
||||
#[inline]
|
||||
pub(crate) fn new(shard: RwLockWriteGuard<'a, HashMap<K, V, S>>, key: K) -> Self {
|
||||
Self { shard, key }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn insert(mut self, value: V) -> RefMut<'a, K, V, S> {
|
||||
unsafe {
|
||||
let c: K = ptr::read(&self.key);
|
||||
|
@ -121,12 +118,10 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> VacantEntry<'a, K, V, S> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_key(self) -> K {
|
||||
self.key
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn key(&self) -> &K {
|
||||
&self.key
|
||||
}
|
||||
|
@ -145,7 +140,6 @@ unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + Sync, S: BuildHasher> Sync
|
|||
}
|
||||
|
||||
impl<'a, K: Eq + Hash, V, S: BuildHasher> OccupiedEntry<'a, K, V, S> {
|
||||
#[inline]
|
||||
pub(crate) fn new(
|
||||
shard: RwLockWriteGuard<'a, HashMap<K, V, S>>,
|
||||
key: K,
|
||||
|
@ -154,49 +148,40 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> OccupiedEntry<'a, K, V, S> {
|
|||
Self { shard, elem, key }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get(&self) -> &V {
|
||||
self.elem.1
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_mut(&mut self) -> &mut V {
|
||||
self.elem.1
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn insert(&mut self, value: V) -> V {
|
||||
mem::replace(self.elem.1, value)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_ref(self) -> RefMut<'a, K, V, S> {
|
||||
RefMut::new(self.shard, self.elem.0, self.elem.1)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_key(self) -> K {
|
||||
self.key
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn key(&self) -> &K {
|
||||
self.elem.0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn remove(mut self) -> V {
|
||||
self.shard.remove(self.elem.0).unwrap().into_inner()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn remove_entry(mut self) -> (K, V) {
|
||||
let (k, v) = self.shard.remove_entry(self.elem.0).unwrap();
|
||||
|
||||
(k, v.into_inner())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn replace_entry(mut self, value: V) -> (K, V) {
|
||||
let nk = self.key;
|
||||
let (k, v) = self.shard.remove_entry(self.elem.0).unwrap();
|
||||
|
|
|
@ -28,7 +28,6 @@ unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + Sync, S: BuildHasher> Sync
|
|||
}
|
||||
|
||||
impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMulti<'a, K, V, S> {
|
||||
#[inline(always)]
|
||||
pub(crate) fn new(
|
||||
guard: Arc<RwLockReadGuard<'a, HashMap<K, V, S>>>,
|
||||
k: &'a K,
|
||||
|
@ -41,17 +40,14 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMulti<'a, K, V, S> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn key(&self) -> &K {
|
||||
self.k
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn value(&self) -> &V {
|
||||
self.v
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn pair(&self) -> (&K, &V) {
|
||||
(self.k, self.v)
|
||||
}
|
||||
|
@ -60,7 +56,6 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMulti<'a, K, V, S> {
|
|||
impl<'a, K: Eq + Hash, V, S: BuildHasher> Deref for RefMulti<'a, K, V, S> {
|
||||
type Target = V;
|
||||
|
||||
#[inline(always)]
|
||||
fn deref(&self) -> &V {
|
||||
self.value()
|
||||
}
|
||||
|
@ -83,7 +78,6 @@ unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + Sync, S: BuildHasher> Sync
|
|||
}
|
||||
|
||||
impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMutMulti<'a, K, V, S> {
|
||||
#[inline(always)]
|
||||
pub(crate) fn new(
|
||||
guard: Arc<RwLockWriteGuard<'a, HashMap<K, V, S>>>,
|
||||
k: &'a K,
|
||||
|
@ -96,27 +90,22 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMutMulti<'a, K, V, S> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn key(&self) -> &K {
|
||||
self.k
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn value(&self) -> &V {
|
||||
self.v
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn value_mut(&mut self) -> &mut V {
|
||||
self.v
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn pair(&self) -> (&K, &V) {
|
||||
(self.k, self.v)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn pair_mut(&mut self) -> (&K, &mut V) {
|
||||
(self.k, self.v)
|
||||
}
|
||||
|
@ -125,14 +114,12 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMutMulti<'a, K, V, S> {
|
|||
impl<'a, K: Eq + Hash, V, S: BuildHasher> Deref for RefMutMulti<'a, K, V, S> {
|
||||
type Target = V;
|
||||
|
||||
#[inline(always)]
|
||||
fn deref(&self) -> &V {
|
||||
self.value()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K: Eq + Hash, V, S: BuildHasher> DerefMut for RefMutMulti<'a, K, V, S> {
|
||||
#[inline(always)]
|
||||
fn deref_mut(&mut self) -> &mut V {
|
||||
self.value_mut()
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + Sync, S: BuildHasher> Sync
|
|||
}
|
||||
|
||||
impl<'a, K: Eq + Hash, V, S: BuildHasher> Ref<'a, K, V, S> {
|
||||
#[inline(always)]
|
||||
pub(crate) fn new(guard: RwLockReadGuard<'a, HashMap<K, V, S>>, k: &'a K, v: &'a V) -> Self {
|
||||
Self {
|
||||
_guard: guard,
|
||||
|
@ -28,17 +27,14 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> Ref<'a, K, V, S> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn key(&self) -> &K {
|
||||
self.k
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn value(&self) -> &V {
|
||||
self.v
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn pair(&self) -> (&K, &V) {
|
||||
(self.k, self.v)
|
||||
}
|
||||
|
@ -47,7 +43,6 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> Ref<'a, K, V, S> {
|
|||
impl<'a, K: Eq + Hash, V, S: BuildHasher> Deref for Ref<'a, K, V, S> {
|
||||
type Target = V;
|
||||
|
||||
#[inline(always)]
|
||||
fn deref(&self) -> &V {
|
||||
self.value()
|
||||
}
|
||||
|
@ -70,7 +65,6 @@ unsafe impl<'a, K: Eq + Hash + Send + Sync, V: Send + Sync, S: BuildHasher> Sync
|
|||
}
|
||||
|
||||
impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMut<'a, K, V, S> {
|
||||
#[inline(always)]
|
||||
pub(crate) fn new(
|
||||
guard: RwLockWriteGuard<'a, HashMap<K, V, S>>,
|
||||
k: &'a K,
|
||||
|
@ -79,27 +73,22 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMut<'a, K, V, S> {
|
|||
Self { guard, k, v }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn key(&self) -> &K {
|
||||
self.k
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn value(&self) -> &V {
|
||||
self.v
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn value_mut(&mut self) -> &mut V {
|
||||
self.v
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn pair(&self) -> (&K, &V) {
|
||||
(self.k, self.v)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn pair_mut(&mut self) -> (&K, &mut V) {
|
||||
(self.k, self.v)
|
||||
}
|
||||
|
@ -112,14 +101,12 @@ impl<'a, K: Eq + Hash, V, S: BuildHasher> RefMut<'a, K, V, S> {
|
|||
impl<'a, K: Eq + Hash, V, S: BuildHasher> Deref for RefMut<'a, K, V, S> {
|
||||
type Target = V;
|
||||
|
||||
#[inline(always)]
|
||||
fn deref(&self) -> &V {
|
||||
self.value()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K: Eq + Hash, V, S: BuildHasher> DerefMut for RefMut<'a, K, V, S> {
|
||||
#[inline(always)]
|
||||
fn deref_mut(&mut self) -> &mut V {
|
||||
self.value_mut()
|
||||
}
|
||||
|
|
436
src/read_only.rs
436
src/read_only.rs
|
@ -1,219 +1,217 @@
|
|||
use crate::t::Map;
|
||||
use crate::{DashMap, HashMap};
|
||||
use ahash::RandomState;
|
||||
use core::borrow::Borrow;
|
||||
use core::fmt;
|
||||
use core::hash::{BuildHasher, Hash};
|
||||
|
||||
/// A read-only view into a `DashMap`. Allows to obtain raw references to the stored values.
|
||||
pub struct ReadOnlyView<K, V, S = RandomState> {
|
||||
map: DashMap<K, V, S>,
|
||||
}
|
||||
|
||||
impl<K: Eq + Hash + Clone, V: Clone, S: Clone> Clone for ReadOnlyView<K, V, S> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
map: self.map.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Eq + Hash + fmt::Debug, V: fmt::Debug, S: BuildHasher + Clone> fmt::Debug
|
||||
for ReadOnlyView<K, V, S>
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.map.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, S> ReadOnlyView<K, V, S> {
|
||||
#[inline]
|
||||
pub(crate) fn new(map: DashMap<K, V, S>) -> Self {
|
||||
Self { map }
|
||||
}
|
||||
|
||||
/// Consumes this `ReadOnlyView`, returning the underlying `DashMap`.
|
||||
#[inline]
|
||||
pub fn into_inner(self) -> DashMap<K, V, S> {
|
||||
self.map
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView<K, V, S> {
|
||||
/// Returns the number of elements in the map.
|
||||
#[inline]
|
||||
pub fn len(&self) -> usize {
|
||||
self.map.len()
|
||||
}
|
||||
|
||||
/// Returns `true` if the map contains no elements.
|
||||
#[inline]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.map.is_empty()
|
||||
}
|
||||
|
||||
/// Returns the number of elements the map can hold without reallocating.
|
||||
#[inline]
|
||||
pub fn capacity(&self) -> usize {
|
||||
self.map.capacity()
|
||||
}
|
||||
|
||||
/// Returns `true` if the map contains a value for the specified key.
|
||||
#[inline]
|
||||
pub fn contains_key<Q>(&'a self, key: &Q) -> bool
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
let hash = self.map.hash_usize(&key);
|
||||
let idx = self.map.determine_shard(hash);
|
||||
|
||||
let shard = unsafe { self.map._get_read_shard(idx) };
|
||||
shard.contains_key(key)
|
||||
}
|
||||
|
||||
/// Returns a reference to the value corresponding to the key.
|
||||
#[inline]
|
||||
pub fn get<Q>(&'a self, key: &Q) -> Option<&'a V>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
let hash = self.map.hash_usize(&key);
|
||||
let idx = self.map.determine_shard(hash);
|
||||
|
||||
let shard = unsafe { self.map._get_read_shard(idx) };
|
||||
shard.get(key).map(|v| v.get())
|
||||
}
|
||||
|
||||
/// Returns the key-value pair corresponding to the supplied key.
|
||||
#[inline]
|
||||
pub fn get_key_value<Q>(&'a self, key: &Q) -> Option<(&'a K, &'a V)>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
let hash = self.map.hash_usize(&key);
|
||||
let idx = self.map.determine_shard(hash);
|
||||
|
||||
let shard = unsafe { self.map._get_read_shard(idx) };
|
||||
shard.get_key_value(key).map(|(k, v)| (k, v.get()))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn shard_read_iter(&'a self) -> impl Iterator<Item = &'a HashMap<K, V, S>> + 'a {
|
||||
(0..self.map._shard_count())
|
||||
.map(move |shard_i| unsafe { self.map._get_read_shard(shard_i) })
|
||||
}
|
||||
|
||||
/// An iterator visiting all key-value pairs in arbitrary order. The iterator element type is `(&'a K, &'a V)`.
|
||||
#[inline]
|
||||
pub fn iter(&'a self) -> impl Iterator<Item = (&'a K, &'a V)> + 'a {
|
||||
self.shard_read_iter()
|
||||
.flat_map(|shard| shard.iter())
|
||||
.map(|(k, v)| (k, v.get()))
|
||||
}
|
||||
|
||||
/// An iterator visiting all keys in arbitrary order. The iterator element type is `&'a K`.
|
||||
#[inline]
|
||||
pub fn keys(&'a self) -> impl Iterator<Item = &'a K> + 'a {
|
||||
self.shard_read_iter().flat_map(|shard| shard.keys())
|
||||
}
|
||||
|
||||
/// An iterator visiting all values in arbitrary order. The iterator element type is `&'a V`.
|
||||
#[inline]
|
||||
pub fn values(&'a self) -> impl Iterator<Item = &'a V> + 'a {
|
||||
self.shard_read_iter()
|
||||
.flat_map(|shard| shard.values())
|
||||
.map(|v| v.get())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::DashMap;
|
||||
|
||||
fn construct_sample_map() -> DashMap<i32, String> {
|
||||
let map = DashMap::new();
|
||||
map.insert(1, "one".to_string());
|
||||
map.insert(10, "ten".to_string());
|
||||
map.insert(27, "twenty seven".to_string());
|
||||
map.insert(45, "forty five".to_string());
|
||||
map
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_properties() {
|
||||
let map = construct_sample_map();
|
||||
let view = map.clone().into_read_only();
|
||||
|
||||
assert_eq!(view.is_empty(), map.is_empty());
|
||||
assert_eq!(view.len(), map.len());
|
||||
assert_eq!(view.capacity(), map.capacity());
|
||||
|
||||
let new_map = view.into_inner();
|
||||
|
||||
assert_eq!(new_map.is_empty(), map.is_empty());
|
||||
assert_eq!(new_map.len(), map.len());
|
||||
assert_eq!(new_map.capacity(), map.capacity());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get() {
|
||||
let map = construct_sample_map();
|
||||
let view = map.clone().into_read_only();
|
||||
|
||||
for key in map.iter().map(|entry| *entry.key()) {
|
||||
assert!(view.contains_key(&key));
|
||||
|
||||
let map_entry = map.get(&key).unwrap();
|
||||
assert_eq!(view.get(&key).unwrap(), map_entry.value());
|
||||
|
||||
let key_value: (&i32, &String) = view.get_key_value(&key).unwrap();
|
||||
assert_eq!(key_value.0, map_entry.key());
|
||||
assert_eq!(key_value.1, map_entry.value());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iters() {
|
||||
let map = construct_sample_map();
|
||||
let view = map.clone().into_read_only();
|
||||
|
||||
let mut visited_items = Vec::new();
|
||||
for (key, value) in view.iter() {
|
||||
map.contains_key(key);
|
||||
|
||||
let map_entry = map.get(&key).unwrap();
|
||||
assert_eq!(key, map_entry.key());
|
||||
assert_eq!(value, map_entry.value());
|
||||
|
||||
visited_items.push((key, value));
|
||||
}
|
||||
|
||||
let mut visited_keys = Vec::new();
|
||||
for key in view.keys() {
|
||||
map.contains_key(key);
|
||||
|
||||
let map_entry = map.get(&key).unwrap();
|
||||
assert_eq!(key, map_entry.key());
|
||||
assert_eq!(view.get(key).unwrap(), map_entry.value());
|
||||
|
||||
visited_keys.push(key);
|
||||
}
|
||||
|
||||
let mut visited_values = Vec::new();
|
||||
for value in view.values() {
|
||||
visited_values.push(value);
|
||||
}
|
||||
|
||||
for entry in map.iter() {
|
||||
let key = entry.key();
|
||||
let value = entry.value();
|
||||
|
||||
assert!(visited_keys.contains(&key));
|
||||
assert!(visited_values.contains(&value));
|
||||
assert!(visited_items.contains(&(key, value)));
|
||||
}
|
||||
}
|
||||
}
|
||||
use crate::t::Map;
|
||||
use crate::{DashMap, HashMap};
|
||||
use ahash::RandomState;
|
||||
use core::borrow::Borrow;
|
||||
use core::fmt;
|
||||
use core::hash::{BuildHasher, Hash};
|
||||
|
||||
/// A read-only view into a `DashMap`. Allows to obtain raw references to the stored values.
|
||||
pub struct ReadOnlyView<K, V, S = RandomState> {
|
||||
map: DashMap<K, V, S>,
|
||||
}
|
||||
|
||||
impl<K: Eq + Hash + Clone, V: Clone, S: Clone> Clone for ReadOnlyView<K, V, S> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
map: self.map.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Eq + Hash + fmt::Debug, V: fmt::Debug, S: BuildHasher + Clone> fmt::Debug
|
||||
for ReadOnlyView<K, V, S>
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.map.fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, V, S> ReadOnlyView<K, V, S> {
|
||||
pub(crate) fn new(map: DashMap<K, V, S>) -> Self {
|
||||
Self { map }
|
||||
}
|
||||
|
||||
/// Consumes this `ReadOnlyView`, returning the underlying `DashMap`.
|
||||
|
||||
pub fn into_inner(self) -> DashMap<K, V, S> {
|
||||
self.map
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, K: 'a + Eq + Hash, V: 'a, S: BuildHasher + Clone> ReadOnlyView<K, V, S> {
|
||||
/// Returns the number of elements in the map.
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.map.len()
|
||||
}
|
||||
|
||||
/// Returns `true` if the map contains no elements.
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.map.is_empty()
|
||||
}
|
||||
|
||||
/// Returns the number of elements the map can hold without reallocating.
|
||||
|
||||
pub fn capacity(&self) -> usize {
|
||||
self.map.capacity()
|
||||
}
|
||||
|
||||
/// Returns `true` if the map contains a value for the specified key.
|
||||
|
||||
pub fn contains_key<Q>(&'a self, key: &Q) -> bool
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
let hash = self.map.hash_usize(&key);
|
||||
let idx = self.map.determine_shard(hash);
|
||||
|
||||
let shard = unsafe { self.map._get_read_shard(idx) };
|
||||
shard.contains_key(key)
|
||||
}
|
||||
|
||||
/// Returns a reference to the value corresponding to the key.
|
||||
|
||||
pub fn get<Q>(&'a self, key: &Q) -> Option<&'a V>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
let hash = self.map.hash_usize(&key);
|
||||
let idx = self.map.determine_shard(hash);
|
||||
|
||||
let shard = unsafe { self.map._get_read_shard(idx) };
|
||||
shard.get(key).map(|v| v.get())
|
||||
}
|
||||
|
||||
/// Returns the key-value pair corresponding to the supplied key.
|
||||
|
||||
pub fn get_key_value<Q>(&'a self, key: &Q) -> Option<(&'a K, &'a V)>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
Q: Hash + Eq + ?Sized,
|
||||
{
|
||||
let hash = self.map.hash_usize(&key);
|
||||
let idx = self.map.determine_shard(hash);
|
||||
|
||||
let shard = unsafe { self.map._get_read_shard(idx) };
|
||||
shard.get_key_value(key).map(|(k, v)| (k, v.get()))
|
||||
}
|
||||
|
||||
fn shard_read_iter(&'a self) -> impl Iterator<Item = &'a HashMap<K, V, S>> + 'a {
|
||||
(0..self.map._shard_count())
|
||||
.map(move |shard_i| unsafe { self.map._get_read_shard(shard_i) })
|
||||
}
|
||||
|
||||
/// An iterator visiting all key-value pairs in arbitrary order. The iterator element type is `(&'a K, &'a V)`.
|
||||
|
||||
pub fn iter(&'a self) -> impl Iterator<Item = (&'a K, &'a V)> + 'a {
|
||||
self.shard_read_iter()
|
||||
.flat_map(|shard| shard.iter())
|
||||
.map(|(k, v)| (k, v.get()))
|
||||
}
|
||||
|
||||
/// An iterator visiting all keys in arbitrary order. The iterator element type is `&'a K`.
|
||||
|
||||
pub fn keys(&'a self) -> impl Iterator<Item = &'a K> + 'a {
|
||||
self.shard_read_iter().flat_map(|shard| shard.keys())
|
||||
}
|
||||
|
||||
/// An iterator visiting all values in arbitrary order. The iterator element type is `&'a V`.
|
||||
|
||||
pub fn values(&'a self) -> impl Iterator<Item = &'a V> + 'a {
|
||||
self.shard_read_iter()
|
||||
.flat_map(|shard| shard.values())
|
||||
.map(|v| v.get())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::DashMap;
|
||||
|
||||
fn construct_sample_map() -> DashMap<i32, String> {
|
||||
let map = DashMap::new();
|
||||
map.insert(1, "one".to_string());
|
||||
map.insert(10, "ten".to_string());
|
||||
map.insert(27, "twenty seven".to_string());
|
||||
map.insert(45, "forty five".to_string());
|
||||
map
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_properties() {
|
||||
let map = construct_sample_map();
|
||||
let view = map.clone().into_read_only();
|
||||
|
||||
assert_eq!(view.is_empty(), map.is_empty());
|
||||
assert_eq!(view.len(), map.len());
|
||||
assert_eq!(view.capacity(), map.capacity());
|
||||
|
||||
let new_map = view.into_inner();
|
||||
|
||||
assert_eq!(new_map.is_empty(), map.is_empty());
|
||||
assert_eq!(new_map.len(), map.len());
|
||||
assert_eq!(new_map.capacity(), map.capacity());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get() {
|
||||
let map = construct_sample_map();
|
||||
let view = map.clone().into_read_only();
|
||||
|
||||
for key in map.iter().map(|entry| *entry.key()) {
|
||||
assert!(view.contains_key(&key));
|
||||
|
||||
let map_entry = map.get(&key).unwrap();
|
||||
assert_eq!(view.get(&key).unwrap(), map_entry.value());
|
||||
|
||||
let key_value: (&i32, &String) = view.get_key_value(&key).unwrap();
|
||||
assert_eq!(key_value.0, map_entry.key());
|
||||
assert_eq!(key_value.1, map_entry.value());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iters() {
|
||||
let map = construct_sample_map();
|
||||
let view = map.clone().into_read_only();
|
||||
|
||||
let mut visited_items = Vec::new();
|
||||
for (key, value) in view.iter() {
|
||||
map.contains_key(key);
|
||||
|
||||
let map_entry = map.get(&key).unwrap();
|
||||
assert_eq!(key, map_entry.key());
|
||||
assert_eq!(value, map_entry.value());
|
||||
|
||||
visited_items.push((key, value));
|
||||
}
|
||||
|
||||
let mut visited_keys = Vec::new();
|
||||
for key in view.keys() {
|
||||
map.contains_key(key);
|
||||
|
||||
let map_entry = map.get(&key).unwrap();
|
||||
assert_eq!(key, map_entry.key());
|
||||
assert_eq!(view.get(key).unwrap(), map_entry.value());
|
||||
|
||||
visited_keys.push(key);
|
||||
}
|
||||
|
||||
let mut visited_values = Vec::new();
|
||||
for value in view.values() {
|
||||
visited_values.push(value);
|
||||
}
|
||||
|
||||
for entry in map.iter() {
|
||||
let key = entry.key();
|
||||
let value = entry.value();
|
||||
|
||||
assert!(visited_keys.contains(&key));
|
||||
assert!(visited_values.contains(&value));
|
||||
assert!(visited_items.contains(&(key, value)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
41
src/set.rs
41
src/set.rs
|
@ -43,7 +43,6 @@ where
|
|||
K: Eq + Hash,
|
||||
S: Default + BuildHasher + Clone,
|
||||
{
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
Self::with_hasher(Default::default())
|
||||
}
|
||||
|
@ -60,7 +59,7 @@ impl<'a, K: 'a + Eq + Hash> DashSet<K, RandomState> {
|
|||
/// let games = DashSet::new();
|
||||
/// games.insert("Veloren");
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self::with_hasher(RandomState::default())
|
||||
}
|
||||
|
@ -75,7 +74,7 @@ impl<'a, K: 'a + Eq + Hash> DashSet<K, RandomState> {
|
|||
/// numbers.insert(2);
|
||||
/// numbers.insert(8);
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn with_capacity(capacity: usize) -> Self {
|
||||
Self::with_capacity_and_hasher(capacity, RandomState::default())
|
||||
}
|
||||
|
@ -94,7 +93,7 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet<K, S> {
|
|||
/// let games = DashSet::with_hasher(s);
|
||||
/// games.insert("Veloren");
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn with_hasher(hasher: S) -> Self {
|
||||
Self::with_capacity_and_hasher(0, hasher)
|
||||
}
|
||||
|
@ -111,7 +110,7 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet<K, S> {
|
|||
/// numbers.insert(2);
|
||||
/// numbers.insert(8);
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self {
|
||||
Self {
|
||||
inner: DashMap::with_capacity_and_hasher(capacity, hasher),
|
||||
|
@ -120,7 +119,7 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet<K, S> {
|
|||
|
||||
/// Hash a given item to produce a usize.
|
||||
/// Uses the provided or default HashBuilder.
|
||||
#[inline]
|
||||
|
||||
pub fn hash_usize<T: Hash>(&self, item: &T) -> usize {
|
||||
self.inner.hash_usize(item)
|
||||
}
|
||||
|
@ -140,7 +139,7 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet<K, S> {
|
|||
/// let set = DashSet::<()>::new();
|
||||
/// println!("Amount of shards: {}", set.shards().len());
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn shards(&self) -> &[RwLock<HashMap<K, (), S>>] {
|
||||
self.inner.shards()
|
||||
}
|
||||
|
@ -163,7 +162,7 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet<K, S> {
|
|||
/// set.insert("coca-cola");
|
||||
/// println!("coca-cola is stored in shard: {}", set.determine_map("coca-cola"));
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn determine_map<Q>(&self, key: &Q) -> usize
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
|
@ -189,7 +188,7 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet<K, S> {
|
|||
/// let hash = set.hash_usize(&key);
|
||||
/// println!("hash is stored in shard: {}", set.determine_shard(hash));
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn determine_shard(&self, hash: usize) -> usize {
|
||||
self.inner.determine_shard(hash)
|
||||
}
|
||||
|
@ -205,7 +204,7 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet<K, S> {
|
|||
/// let set = DashSet::new();
|
||||
/// set.insert("I am the key!");
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn insert(&self, key: K) -> bool {
|
||||
self.inner.insert(key, ()).is_none()
|
||||
}
|
||||
|
@ -220,7 +219,7 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet<K, S> {
|
|||
/// soccer_team.insert("Jack");
|
||||
/// assert_eq!(soccer_team.remove("Jack").unwrap(), "Jack");
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn remove<Q>(&self, key: &Q) -> Option<K>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
|
@ -247,7 +246,7 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet<K, S> {
|
|||
/// soccer_team.remove_if("Jacob", |player| player.starts_with("Ja"));
|
||||
/// assert!(!soccer_team.contains("Jacob"));
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn remove_if<Q>(&self, key: &Q, f: impl FnOnce(&K) -> bool) -> Option<K>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
|
@ -267,7 +266,7 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet<K, S> {
|
|||
/// words.insert("hello");
|
||||
/// assert_eq!(words.iter().count(), 1);
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn iter(&'a self) -> Iter<'a, K, S, DashMap<K, (), S>> {
|
||||
let iter = self.inner.iter();
|
||||
Iter::new(iter)
|
||||
|
@ -283,7 +282,7 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet<K, S> {
|
|||
/// youtubers.insert("Bosnian Bill");
|
||||
/// assert_eq!(*youtubers.get("Bosnian Bill").unwrap(), "Bosnian Bill");
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn get<Q>(&'a self, key: &Q) -> Option<Ref<'a, K, S>>
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
|
@ -292,7 +291,7 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet<K, S> {
|
|||
self.inner.get(key).map(Ref::new)
|
||||
}
|
||||
/// Remove excess capacity to reduce memory usage.
|
||||
#[inline]
|
||||
|
||||
pub fn shrink_to_fit(&self) {
|
||||
self.inner.shrink_to_fit()
|
||||
}
|
||||
|
@ -311,7 +310,7 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet<K, S> {
|
|||
/// people.retain(|name| name.contains('i'));
|
||||
/// assert_eq!(people.len(), 2);
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn retain(&self, mut f: impl FnMut(&K) -> bool) {
|
||||
// TODO: Don't create another closure
|
||||
self.inner.retain(|k, _| f(k))
|
||||
|
@ -329,7 +328,7 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet<K, S> {
|
|||
/// people.insert("Charlie");
|
||||
/// assert_eq!(people.len(), 3);
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.inner.len()
|
||||
}
|
||||
|
@ -343,7 +342,7 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet<K, S> {
|
|||
/// let map = DashSet::<()>::new();
|
||||
/// assert!(map.is_empty());
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.inner.is_empty()
|
||||
}
|
||||
|
@ -360,12 +359,12 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet<K, S> {
|
|||
/// people.clear();
|
||||
/// assert!(people.is_empty());
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn clear(&self) {
|
||||
self.inner.clear()
|
||||
}
|
||||
/// Returns how many keys the set can store without reallocating.
|
||||
#[inline]
|
||||
|
||||
pub fn capacity(&self) -> usize {
|
||||
self.inner.capacity()
|
||||
}
|
||||
|
@ -380,7 +379,7 @@ impl<'a, K: 'a + Eq + Hash, S: BuildHasher + Clone> DashSet<K, S> {
|
|||
/// people.insert("Dakota Cherries");
|
||||
/// assert!(people.contains("Dakota Cherries"));
|
||||
/// ```
|
||||
#[inline]
|
||||
|
||||
pub fn contains<Q>(&self, key: &Q) -> bool
|
||||
where
|
||||
K: Borrow<Q>,
|
||||
|
|
|
@ -9,11 +9,10 @@ pub struct RefMulti<'a, K, S = RandomState> {
|
|||
}
|
||||
|
||||
impl<'a, K: Eq + Hash, S: BuildHasher> RefMulti<'a, K, S> {
|
||||
#[inline(always)]
|
||||
pub(crate) fn new(inner: mapref::multiple::RefMulti<'a, K, (), S>) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
#[inline(always)]
|
||||
|
||||
pub fn key(&self) -> &K {
|
||||
self.inner.key()
|
||||
}
|
||||
|
@ -21,7 +20,7 @@ impl<'a, K: Eq + Hash, S: BuildHasher> RefMulti<'a, K, S> {
|
|||
|
||||
impl<'a, K: Eq + Hash, S: BuildHasher> Deref for RefMulti<'a, K, S> {
|
||||
type Target = K;
|
||||
#[inline(always)]
|
||||
|
||||
fn deref(&self) -> &K {
|
||||
self.key()
|
||||
}
|
||||
|
|
|
@ -11,11 +11,10 @@ unsafe impl<'a, K: Eq + Hash + Send, S: BuildHasher> Send for Ref<'a, K, S> {}
|
|||
unsafe impl<'a, K: Eq + Hash + Send + Sync, S: BuildHasher> Sync for Ref<'a, K, S> {}
|
||||
|
||||
impl<'a, K: Eq + Hash, S: BuildHasher> Ref<'a, K, S> {
|
||||
#[inline(always)]
|
||||
pub(crate) fn new(inner: mapref::one::Ref<'a, K, (), S>) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
#[inline(always)]
|
||||
|
||||
pub fn key(&self) -> &K {
|
||||
self.inner.key()
|
||||
}
|
||||
|
@ -23,7 +22,7 @@ impl<'a, K: Eq + Hash, S: BuildHasher> Ref<'a, K, S> {
|
|||
|
||||
impl<'a, K: Eq + Hash, S: BuildHasher> Deref for Ref<'a, K, S> {
|
||||
type Target = K;
|
||||
#[inline(always)]
|
||||
|
||||
fn deref(&self) -> &K {
|
||||
self.key()
|
||||
}
|
||||
|
|
17
src/util.rs
17
src/util.rs
|
@ -4,12 +4,10 @@
|
|||
use core::cell::UnsafeCell;
|
||||
use core::{mem, ptr};
|
||||
|
||||
#[inline(always)]
|
||||
pub const fn ptr_size_bits() -> usize {
|
||||
mem::size_of::<usize>() * 8
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn map_in_place_2<T, U, F: FnOnce(U, T) -> T>((k, v): (U, &mut T), f: F) {
|
||||
unsafe {
|
||||
// # Safety
|
||||
|
@ -25,7 +23,7 @@ pub fn map_in_place_2<T, U, F: FnOnce(U, T) -> T>((k, v): (U, &mut T), f: F) {
|
|||
///
|
||||
/// Requires that you ensure the reference does not become invalid.
|
||||
/// The object has to outlive the reference.
|
||||
#[inline(always)]
|
||||
|
||||
pub unsafe fn change_lifetime_const<'a, 'b, T>(x: &'a T) -> &'b T {
|
||||
&*(x as *const T)
|
||||
}
|
||||
|
@ -34,7 +32,7 @@ pub unsafe fn change_lifetime_const<'a, 'b, T>(x: &'a T) -> &'b T {
|
|||
///
|
||||
/// Requires that you ensure the reference does not become invalid.
|
||||
/// The object has to outlive the reference.
|
||||
#[inline(always)]
|
||||
|
||||
pub unsafe fn change_lifetime_mut<'a, 'b, T>(x: &'a mut T) -> &'b mut T {
|
||||
&mut *(x as *mut T)
|
||||
}
|
||||
|
@ -67,7 +65,7 @@ unsafe impl<T: Sync> Sync for SharedValue<T> {}
|
|||
|
||||
impl<T> SharedValue<T> {
|
||||
/// Create a new `SharedValue<T>`
|
||||
#[inline]
|
||||
|
||||
pub const fn new(value: T) -> Self {
|
||||
Self {
|
||||
value: UnsafeCell::new(value),
|
||||
|
@ -75,25 +73,25 @@ impl<T> SharedValue<T> {
|
|||
}
|
||||
|
||||
/// Get a shared reference to `T`
|
||||
#[inline]
|
||||
|
||||
pub fn get(&self) -> &T {
|
||||
unsafe { &*self.value.get() }
|
||||
}
|
||||
|
||||
/// Get an unique reference to `T`
|
||||
#[inline]
|
||||
|
||||
pub fn get_mut(&mut self) -> &mut T {
|
||||
unsafe { &mut *self.value.get() }
|
||||
}
|
||||
|
||||
/// Unwraps the value
|
||||
#[inline]
|
||||
|
||||
pub fn into_inner(self) -> T {
|
||||
self.value.into_inner()
|
||||
}
|
||||
|
||||
/// Get a mutable raw pointer to the underlying value
|
||||
#[inline]
|
||||
|
||||
pub(crate) fn as_ptr(&self) -> *mut T {
|
||||
self.value.get()
|
||||
}
|
||||
|
@ -102,7 +100,6 @@ impl<T> SharedValue<T> {
|
|||
struct AbortOnPanic;
|
||||
|
||||
impl Drop for AbortOnPanic {
|
||||
#[inline]
|
||||
fn drop(&mut self) {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "no_std")] {
|
||||
|
|
Loading…
Reference in New Issue