Merge pull request #322 from ia0/fix_320
Stop using try_trait in persistent_store
This commit is contained in:
4
.github/workflows/persistent_store_test.yml
vendored
4
.github/workflows/persistent_store_test.yml
vendored
@@ -22,10 +22,10 @@ jobs:
|
|||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: test
|
command: test
|
||||||
args: --manifest-path libraries/persistent_store/Cargo.toml --release --features std
|
args: --manifest-path libraries/persistent_store/Cargo.toml --release --features=std
|
||||||
|
|
||||||
- name: Unit testing of Persistent store library (debug mode)
|
- name: Unit testing of Persistent store library (debug mode)
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: test
|
command: test
|
||||||
args: --manifest-path libraries/persistent_store/Cargo.toml --features std
|
args: --manifest-path libraries/persistent_store/Cargo.toml --features=std
|
||||||
|
|||||||
@@ -335,7 +335,6 @@
|
|||||||
//! is checked not to crash.
|
//! is checked not to crash.
|
||||||
|
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
#![feature(try_trait)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ use alloc::vec::Vec;
|
|||||||
use core::borrow::Borrow;
|
use core::borrow::Borrow;
|
||||||
use core::cmp::{max, min, Ordering};
|
use core::cmp::{max, min, Ordering};
|
||||||
use core::convert::TryFrom;
|
use core::convert::TryFrom;
|
||||||
use core::option::NoneError;
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
@@ -78,17 +77,16 @@ impl From<StorageError> for StoreError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<NoneError> for StoreError {
|
|
||||||
fn from(error: NoneError) -> StoreError {
|
|
||||||
match error {
|
|
||||||
NoneError => StoreError::InvalidStorage,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Result of store operations.
|
/// Result of store operations.
|
||||||
pub type StoreResult<T> = Result<T, StoreError>;
|
pub type StoreResult<T> = Result<T, StoreError>;
|
||||||
|
|
||||||
|
/// Converts an Option into a StoreResult.
|
||||||
|
///
|
||||||
|
/// The None case is considered invalid and returns [`StoreError::InvalidStorage`].
|
||||||
|
fn or_invalid<T>(x: Option<T>) -> StoreResult<T> {
|
||||||
|
x.ok_or(StoreError::InvalidStorage)
|
||||||
|
}
|
||||||
|
|
||||||
/// Progression ratio for store metrics.
|
/// Progression ratio for store metrics.
|
||||||
///
|
///
|
||||||
/// This is used for the [`Store::capacity`] and [`Store::lifetime`] metrics. Those metrics are
|
/// This is used for the [`Store::capacity`] and [`Store::lifetime`] metrics. Those metrics are
|
||||||
@@ -242,8 +240,8 @@ impl<S: Storage> Store<S> {
|
|||||||
|
|
||||||
/// Iterates over the entries.
|
/// Iterates over the entries.
|
||||||
pub fn iter<'a>(&'a self) -> StoreResult<StoreIter<'a>> {
|
pub fn iter<'a>(&'a self) -> StoreResult<StoreIter<'a>> {
|
||||||
let head = self.head?;
|
let head = or_invalid(self.head)?;
|
||||||
Ok(Box::new(self.entries.as_ref()?.iter().map(
|
Ok(Box::new(or_invalid(self.entries.as_ref())?.iter().map(
|
||||||
move |&offset| {
|
move |&offset| {
|
||||||
let pos = head + offset as Nat;
|
let pos = head + offset as Nat;
|
||||||
match self.parse_entry(&mut pos.clone())? {
|
match self.parse_entry(&mut pos.clone())? {
|
||||||
@@ -532,7 +530,7 @@ impl<S: Storage> Store<S> {
|
|||||||
/// Recover a possible interrupted operation which is not a compaction.
|
/// Recover a possible interrupted operation which is not a compaction.
|
||||||
fn recover_operation(&mut self) -> StoreResult<()> {
|
fn recover_operation(&mut self) -> StoreResult<()> {
|
||||||
self.entries = Some(Vec::new());
|
self.entries = Some(Vec::new());
|
||||||
let mut pos = self.head?;
|
let mut pos = or_invalid(self.head)?;
|
||||||
let mut prev_pos = pos;
|
let mut prev_pos = pos;
|
||||||
let end = pos + self.format.virt_size();
|
let end = pos + self.format.virt_size();
|
||||||
while pos < end {
|
while pos < end {
|
||||||
@@ -672,7 +670,7 @@ impl<S: Storage> Store<S> {
|
|||||||
///
|
///
|
||||||
/// In particular, the handle has not been compacted.
|
/// In particular, the handle has not been compacted.
|
||||||
fn check_handle(&self, handle: &StoreHandle) -> StoreResult<()> {
|
fn check_handle(&self, handle: &StoreHandle) -> StoreResult<()> {
|
||||||
if handle.pos < self.head? {
|
if handle.pos < or_invalid(self.head)? {
|
||||||
Err(StoreError::InvalidArgument)
|
Err(StoreError::InvalidArgument)
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -702,7 +700,7 @@ impl<S: Storage> Store<S> {
|
|||||||
|
|
||||||
/// Compacts one page.
|
/// Compacts one page.
|
||||||
fn compact(&mut self) -> StoreResult<()> {
|
fn compact(&mut self) -> StoreResult<()> {
|
||||||
let head = self.head?;
|
let head = or_invalid(self.head)?;
|
||||||
if head.cycle(&self.format) >= self.format.max_page_erases() {
|
if head.cycle(&self.format) >= self.format.max_page_erases() {
|
||||||
return Err(StoreError::NoLifetime);
|
return Err(StoreError::NoLifetime);
|
||||||
}
|
}
|
||||||
@@ -717,7 +715,7 @@ impl<S: Storage> Store<S> {
|
|||||||
|
|
||||||
/// Continues a compaction after its compact page info has been written.
|
/// Continues a compaction after its compact page info has been written.
|
||||||
fn compact_copy(&mut self) -> StoreResult<()> {
|
fn compact_copy(&mut self) -> StoreResult<()> {
|
||||||
let mut head = self.head?;
|
let mut head = or_invalid(self.head)?;
|
||||||
let page = head.page(&self.format);
|
let page = head.page(&self.format);
|
||||||
let end = head.next_page(&self.format);
|
let end = head.next_page(&self.format);
|
||||||
let mut tail = match self.parse_compact(page)? {
|
let mut tail = match self.parse_compact(page)? {
|
||||||
@@ -773,9 +771,9 @@ impl<S: Storage> Store<S> {
|
|||||||
};
|
};
|
||||||
let head = self.format.page_head(init, page);
|
let head = self.format.page_head(init, page);
|
||||||
if let Some(entries) = &mut self.entries {
|
if let Some(entries) = &mut self.entries {
|
||||||
let head_offset = u16::try_from(head - self.head?).ok()?;
|
let head_offset = or_invalid(u16::try_from(head - or_invalid(self.head)?).ok())?;
|
||||||
for entry in entries {
|
for entry in entries {
|
||||||
*entry = entry.checked_sub(head_offset)?;
|
*entry = or_invalid(entry.checked_sub(head_offset))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.head = Some(head);
|
self.head = Some(head);
|
||||||
@@ -791,7 +789,7 @@ impl<S: Storage> Store<S> {
|
|||||||
fn transaction_apply(&mut self, sorted_keys: &[Nat], marker: Position) -> StoreResult<()> {
|
fn transaction_apply(&mut self, sorted_keys: &[Nat], marker: Position) -> StoreResult<()> {
|
||||||
self.delete_keys(&sorted_keys, marker)?;
|
self.delete_keys(&sorted_keys, marker)?;
|
||||||
self.set_padding(marker)?;
|
self.set_padding(marker)?;
|
||||||
let end = self.head? + self.format.virt_size();
|
let end = or_invalid(self.head)? + self.format.virt_size();
|
||||||
let mut pos = marker + 1;
|
let mut pos = marker + 1;
|
||||||
while pos < end {
|
while pos < end {
|
||||||
let entry_pos = pos;
|
let entry_pos = pos;
|
||||||
@@ -826,8 +824,8 @@ impl<S: Storage> Store<S> {
|
|||||||
|
|
||||||
/// Deletes entries matching a predicate up to a certain position.
|
/// Deletes entries matching a predicate up to a certain position.
|
||||||
fn delete_if(&mut self, end: Position, delete: impl Fn(Nat) -> bool) -> StoreResult<()> {
|
fn delete_if(&mut self, end: Position, delete: impl Fn(Nat) -> bool) -> StoreResult<()> {
|
||||||
let head = self.head?;
|
let head = or_invalid(self.head)?;
|
||||||
let mut entries = self.entries.take()?;
|
let mut entries = or_invalid(self.entries.take())?;
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
while i < entries.len() {
|
while i < entries.len() {
|
||||||
let pos = head + entries[i] as Nat;
|
let pos = head + entries[i] as Nat;
|
||||||
@@ -924,20 +922,20 @@ impl<S: Storage> Store<S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// There is always at least one initialized page.
|
// There is always at least one initialized page.
|
||||||
Ok(best?)
|
or_invalid(best)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the number of words that can be written without compaction.
|
/// Returns the number of words that can be written without compaction.
|
||||||
fn immediate_capacity(&self) -> StoreResult<Nat> {
|
fn immediate_capacity(&self) -> StoreResult<Nat> {
|
||||||
let tail = self.tail()?;
|
let tail = self.tail()?;
|
||||||
let end = self.head? + self.format.virt_size();
|
let end = or_invalid(self.head)? + self.format.virt_size();
|
||||||
Ok(end.get().saturating_sub(tail.get()))
|
Ok(end.get().saturating_sub(tail.get()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the position of the first word in the store.
|
/// Returns the position of the first word in the store.
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub(crate) fn head(&self) -> StoreResult<Position> {
|
pub(crate) fn head(&self) -> StoreResult<Position> {
|
||||||
Ok(self.head?)
|
or_invalid(self.head)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns one past the position of the last word in the store.
|
/// Returns one past the position of the last word in the store.
|
||||||
@@ -957,8 +955,8 @@ impl<S: Storage> Store<S> {
|
|||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
};
|
};
|
||||||
let head = self.head?;
|
let head = or_invalid(self.head)?;
|
||||||
let offset = u16::try_from(pos - head).ok()?;
|
let offset = or_invalid(u16::try_from(pos - head).ok())?;
|
||||||
debug_assert!(!entries.contains(&offset));
|
debug_assert!(!entries.contains(&offset));
|
||||||
entries.push(offset);
|
entries.push(offset);
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -969,9 +967,9 @@ impl<S: Storage> Store<S> {
|
|||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
};
|
};
|
||||||
let head = self.head?;
|
let head = or_invalid(self.head)?;
|
||||||
let offset = u16::try_from(pos - head).ok()?;
|
let offset = or_invalid(u16::try_from(pos - head).ok())?;
|
||||||
let i = entries.iter().position(|x| *x == offset)?;
|
let i = or_invalid(entries.iter().position(|x| *x == offset))?;
|
||||||
entries.swap_remove(i);
|
entries.swap_remove(i);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user