use crate::{shard::KQCacheShard, DefaultHashBuilder, UnitWeighter, Weighter};
use std::{
borrow::Borrow,
hash::{BuildHasher, Hash},
};
pub struct KQCache<Key, Qey, Val, We = UnitWeighter, B = DefaultHashBuilder> {
shard: KQCacheShard<Key, Qey, Val, We, B>,
}
impl<Key: Eq + Hash, Qey: Eq + Hash, Val> KQCache<Key, Qey, Val, UnitWeighter, DefaultHashBuilder> {
pub fn new(items_capacity: usize) -> Self {
Self::with(
items_capacity,
items_capacity as u64,
UnitWeighter,
DefaultHashBuilder::default(),
)
}
}
impl<Key: Eq + Hash, Qey: Eq + Hash, Val, We: Weighter<Key, Qey, Val>>
KQCache<Key, Qey, Val, We, DefaultHashBuilder>
{
pub fn with_weighter(
estimated_items_capacity: usize,
weight_capacity: u64,
weighter: We,
) -> KQCache<Key, Qey, Val, We, DefaultHashBuilder> {
Self::with(
estimated_items_capacity,
weight_capacity,
weighter,
DefaultHashBuilder::default(),
)
}
}
impl<Key: Eq + Hash, Qey: Eq + Hash, Val, We: Weighter<Key, Qey, Val>, B: BuildHasher>
KQCache<Key, Qey, Val, We, B>
{
pub fn with(
estimated_items_capacity: usize,
weight_capacity: u64,
weighter: We,
hasher: B,
) -> Self {
let shard = KQCacheShard::new(estimated_items_capacity, weight_capacity, weighter, hasher);
Self { shard }
}
pub fn is_empty(&self) -> bool {
self.shard.len() == 0
}
pub fn len(&self) -> usize {
self.shard.len()
}
pub fn weight(&self) -> u64 {
self.shard.weight()
}
pub fn capacity(&self) -> u64 {
self.shard.capacity()
}
pub fn misses(&self) -> u64 {
self.shard.misses()
}
pub fn hits(&self) -> u64 {
self.shard.hits()
}
pub fn reserve(&mut self, additional: usize) {
self.shard.reserve(additional);
}
pub fn get<Q: ?Sized, W: ?Sized>(&self, key: &Q, qey: &W) -> Option<&Val>
where
Key: Borrow<Q>,
Q: Hash + Eq,
Qey: Borrow<W>,
W: Hash + Eq,
{
self.shard.get(self.shard.hash(key, qey), key, qey)
}
pub fn get_mut<Q: ?Sized, W: ?Sized>(&mut self, key: &Q, qey: &W) -> Option<&mut Val>
where
Key: Borrow<Q>,
Q: Hash + Eq,
Qey: Borrow<W>,
W: Hash + Eq,
{
self.shard.get_mut(self.shard.hash(key, qey), key, qey)
}
pub fn peek<Q: ?Sized, W: ?Sized>(&self, key: &Q, qey: &W) -> Option<&Val>
where
Key: Borrow<Q>,
Q: Hash + Eq,
Qey: Borrow<W>,
W: Hash + Eq,
{
self.shard.peek(self.shard.hash(key, qey), key, qey)
}
pub fn peek_mut<Q: ?Sized, W: ?Sized>(&mut self, key: &Q, qey: &W) -> Option<&mut Val>
where
Key: Borrow<Q>,
Q: Hash + Eq,
Qey: Borrow<W>,
W: Hash + Eq,
{
self.shard.peek_mut(self.shard.hash(key, qey), key, qey)
}
pub fn remove<Q: ?Sized, W: ?Sized>(&mut self, key: &Q, qey: &W) -> bool
where
Key: Borrow<Q>,
Q: Hash + Eq,
Qey: Borrow<W>,
W: Hash + Eq,
{
matches!(
self.shard.remove(self.shard.hash(key, qey), key, qey),
Some(Ok(_))
)
}
pub fn insert(&mut self, key: Key, qey: Qey, value: Val) {
self.shard
.insert(self.shard.hash(&key, &qey), key, qey, value);
}
}
impl<Key, Qey, Val> std::fmt::Debug for KQCache<Key, Qey, Val> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("KQCache").finish_non_exhaustive()
}
}
pub struct Cache<Key, Val, We = UnitWeighter, B = DefaultHashBuilder>(KQCache<Key, (), Val, We, B>);
impl<Key: Eq + Hash, Val> Cache<Key, Val, UnitWeighter, DefaultHashBuilder> {
pub fn new(items_capacity: usize) -> Self {
Self(KQCache::new(items_capacity))
}
}
impl<Key: Eq + Hash, Val, We: Weighter<Key, (), Val>> Cache<Key, Val, We, DefaultHashBuilder> {
pub fn with_weighter(
estimated_items_capacity: usize,
weight_capacity: u64,
weighter: We,
) -> Cache<Key, Val, We, DefaultHashBuilder> {
Self::with(
estimated_items_capacity,
weight_capacity,
weighter,
DefaultHashBuilder::default(),
)
}
}
impl<Key: Eq + Hash, Val, We: Weighter<Key, (), Val>, B: BuildHasher> Cache<Key, Val, We, B> {
pub fn with(
estimated_items_capacity: usize,
weight_capacity: u64,
weighter: We,
hasher: B,
) -> Self {
Self(KQCache::with(
estimated_items_capacity,
weight_capacity,
weighter,
hasher,
))
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn weight(&self) -> u64 {
self.0.weight()
}
pub fn capacity(&self) -> u64 {
self.0.capacity()
}
pub fn misses(&self) -> u64 {
self.0.misses()
}
pub fn hits(&self) -> u64 {
self.0.hits()
}
pub fn reserve(&mut self, additional: usize) {
self.0.reserve(additional);
}
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()
}
}