From 5ce91947b6b458d9b49336ef62e9ef8a3a0d0bad Mon Sep 17 00:00:00 2001 From: Julien Cretin Date: Thu, 29 Oct 2020 12:23:34 +0100 Subject: [PATCH] Fix StoreRatio fields visibility and improve documentation --- libraries/persistent_store/src/model.rs | 22 +++++++++++++--------- libraries/persistent_store/src/store.rs | 18 ++++++++++++++++-- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/libraries/persistent_store/src/model.rs b/libraries/persistent_store/src/model.rs index 74eea698..2677265b 100644 --- a/libraries/persistent_store/src/model.rs +++ b/libraries/persistent_store/src/model.rs @@ -22,7 +22,7 @@ use std::collections::{HashMap, HashSet}; #[derive(Clone, Debug)] pub struct StoreModel { /// Represents the content of the store. - map: HashMap>, + content: HashMap>, /// The modeled storage configuration. format: Format, @@ -53,13 +53,13 @@ pub enum StoreOperation { impl StoreModel { /// Creates an empty model for a given storage configuration. pub fn new(format: Format) -> StoreModel { - let map = HashMap::new(); - StoreModel { map, format } + let content = HashMap::new(); + StoreModel { content, format } } /// Returns the modeled content. - pub fn map(&self) -> &HashMap> { - &self.map + pub fn content(&self) -> &HashMap> { + &self.content } /// Returns the storage configuration. @@ -79,7 +79,7 @@ impl StoreModel { /// Returns the capacity according to the model. pub fn capacity(&self) -> StoreRatio { 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 } } @@ -100,11 +100,15 @@ impl StoreModel { } // Fail if there is not enough capacity. let capacity = match updates.len() { + // An empty transaction doesn't consume anything. 0 => 0, + // Transactions with a single update are optimized by avoiding a marker entry. 1 => match &updates[0] { StoreUpdate::Insert { value, .. } => self.entry_size(value), + // Transactions with a single update which is a removal don't consume anything. 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::(), }; if self.capacity().remaining() < capacity { @@ -114,10 +118,10 @@ impl StoreModel { for update in updates { match update { StoreUpdate::Insert { key, value } => { - self.map.insert(key, value.into_boxed_slice()); + self.content.insert(key, value.into_boxed_slice()); } StoreUpdate::Remove { key } => { - self.map.remove(&key); + self.content.remove(&key); } } } @@ -129,7 +133,7 @@ impl StoreModel { if min_key > self.format.max_key() { return Err(StoreError::InvalidArgument); } - self.map.retain(|&k, _| k < min_key); + self.content.retain(|&k, _| k < min_key); Ok(()) } diff --git a/libraries/persistent_store/src/store.rs b/libraries/persistent_store/src/store.rs index d8d39ae2..473310bc 100644 --- a/libraries/persistent_store/src/store.rs +++ b/libraries/persistent_store/src/store.rs @@ -69,18 +69,32 @@ pub type StoreResult = Result; /// /// 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 /// [lifetime]: struct.Store.html#method.lifetime #[derive(Copy, Clone, PartialEq, Eq)] pub struct StoreRatio { /// How much of the metric is used. - pub used: usize, + pub(crate) used: usize, /// How much of the metric can be used at most. - pub total: usize, + pub(crate) total: usize, } 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. pub fn remaining(self) -> usize { self.total - self.used