Fix StoreRatio fields visibility and improve documentation

This commit is contained in:
Julien Cretin
2020-10-29 12:23:34 +01:00
parent 8e22fbd9a6
commit 5ce91947b6
2 changed files with 29 additions and 11 deletions

View File

@@ -22,7 +22,7 @@ use std::collections::{HashMap, HashSet};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct StoreModel { pub struct StoreModel {
/// Represents the content of the store. /// Represents the content of the store.
map: HashMap<usize, Box<[u8]>>, content: HashMap<usize, Box<[u8]>>,
/// The modeled storage configuration. /// The modeled storage configuration.
format: Format, format: Format,
@@ -53,13 +53,13 @@ pub enum StoreOperation {
impl StoreModel { impl StoreModel {
/// Creates an empty model for a given storage configuration. /// Creates an empty model for a given storage configuration.
pub fn new(format: Format) -> StoreModel { pub fn new(format: Format) -> StoreModel {
let map = HashMap::new(); let content = HashMap::new();
StoreModel { map, format } StoreModel { content, format }
} }
/// Returns the modeled content. /// Returns the modeled content.
pub fn map(&self) -> &HashMap<usize, Box<[u8]>> { pub fn content(&self) -> &HashMap<usize, Box<[u8]>> {
&self.map &self.content
} }
/// Returns the storage configuration. /// Returns the storage configuration.
@@ -79,7 +79,7 @@ impl StoreModel {
/// Returns the capacity according to the model. /// Returns the capacity according to the model.
pub fn capacity(&self) -> StoreRatio { pub fn capacity(&self) -> StoreRatio {
let total = self.format.total_capacity(); let total = self.format.total_capacity();
let used: usize = self.map.values().map(|x| self.entry_size(x)).sum(); let used: usize = self.content.values().map(|x| self.entry_size(x)).sum();
StoreRatio { used, total } StoreRatio { used, total }
} }
@@ -100,11 +100,15 @@ impl StoreModel {
} }
// Fail if there is not enough capacity. // Fail if there is not enough capacity.
let capacity = match updates.len() { let capacity = match updates.len() {
// An empty transaction doesn't consume anything.
0 => 0, 0 => 0,
// Transactions with a single update are optimized by avoiding a marker entry.
1 => match &updates[0] { 1 => match &updates[0] {
StoreUpdate::Insert { value, .. } => self.entry_size(value), StoreUpdate::Insert { value, .. } => self.entry_size(value),
// Transactions with a single update which is a removal don't consume anything.
StoreUpdate::Remove { .. } => 0, StoreUpdate::Remove { .. } => 0,
}, },
// A transaction consumes one word for the marker entry in addition to its updates.
_ => 1 + updates.iter().map(|x| self.update_size(x)).sum::<usize>(), _ => 1 + updates.iter().map(|x| self.update_size(x)).sum::<usize>(),
}; };
if self.capacity().remaining() < capacity { if self.capacity().remaining() < capacity {
@@ -114,10 +118,10 @@ impl StoreModel {
for update in updates { for update in updates {
match update { match update {
StoreUpdate::Insert { key, value } => { StoreUpdate::Insert { key, value } => {
self.map.insert(key, value.into_boxed_slice()); self.content.insert(key, value.into_boxed_slice());
} }
StoreUpdate::Remove { key } => { StoreUpdate::Remove { key } => {
self.map.remove(&key); self.content.remove(&key);
} }
} }
} }
@@ -129,7 +133,7 @@ impl StoreModel {
if min_key > self.format.max_key() { if min_key > self.format.max_key() {
return Err(StoreError::InvalidArgument); return Err(StoreError::InvalidArgument);
} }
self.map.retain(|&k, _| k < min_key); self.content.retain(|&k, _| k < min_key);
Ok(()) Ok(())
} }

View File

@@ -69,18 +69,32 @@ pub type StoreResult<T> = Result<T, StoreError>;
/// ///
/// This is used for the [capacity] and [lifetime] metrics. Those metrics are measured in words. /// This is used for the [capacity] and [lifetime] metrics. Those metrics are measured in words.
/// ///
/// # Invariant
///
/// - The used value does not exceed the total: `used <= total`.
///
/// [capacity]: struct.Store.html#method.capacity /// [capacity]: struct.Store.html#method.capacity
/// [lifetime]: struct.Store.html#method.lifetime /// [lifetime]: struct.Store.html#method.lifetime
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
pub struct StoreRatio { pub struct StoreRatio {
/// How much of the metric is used. /// How much of the metric is used.
pub used: usize, pub(crate) used: usize,
/// How much of the metric can be used at most. /// How much of the metric can be used at most.
pub total: usize, pub(crate) total: usize,
} }
impl StoreRatio { impl StoreRatio {
/// How much of the metric is used.
pub fn used(self) -> usize {
self.used
}
/// How much of the metric can be used at most.
pub fn total(self) -> usize {
self.total
}
/// How much of the metric is remaining. /// How much of the metric is remaining.
pub fn remaining(self) -> usize { pub fn remaining(self) -> usize {
self.total - self.used self.total - self.used