You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
yuurei/src/cache.rs

96 lines
1.6 KiB

//! Caching interfaces
use super::*;
use std::{
borrow::{
Borrow,
ToOwned,
},
};
pub trait Cache<T>
{
fn cap(&self) -> Option<usize>;
fn len(&self) -> usize;
fn insert(&mut self, value: T) -> &T;
fn get<Q: ?Sized + PartialEq<T>>(&self, value: &Q) -> Option<&T>;
}
pub struct MemCache<T>(Vec<T>);
pub struct UnlimitedMemCache<T>(Vec<T>);
impl<T> MemCache<T>
{
/// Create a new cache with a max size
pub fn new(cap: usize) -> Self
{
Self(Vec::with_capacity(cap))
}
}
impl<T> Cache<T> for MemCache<T>
{
fn cap(&self) -> Option<usize>
{
Some(self.0.capacity())
}
fn len(&self) -> usize
{
self.0.len()
}
fn insert(&mut self, value: T) -> &T
{
if self.0.len() == self.0.capacity() {
self.0.remove(self.0.len()-1);
}
self.0.insert(0, value);
&self.0[0]
}
fn get<Q: ?Sized + PartialEq<T>>(&self, value: &Q) -> Option<&T>
{
for x in self.0.iter() {
if value.eq(x) {
return Some(x);
}
}
None
}
}
impl<T> UnlimitedMemCache<T>
{
/// Create a new cache
pub fn new() -> Self
{
Self(Vec::new())
}
}
// extension
pub trait CacheExt<T>
{
/// Insert into the cache if borrowed value is not present,
fn clone_insert<'a, Q>(&'a mut self, refer: &Q) -> &'a T
where Q: ToOwned<Owned=T> + ?Sized + PartialEq<T>,
T: Borrow<Q>;
}
impl<S, T> CacheExt<T> for S
where S: Cache<T>,
T: Clone
{
fn clone_insert<'a, Q>(&'a mut self, refer: &Q) -> &'a T
where Q: ToOwned<Owned=T> + ?Sized + PartialEq<T>,
T: Borrow<Q>
{
if let Some(get) = self.get(refer) {
return get;
}
self.insert(refer.to_owned())
}
}