use crate::{shard::VersionedCacheShard, DefaultHashBuilder};
use std::{
borrow::Borrow,
hash::{BuildHasher, Hash},
};
pub struct VersionedCache<Key, Ver, Val, B = DefaultHashBuilder> {
shard: VersionedCacheShard<Key, Ver, Val, B>,
}
impl<Key: Eq + Hash, Ver: Eq + Hash, Val: Clone> VersionedCache<Key, Ver, Val, DefaultHashBuilder> {
pub fn new(initial_capacity: usize, max_capacity: usize) -> Self {
Self::with_hasher(
initial_capacity,
max_capacity,
DefaultHashBuilder::default(),
)
}
}
impl<Key: Eq + Hash, Ver: Eq + Hash, Val: Clone, B: BuildHasher + Clone>
VersionedCache<Key, Ver, Val, B>
{
pub fn with_hasher(initial_capacity: usize, max_capacity: usize, hasher: B) -> Self {
assert!(initial_capacity <= max_capacity);
let shard = VersionedCacheShard::new(initial_capacity, max_capacity, hasher);
Self { shard }
}
pub fn is_empty(&self) -> bool {
self.shard.len() == 0
}
pub fn len(&self) -> usize {
self.shard.len()
}
pub fn capacity(&self) -> usize {
self.shard.capacity()
}
pub fn misses(&self) -> u64 {
self.shard.misses()
}
pub fn hits(&self) -> u64 {
self.shard.hits()
}
pub fn get<Q: ?Sized, W: ?Sized>(&self, key: &Q, version: &W) -> Option<&Val>
where
Key: Borrow<Q>,
Q: Hash + Eq,
Ver: Borrow<W>,
W: Hash + Eq,
{
self.shard.get(self.shard.hash(key, version), key, version)
}
pub fn get_mut<Q: ?Sized, W: ?Sized>(&mut self, key: &Q, version: &W) -> Option<&mut Val>
where
Key: Borrow<Q>,
Q: Hash + Eq,
Ver: Borrow<W>,
W: Hash + Eq,
{
self.shard
.get_mut(self.shard.hash(key, version), key, version)
}
pub fn peek<Q: ?Sized, W: ?Sized>(&self, key: &Q, version: &W) -> Option<&Val>
where
Key: Borrow<Q>,
Q: Hash + Eq,
Ver: Borrow<W>,
W: Hash + Eq,
{
self.shard.peek(self.shard.hash(key, version), key, version)
}
pub fn peek_mut<Q: ?Sized, W: ?Sized>(&mut self, key: &Q, version: &W) -> Option<&mut Val>
where
Key: Borrow<Q>,
Q: Hash + Eq,
Ver: Borrow<W>,
W: Hash + Eq,
{
self.shard
.peek_mut(self.shard.hash(key, version), key, version)
}
pub fn remove<Q: ?Sized, W: ?Sized>(&mut self, key: &Q, version: &W) -> bool
where
Key: Borrow<Q>,
Q: Hash + Eq,
Ver: Borrow<W>,
W: Hash + Eq,
{
matches!(
self.shard
.remove(self.shard.hash(key, version), key, version),
Some(Ok(_))
)
}
pub fn insert(&mut self, key: Key, version: Ver, value: Val) {
self.shard
.insert(self.shard.hash(&key, &version), key, version, value);
}
}
impl<Key, Ver, Val> std::fmt::Debug for VersionedCache<Key, Ver, Val> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("VersionedCache").finish_non_exhaustive()
}
}
pub struct Cache<Key, Val, B = DefaultHashBuilder>(VersionedCache<Key, (), Val, B>);
impl<Key: Eq + Hash, Val: Clone> Cache<Key, Val, DefaultHashBuilder> {
pub fn new(initial_capacity: usize, max_capacity: usize) -> Self {
Self(VersionedCache::new(initial_capacity, max_capacity))
}
}
impl<Key: Eq + Hash, Val: Clone, B: Clone + BuildHasher> Cache<Key, Val, B> {
pub fn with_hasher(initial_capacity: usize, max_capacity: usize, hasher: B) -> Self {
Self(VersionedCache::with_hasher(
initial_capacity,
max_capacity,
hasher,
))
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn capacity(&self) -> usize {
self.0.capacity()
}
pub fn misses(&self) -> u64 {
self.0.misses()
}
pub fn hits(&self) -> u64 {
self.0.hits()
}
pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&Val>
where
Key: Borrow<Q>,
Q: Eq + Hash,
{
self.0.get(key, &())
}
pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut Val>
where
Key: Borrow<Q>,
Q: Eq + Hash,
{
self.0.get_mut(key, &())
}
pub fn peek<Q: ?Sized>(&self, key: &Q) -> Option<&Val>
where
Key: Borrow<Q>,
Q: Eq + Hash,
{
self.0.peek(key, &())
}
pub fn peek_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut Val>
where
Key: Borrow<Q>,
Q: Eq + Hash,
{
self.0.peek_mut(key, &())
}
pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> bool
where
Key: Borrow<Q>,
Q: Eq + Hash,
{
self.0.remove(key, &())
}
pub fn insert(&mut self, key: Key, value: Val) {
self.0.insert(key, (), value);
}
}
impl<Key: Eq + Hash, Val> std::fmt::Debug for Cache<Key, Val> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Cache").finish_non_exhaustive()
}
}