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:
Acrimon 2020-07-31 22:43:28 +02:00
parent aff9eb407f
commit 64e4e960db
No known key found for this signature in database
GPG Key ID: 79B55D369EAD2A06
12 changed files with 284 additions and 389 deletions

View File

@ -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() {

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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,

View File

@ -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();

View File

@ -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()
}

View File

@ -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()
}

View File

@ -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)));
}
}
}

View File

@ -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>,

View File

@ -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()
}

View File

@ -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()
}

View File

@ -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")] {