Struct plru::Cache
[−]
[src]
pub struct Cache<B> { /* fields omitted */ }
A pseudo-LRU cache tracker.
This manages a set of cache lines (enumerated by usize
) in an efficient manner, such that you
can touch cache lines (mark usage) and efficiently find a cache line which can be replaced
(unlikely to be used in the near future).
Methods
impl<B: AsRef<[AtomicU64]>> Cache<B>
[src]
fn new(bulks: B) -> Cache<B>
Create a new cache based on some array.
Generally, this should not be used unless you're building abstractions. You should likely
use Cache::<SomeType>::default()
or plru::create()
instead.
Example
use plru::Cache; Cache::new([Default::default(), Default::default()]);
fn touch(&self, n: usize)
Touch the n'th cache line.
Whenever you modify/use the cache line, you should call touch
in order to mark that it
was recently used.
Each cache line has a bitflag defining if it was recently used. This will set said flag.
Example
let cache = plru::SmallCache::default(); cache.touch(10); assert!(cache.is_hot(10));
fn trash(&self, n: usize)
Trash the n'th cache line.
Trashing is generally only used if you know that this line is not going to be used later on.
Trashing will merely mark this line as cold, and hence be queued for replacement until it is used again. As such, it is not a terrible performance loss if you trash a line which is used later, and decision can be made heuristically ("this is likely not going to be used later again").
Example
let cache = plru::SmallCache::default(); cache.touch(10); assert!(cache.is_hot(10)); cache.trash(10); assert!(!cache.is_hot(10));
fn replace(&self) -> usize
Find the approximately least recently used cache line to replace.
A particular bulk is selected based on a counter incremented on every replace
call. The
first unset bit of this bulk determines the cold cache line we will return. If all the
flags in the 64-bit bulk are set, the whole bulk will be reset to zero in order to inflate
the cache.
This is approximately the least-recently-used cache line.
Note that it will not set the found bit. If you use the line right after requesting it, you
still need to call touch
. In fact, it will always return a cold line.
You cannot rely on uniqueness of the output. It might return the same result twice, although it is unlikely.
Example
let cache = plru::MediumCache::default(); cache.touch(10); cache.touch(20); cache.touch(1); assert_ne!(cache.replace(), 1); assert_ne!(cache.replace(), 20); assert_ne!(cache.replace(), 10);
fn len(&self) -> usize
Find the number of cache lines in this cache.
This is subject equal to the length of B
mutliplied by 64.
Example
assert_eq!(plru::create(10).len(), 64); assert_eq!(plru::create(64).len(), 64); assert_eq!(plru::create(65).len(), 128);
fn is_hot(&self, n: usize) -> bool
Is the n'th cache line hot?
This returns a boolean defining if it has recently be used or not. true
means that the
cache line is registered as "hot" and false
that it is registered as "cold".
Example
let cache = plru::MicroCache::default(); cache.touch(2); assert!(cache.is_hot(2)); assert!(!cache.is_hot(3));