git_zero_core/cache/selected/
fixed.rs1use super::{Key, PackCache};
2use crate::{Error, Result};
3
4#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
5pub struct Statistics {
6 pub hits: u64,
7 pub misses: u64,
8 pub insertions: u64,
9 pub evictions: u64,
10}
11
12pub struct FixedCache<'a> {
16 storage: &'a mut [u8],
17 entry: Option<(Key, usize)>,
18 enabled: bool,
19 statistics: Statistics,
20}
21
22impl<'a> FixedCache<'a> {
23 pub fn new(storage: &'a mut [u8]) -> Self {
24 Self {
25 storage,
26 entry: None,
27 enabled: true,
28 statistics: Statistics::default(),
29 }
30 }
31 pub fn set_enabled(&mut self, enabled: bool) {
32 self.enabled = enabled;
33 }
34 pub fn statistics(&self) -> Statistics {
35 self.statistics
36 }
37 pub fn evict(&mut self) {
38 if self.entry.take().is_some() {
39 self.statistics.evictions = self.statistics.evictions.saturating_add(1);
40 }
41 }
42}
43
44impl PackCache for FixedCache<'_> {
45 fn get(&mut self, key: Key) -> Result<Option<&[u8]>> {
46 if let Some((_, length)) = self
47 .entry
48 .filter(|(stored, _)| self.enabled && *stored == key)
49 {
50 self.statistics.hits = self.statistics.hits.saturating_add(1);
51 return Ok(Some(&self.storage[..length]));
52 }
53 self.statistics.misses = self.statistics.misses.saturating_add(1);
54 Ok(None)
55 }
56 fn put(&mut self, key: Key, pack: &[u8]) -> Result<()> {
57 if !self.enabled {
58 return Ok(());
59 }
60 let destination = self
61 .storage
62 .get_mut(..pack.len())
63 .ok_or(Error::BufferTooSmall)?;
64 destination.copy_from_slice(pack);
65 self.entry = Some((key, pack.len()));
66 self.statistics.insertions = self.statistics.insertions.saturating_add(1);
67 Ok(())
68 }
69}