ritecache/meter/
count_meter.rs

1use std::borrow::Borrow;
2
3use super::Meter;
4
5/// Size limit based on a simple count of cache items.
6pub struct Count;
7
8impl<K, V> Meter<K, V> for Count {
9    /// Don't store anything, the measurement can be derived from the map.
10    type Measure = ();
11
12    /// Don't actually count anything either.
13    fn measure<Q: ?Sized>(&self, _: &Q, _: &V)
14    where
15        K: Borrow<Q>,
16    {
17    }
18}
19
20/// A trait to allow the default `Count` measurement to not store an
21/// extraneous counter.
22pub trait CountableMeter<K, V>: Meter<K, V> {
23    /// Add `amount` to `current` and return the sum.
24    fn add(&self, current: Self::Measure, amount: Self::Measure) -> Self::Measure;
25    /// Subtract `amount` from `current` and return the difference.
26    fn sub(&self, current: Self::Measure, amount: Self::Measure) -> Self::Measure;
27    /// Return `current` as a `usize` if possible, otherwise return `None`.
28    ///
29    /// If this method returns `None` the cache will use the number of cache entries as
30    /// its size.
31    fn size(&self, current: Self::Measure) -> Option<u64>;
32}
33
34/// `Count` is all no-ops, the number of entries in the map is the size.
35impl<K, V, T: Meter<K, V>> CountableMeter<K, V> for T
36where
37    T: CountableMeterWithMeasure<K, V, <T as Meter<K, V>>::Measure>,
38{
39    fn add(&self, current: Self::Measure, amount: Self::Measure) -> Self::Measure {
40        CountableMeterWithMeasure::meter_add(self, current, amount)
41    }
42    fn sub(&self, current: Self::Measure, amount: Self::Measure) -> Self::Measure {
43        CountableMeterWithMeasure::meter_sub(self, current, amount)
44    }
45    fn size(&self, current: Self::Measure) -> Option<u64> {
46        CountableMeterWithMeasure::meter_size(self, current)
47    }
48}
49
50pub trait CountableMeterWithMeasure<K, V, M> {
51    /// Add `amount` to `current` and return the sum.
52    fn meter_add(&self, current: M, amount: M) -> M;
53    /// Subtract `amount` from `current` and return the difference.
54    fn meter_sub(&self, current: M, amount: M) -> M;
55    /// Return `current` as a `usize` if possible, otherwise return `None`.
56    ///
57    /// If this method returns `None` the cache will use the number of cache entries as
58    /// its size.
59    fn meter_size(&self, current: M) -> Option<u64>;
60}
61
62/// For any other `Meter` with `Measure=usize`, just do the simple math.
63impl<K, V, T> CountableMeterWithMeasure<K, V, usize> for T
64where
65    T: Meter<K, V>,
66{
67    fn meter_add(&self, current: usize, amount: usize) -> usize {
68        current + amount
69    }
70    fn meter_sub(&self, current: usize, amount: usize) -> usize {
71        current - amount
72    }
73    fn meter_size(&self, current: usize) -> Option<u64> {
74        Some(current as u64)
75    }
76}
77
78impl<K, V> CountableMeterWithMeasure<K, V, ()> for Count {
79    fn meter_add(&self, _current: (), _amount: ()) {}
80    fn meter_sub(&self, _current: (), _amount: ()) {}
81    fn meter_size(&self, _current: ()) -> Option<u64> {
82        None
83    }
84}