expire_cache 0.1.20

High-performance generational cache for Rust / 高性能分代缓存
Documentation
use std::{borrow::Borrow, hash::Hash, ops::Deref};

use dashmap::DashMap;

use crate::Map;

pub struct RefVal<'a, K, V>(dashmap::mapref::one::Ref<'a, K, V>);

impl<'a, K, V> RefVal<'a, K, V>
where
  K: Eq + Hash,
{
  pub fn new(mapref: dashmap::mapref::one::Ref<'a, K, V>) -> Self {
    Self(mapref)
  }
}

impl<'a, K: Eq + Hash, V> Borrow<V> for RefVal<'a, K, V> {
  fn borrow(&self) -> &V {
    self.0.value()
  }
}

impl<'a, K: Eq + Hash, V> AsRef<V> for RefVal<'a, K, V> {
  fn as_ref(&self) -> &V {
    self.0.value()
  }
}

impl<'a, K: Eq + Hash, V> Deref for RefVal<'a, K, V> {
  type Target = V;

  fn deref(&self) -> &Self::Target {
    self.0.value()
  }
}

#[cfg(feature = "get_or_init")]
impl<K, V> crate::GetOrInit for DashMap<K, V>
where
  K: Eq + Hash + Send + Sync + 'static,
  V: Send + Sync + 'static,
{
  fn get_or_init<'a, Q, E>(
    &'a self,
    key: &Q,
    func: impl FnOnce(&Q) -> Result<V, E>,
  ) -> Result<Self::RefVal<'a>, E>
  where
    K: Borrow<Q>,
    Q: ToOwned<Owned = K> + Hash + Eq + ?Sized,
  {
    if let Some(r) = DashMap::get(self, key) {
      return Ok(RefVal::new(r));
    }
    let v = func(key)?;
    Ok(RefVal::new(
      self.entry(key.to_owned()).or_insert(v).downgrade(),
    ))
  }
}

impl<K, V> Map for DashMap<K, V>
where
  K: Eq + Hash + Send + Sync + 'static,
  V: Send + Sync + 'static,
{
  type Key = K;
  type Val = V;
  type RefVal<'a> = RefVal<'a, K, V>;

  fn clear(&self) {
    self.clear();
  }

  fn insert(&self, key: Self::Key, val: Self::Val) {
    self.insert(key, val);
  }

  fn get<'a, Q>(&'a self, key: &Q) -> Option<Self::RefVal<'a>>
  where
    K: Borrow<Q>,
    Q: Hash + Eq + ?Sized,
  {
    let mapref = DashMap::get(self, key)?;
    Some(RefVal::new(mapref))
  }
}