use std::sync::atomic::{AtomicU64, Ordering};
#[derive(Debug, Default)]
pub struct Counter(AtomicU64);
impl Counter {
pub const fn new() -> Self {
Self(AtomicU64::new(0))
}
#[inline]
pub fn inc(&self) {
self.0.fetch_add(1, Ordering::Relaxed);
}
#[inline]
pub fn add(&self, n: u64) {
self.0.fetch_add(n, Ordering::Relaxed);
}
#[inline]
pub fn get(&self) -> u64 {
self.0.load(Ordering::Relaxed)
}
}
pub fn evict_from_dashmap<K, V, F>(map: &dashmap::DashMap<K, V>, should_evict: F) -> usize
where
K: Eq + std::hash::Hash + Clone,
F: Fn(&K, &V) -> bool,
{
let keys: Vec<K> = map
.iter()
.filter(|entry| should_evict(entry.key(), entry.value()))
.map(|entry| entry.key().clone())
.collect();
let count = keys.len();
for key in &keys {
map.remove(key);
}
count
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn counter_basics() {
let c = Counter::new();
assert_eq!(c.get(), 0);
c.inc();
assert_eq!(c.get(), 1);
c.add(5);
assert_eq!(c.get(), 6);
}
#[test]
fn evict_from_dashmap_works() {
let map = dashmap::DashMap::new();
map.insert("a", 1);
map.insert("b", 2);
map.insert("c", 3);
let evicted = evict_from_dashmap(&map, |_k, v| *v > 1);
assert_eq!(evicted, 2);
assert_eq!(map.len(), 1);
assert!(map.contains_key("a"));
}
#[test]
fn evict_none() {
let map: dashmap::DashMap<String, i32> = dashmap::DashMap::new();
map.insert("a".into(), 1);
let evicted = evict_from_dashmap(&map, |_k, _v| false);
assert_eq!(evicted, 0);
assert_eq!(map.len(), 1);
}
}