Skip to content

Commit

Permalink
SerCache, add helper functions
Browse files Browse the repository at this point in the history
  • Loading branch information
RCasatta committed Aug 2, 2023
1 parent 2aa6d90 commit 5f08a35
Showing 1 changed file with 27 additions and 5 deletions.
32 changes: 27 additions & 5 deletions src/ser_cache.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use alloc::{boxed::Box, collections::VecDeque, rc::Rc};
use alloc::{boxed::Box, collections::VecDeque, sync::Arc};
use core::hash::Hash;
use hashbrown::HashMap;

Expand All @@ -8,7 +8,7 @@ pub enum Error {
ValueAlreadyPresent,
}

/// A LIFO cache for serializable objects with predictable size and almost no allocations at regime
/// A FIFO cache for serializable objects with predictable size and almost no allocations at regime
/// and almost no wasted space.
///
/// The serialized cache requires an allocator.
Expand All @@ -35,10 +35,14 @@ pub struct SerCache<K: Hash + PartialEq + Eq + core::fmt::Debug> {
free_pointer: usize,

/// Pointers to buffer of the serialized objects
indexes: HashMap<Rc<K>, Range>,
indexes: HashMap<Arc<K>, Range>,

/// Order of the key inserted
insertions: VecDeque<Rc<K>>,
insertions: VecDeque<Arc<K>>,

/// The cache is full, at least once it removed an older element to insert a new one.
/// Obviously elements can still be inserted but they may remove older elements.
full: bool,
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
Expand Down Expand Up @@ -66,6 +70,7 @@ impl<K: Hash + PartialEq + Eq + core::fmt::Debug> SerCache<K> {
free_pointer: 0,
indexes: HashMap::new(),
insertions: VecDeque::new(),
full: false,
}
}
/// Insert a value V in the cache, with key K
Expand All @@ -89,14 +94,15 @@ impl<K: Hash + PartialEq + Eq + core::fmt::Debug> SerCache<K> {
end: self.buffer.len(),
});
self.free_pointer = 0;
self.full = true;
}
let begin = self.free_pointer;
let end = begin + value.len();
self.buffer[begin..end].copy_from_slice(value);
self.free_pointer = end;

let inserted_range = Range { begin, end };
let key = Rc::new(key);
let key = Arc::new(key);
self.indexes.insert(key.clone(), inserted_range.clone());
self.insertions.push_front(key);

Expand All @@ -114,6 +120,11 @@ impl<K: Hash + PartialEq + Eq + core::fmt::Debug> SerCache<K> {
Some(&self.buffer[index.begin..index.end])
}

/// Return wether the cache contains the given key
pub fn contains(&self, key: &K) -> bool {
self.indexes.get(key).is_some()
}

#[cfg(feature = "redb")]
/// Get the value at key `K` if exist in the cache, `None` otherwise
pub fn get_value<'a, V: redb::RedbValue>(&'a self, key: &K) -> Option<V::SelfType<'a>> {
Expand All @@ -123,6 +134,17 @@ impl<K: Hash + PartialEq + Eq + core::fmt::Debug> SerCache<K> {
Some(value)
}

/// Return the number of elements contained in the cache
pub fn len(&self) -> usize {
self.indexes.len()
}

/// Return wether the cache filled the inner buffer of serialized object and removed at least
/// one older element, following inserted elements will likely remove older entries.
pub fn full(&self) -> bool {
self.full
}

fn remove_range(&mut self, range_to_remove: &Range) -> usize {
let mut removed = 0;

Expand Down

0 comments on commit 5f08a35

Please sign in to comment.