dashmap 2.1.0

Blazing fast concurrent HashMap for Rust.
Documentation
use crate::mapref::interface::{RefInterface, RefMutInterface};
use crate::t::Map;
use crate::util;
use crate::DashMap;
use dashmap_shard::HashMap as ShardHashMap;
use fxhash::FxBuildHasher;
use parking_lot::RwLockWriteGuard;
use std::borrow::Borrow;
use std::cell::RefCell;
use std::collections::HashMap;
use std::hash::Hash;

fn tt_aq_shared(map: &RefCell<HashMap<u64, BorrowStatus>>, hash: u64) -> bool {
    let mut map = map.borrow_mut();
    if let Some(status) = map.get_mut(&hash) {
        match status {
            BorrowStatus::Shared(c) => {
                *c += 1;
                true
            }
            BorrowStatus::Exclusive => false,
        }
    } else {
        map.insert(hash, BorrowStatus::Shared(1));
        true
    }
}

pub(crate) fn tt_rl_shared(map: &RefCell<HashMap<u64, BorrowStatus>>, hash: u64) {
    let mut map = map.borrow_mut();
    if let Some(status) = map.get_mut(&hash) {
        match status {
            BorrowStatus::Shared(c) => {
                *c -= 1;
                if *c == 0 {
                    map.remove(&hash);
                }
            }
            BorrowStatus::Exclusive => unreachable!(),
        }
    }
}

pub(crate) fn tt_rl_exclusive(map: &RefCell<HashMap<u64, BorrowStatus>>, hash: u64) {
    let mut map = map.borrow_mut();
    map.remove(&hash);
}

fn tt_aq_exclusive(map: &RefCell<HashMap<u64, BorrowStatus>>, hash: u64) -> bool {
    let mut map = map.borrow_mut();
    if let Some(_) = map.get(&hash) {
        false
    } else {
        map.insert(hash, BorrowStatus::Exclusive);
        true
    }
}

pub(crate) enum BorrowStatus {
    Shared(usize),
    Exclusive,
}

pub struct Interface<'a, K: Eq + Hash, V> {
    base: &'a DashMap<K, V>,
    iic: RefCell<HashMap<usize, RwLockWriteGuard<'a, ShardHashMap<K, V, FxBuildHasher>>>>,
    borrows: RefCell<HashMap<u64, BorrowStatus>>,
}

impl<'a, K: Eq + Hash, V> Interface<'a, K, V> {
    pub(crate) fn new(base: &'a DashMap<K, V>) -> Self {
        Self {
            base,
            iic: RefCell::new(HashMap::new()),
            borrows: RefCell::new(HashMap::new()),
        }
    }

    fn ensure_has(&self, i: usize) {
        let mut iic = self.iic.borrow_mut();
        if !iic.contains_key(&i) {
            let guard = unsafe { self.base._yield_write_shard(i) };
            iic.insert(i, guard);
        }
    }

    #[inline]
    pub fn get<Q>(&'a self, key: &Q) -> Option<RefInterface<'a, K, V>>
    where
        K: Borrow<Q>,
        Q: Hash + Eq + ?Sized,
    {
        let (i, hash) = self.base.determine_map(key);
        if tt_aq_shared(&self.borrows, hash) {
            self.ensure_has(i);
            let iic = self.iic.borrow();
            let shard = &iic[&i];
            if let Some((kptr, vptr)) = shard.get_hash_nocheck_key_value(hash, key) {
                unsafe {
                    let kptr = util::change_lifetime_const(kptr);
                    let vptr = util::change_lifetime_const(vptr);
                    Some(RefInterface::new(hash, &self.borrows, kptr, vptr))
                }
            } else {
                None
            }
        } else {
            None
        }
    }

    #[inline]
    pub fn get_mut<Q>(&'a self, key: &Q) -> Option<RefMutInterface<'a, K, V>>
    where
        K: Borrow<Q>,
        Q: Hash + Eq + ?Sized,
    {
        let (i, hash) = self.base.determine_map(key);
        if tt_aq_exclusive(&self.borrows, hash) {
            self.ensure_has(i);
            let iic = self.iic.borrow();
            let shard = &iic[&i];
            if let Some((kptr, vptr)) = shard.get_hash_nocheck_key_value(hash, key) {
                unsafe {
                    let kptr = util::change_lifetime_const(kptr);
                    let vptr = util::change_lifetime_mut(util::to_mut(vptr));
                    Some(RefMutInterface::new(hash, &self.borrows, kptr, vptr))
                }
            } else {
                None
            }
        } else {
            None
        }
    }
}