|
|
@ -6,90 +6,3 @@ use std::{
|
|
|
|
ToOwned,
|
|
|
|
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())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|