Skip to content

Commit

Permalink
Merge pull request #59 from tweedegolf/keys-by-ref
Browse files Browse the repository at this point in the history
Take keys by reference
  • Loading branch information
diondokter authored Jul 17, 2024
2 parents aea3565 + aefb7d3 commit 9912929
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 124 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,10 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
- uses: cargo-bins/cargo-binstall@main

- name: Install cargo fuzz
uses: taiki-e/install-action@v2
with:
tool: cargo-fuzz
run: cargo binstall cargo-fuzz --no-confirm --target x86_64-unknown-linux-gnu

- name: Smoke-test fuzz targets
run: |
Expand Down
9 changes: 6 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,21 @@

## Unreleased

## 3.0.0 17-07-24

- *Breaking:* Map keys are now always passed by reference. This avoids extra cloning and memory use for bigger keys.
- Added `space_left` function for queue
- Added a new `map::remove_all_items()` API to remove all stored items in flash.

# 2.0.2 07-05-24
## 2.0.2 07-05-24

- Added check for too big items that won't ever fit in flash so it returns a good clear error.

# 2.0.1 06-05-24
## 2.0.1 06-05-24

- Implemented the `get_len` function for all built-in key types

# 2.0.0 06-05-24
## 2.0.0 06-05-24

- *Breaking:* Made the cache API a bit more strict. Caches now always have to be passed as a mutable reference.
The API before would lead to a lot of extra unncesessary binary size.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sequential-storage"
version = "2.0.2"
version = "3.0.0"
edition = "2021"
license = "MIT OR Apache-2.0"
description = "A crate for storing data in flash with minimal erase cycles."
Expand Down
2 changes: 1 addition & 1 deletion example/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions example/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ async fn run_map<E: defmt::Format>(
flash_range.clone(),
&mut NoCache::new(),
&mut data_buffer,
0u8,
&0u8,
&0u8,
)
.await
Expand All @@ -108,7 +108,7 @@ async fn run_map<E: defmt::Format>(
flash_range.clone(),
&mut NoCache::new(),
&mut data_buffer,
1u8,
&1u8,
&123u32,
)
.await
Expand All @@ -120,7 +120,7 @@ async fn run_map<E: defmt::Format>(
flash_range.clone(),
&mut NoCache::new(),
&mut data_buffer,
2u8,
&2u8,
&0.123f32,
)
.await
Expand All @@ -132,7 +132,7 @@ async fn run_map<E: defmt::Format>(
flash_range.clone(),
&mut NoCache::new(),
&mut data_buffer,
3,
&3,
)
.await
);
Expand All @@ -145,7 +145,7 @@ async fn run_map<E: defmt::Format>(
flash_range.clone(),
&mut NoCache::new(),
&mut data_buffer,
1,
&1,
)
.await
);
Expand Down
12 changes: 6 additions & 6 deletions fuzz/fuzz_targets/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ fn fuzz(ops: Input, mut cache: impl KeyCacheImpl<u8> + Debug) {
FLASH_RANGE,
&mut cache,
&mut buf.0,
key,
&key,
&value.as_slice(),
)) {
Ok(_) => {
Expand All @@ -121,7 +121,7 @@ fn fuzz(ops: Input, mut cache: impl KeyCacheImpl<u8> + Debug) {
FLASH_RANGE,
&mut cache,
&mut buf.0,
key,
&key,
)) {
Ok(Some(check_item)) if check_item == value => {
#[cfg(fuzzing_repro)]
Expand Down Expand Up @@ -152,7 +152,7 @@ fn fuzz(ops: Input, mut cache: impl KeyCacheImpl<u8> + Debug) {
FLASH_RANGE,
&mut cache,
&mut buf.0,
key,
&key,
)) {
Ok(Some(fetch_result)) => {
let map_value = map
Expand Down Expand Up @@ -186,7 +186,7 @@ fn fuzz(ops: Input, mut cache: impl KeyCacheImpl<u8> + Debug) {
FLASH_RANGE,
&mut cache,
&mut buf.0,
key,
&key,
)) {
Ok(()) => {
map.remove(&key);
Expand All @@ -201,7 +201,7 @@ fn fuzz(ops: Input, mut cache: impl KeyCacheImpl<u8> + Debug) {
FLASH_RANGE,
&mut cache,
&mut buf.0,
key,
&key,
)) {
Ok(Some(_)) => {
#[cfg(fuzzing_repro)]
Expand Down Expand Up @@ -247,7 +247,7 @@ fn fuzz(ops: Input, mut cache: impl KeyCacheImpl<u8> + Debug) {
FLASH_RANGE,
&mut cache,
&mut buf.0,
key,
&key,
)) {
Ok(Some(_)) => {
#[cfg(fuzzing_repro)]
Expand Down
20 changes: 11 additions & 9 deletions src/cache/key_pointers.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use core::{fmt::Debug, num::NonZeroU32};

pub(crate) trait KeyPointersCache<KEY: Eq> {
use crate::map::Key;

pub(crate) trait KeyPointersCache<KEY: Key> {
fn key_location(&self, key: &KEY) -> Option<u32>;

fn notice_key_location(&mut self, key: KEY, item_address: u32);
fn notice_key_location(&mut self, key: &KEY, item_address: u32);
fn notice_key_erased(&mut self, key: &KEY);

fn invalidate_cache_state(&mut self);
Expand Down Expand Up @@ -45,20 +47,20 @@ impl<KEY: Eq, const KEYS: usize> CachedKeyPointers<KEY, KEYS> {
}
}

impl<KEY: Eq, const KEYS: usize> KeyPointersCache<KEY> for CachedKeyPointers<KEY, KEYS> {
impl<KEY: Key, const KEYS: usize> KeyPointersCache<KEY> for CachedKeyPointers<KEY, KEYS> {
fn key_location(&self, key: &KEY) -> Option<u32> {
self.key_index(key)
.map(|index| self.key_pointers[index].as_ref().unwrap().1.get())
}

fn notice_key_location(&mut self, key: KEY, item_address: u32) {
match self.key_index(&key) {
fn notice_key_location(&mut self, key: &KEY, item_address: u32) {
match self.key_index(key) {
Some(existing_index) => {
self.key_pointers[existing_index] =
Some((key, NonZeroU32::new(item_address).unwrap()));
Some((key.clone(), NonZeroU32::new(item_address).unwrap()));
move_to_front(&mut self.key_pointers, existing_index);
}
None => self.insert_front((key, NonZeroU32::new(item_address).unwrap())),
None => self.insert_front((key.clone(), NonZeroU32::new(item_address).unwrap())),
}
}

Expand All @@ -77,12 +79,12 @@ impl<KEY: Eq, const KEYS: usize> KeyPointersCache<KEY> for CachedKeyPointers<KEY
#[derive(Debug)]
pub(crate) struct UncachedKeyPointers;

impl<KEY: Eq> KeyPointersCache<KEY> for UncachedKeyPointers {
impl<KEY: Key> KeyPointersCache<KEY> for UncachedKeyPointers {
fn key_location(&self, _key: &KEY) -> Option<u32> {
None
}

fn notice_key_location(&mut self, _key: KEY, _item_address: u32) {}
fn notice_key_location(&mut self, _key: &KEY, _item_address: u32) {}

fn notice_key_erased(&mut self, _key: &KEY) {}

Expand Down
38 changes: 19 additions & 19 deletions src/cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use core::{fmt::Debug, ops::Range};

use embedded_storage_async::nor_flash::NorFlash;

use crate::{item::ItemHeader, PageState};
use crate::{item::ItemHeader, map::Key, PageState};

use self::{
key_pointers::{CachedKeyPointers, KeyPointersCache, UncachedKeyPointers},
Expand All @@ -26,7 +26,7 @@ pub trait CacheImpl: PrivateCacheImpl {}

/// Trait implemented by all cache types that know about keys
#[allow(private_bounds)]
pub trait KeyCacheImpl<KEY: Eq>: CacheImpl + PrivateKeyCacheImpl<KEY> {}
pub trait KeyCacheImpl<KEY: Key>: CacheImpl + PrivateKeyCacheImpl<KEY> {}

pub(crate) trait Invalidate {
fn invalidate_cache_state(&mut self);
Expand Down Expand Up @@ -133,7 +133,7 @@ impl<T: PrivateCacheImpl> PrivateCacheImpl for &mut T {
}
}

pub(crate) trait PrivateKeyCacheImpl<KEY: Eq>: PrivateCacheImpl {
pub(crate) trait PrivateKeyCacheImpl<KEY: Key>: PrivateCacheImpl {
type KPC: KeyPointersCache<KEY>;

fn key_pointers(&mut self) -> &mut Self::KPC;
Expand All @@ -142,7 +142,7 @@ pub(crate) trait PrivateKeyCacheImpl<KEY: Eq>: PrivateCacheImpl {
self.key_pointers().key_location(key)
}

fn notice_key_location(&mut self, key: KEY, item_address: u32, dirty: bool) {
fn notice_key_location(&mut self, key: &KEY, item_address: u32, dirty: bool) {
if dirty {
self.mark_dirty();
}
Expand All @@ -155,7 +155,7 @@ pub(crate) trait PrivateKeyCacheImpl<KEY: Eq>: PrivateCacheImpl {
}
}

impl<KEY: Eq, T: PrivateKeyCacheImpl<KEY>> PrivateKeyCacheImpl<KEY> for &mut T {
impl<KEY: Key, T: PrivateKeyCacheImpl<KEY>> PrivateKeyCacheImpl<KEY> for &mut T {
type KPC = T::KPC;

fn key_pointers(&mut self) -> &mut Self::KPC {
Expand Down Expand Up @@ -240,13 +240,13 @@ impl PrivateCacheImpl for NoCache {
}

impl CacheImpl for NoCache {}
impl<KEY: Eq> KeyCacheImpl<KEY> for NoCache {}
impl<KEY: Key> KeyCacheImpl<KEY> for NoCache {}

impl Invalidate for NoCache {
fn invalidate_cache_state(&mut self) {}
}

impl<KEY: Eq> PrivateKeyCacheImpl<KEY> for NoCache {
impl<KEY: Key> PrivateKeyCacheImpl<KEY> for NoCache {
type KPC = UncachedKeyPointers;

fn key_pointers(&mut self) -> &mut Self::KPC {
Expand Down Expand Up @@ -309,7 +309,7 @@ impl<const PAGE_COUNT: usize> PrivateCacheImpl for PageStateCache<PAGE_COUNT> {
}

impl<const PAGE_COUNT: usize> CacheImpl for PageStateCache<PAGE_COUNT> {}
impl<KEY: Eq, const PAGE_COUNT: usize> KeyCacheImpl<KEY> for PageStateCache<PAGE_COUNT> {}
impl<KEY: Key, const PAGE_COUNT: usize> KeyCacheImpl<KEY> for PageStateCache<PAGE_COUNT> {}

impl<const PAGE_COUNT: usize> Invalidate for PageStateCache<PAGE_COUNT> {
fn invalidate_cache_state(&mut self) {
Expand All @@ -319,7 +319,7 @@ impl<const PAGE_COUNT: usize> Invalidate for PageStateCache<PAGE_COUNT> {
}
}

impl<KEY: Eq, const PAGE_COUNT: usize> PrivateKeyCacheImpl<KEY> for PageStateCache<PAGE_COUNT> {
impl<KEY: Key, const PAGE_COUNT: usize> PrivateKeyCacheImpl<KEY> for PageStateCache<PAGE_COUNT> {
type KPC = UncachedKeyPointers;

fn key_pointers(&mut self) -> &mut Self::KPC {
Expand Down Expand Up @@ -382,7 +382,7 @@ impl<const PAGE_COUNT: usize> PrivateCacheImpl for PagePointerCache<PAGE_COUNT>
}

impl<const PAGE_COUNT: usize> CacheImpl for PagePointerCache<PAGE_COUNT> {}
impl<KEY: Eq, const PAGE_COUNT: usize> KeyCacheImpl<KEY> for PagePointerCache<PAGE_COUNT> {}
impl<KEY: Key, const PAGE_COUNT: usize> KeyCacheImpl<KEY> for PagePointerCache<PAGE_COUNT> {}

impl<const PAGE_COUNT: usize> Invalidate for PagePointerCache<PAGE_COUNT> {
fn invalidate_cache_state(&mut self) {
Expand All @@ -392,7 +392,7 @@ impl<const PAGE_COUNT: usize> Invalidate for PagePointerCache<PAGE_COUNT> {
}
}

impl<KEY: Eq, const PAGE_COUNT: usize> PrivateKeyCacheImpl<KEY> for PagePointerCache<PAGE_COUNT> {
impl<KEY: Key, const PAGE_COUNT: usize> PrivateKeyCacheImpl<KEY> for PagePointerCache<PAGE_COUNT> {
type KPC = UncachedKeyPointers;

fn key_pointers(&mut self) -> &mut Self::KPC {
Expand All @@ -417,14 +417,14 @@ impl<KEY: Eq, const PAGE_COUNT: usize> PrivateKeyCacheImpl<KEY> for PagePointerC
/// the chance of a cache hit.
/// The keys are cached in a fifo and any time its location is updated in cache it's added to the front.
#[derive(Debug)]
pub struct KeyPointerCache<const PAGE_COUNT: usize, KEY: Eq, const KEYS: usize> {
pub struct KeyPointerCache<const PAGE_COUNT: usize, KEY: Key, const KEYS: usize> {
dirt_tracker: DirtTracker,
page_states: CachedPageStates<PAGE_COUNT>,
page_pointers: CachedPagePointers<PAGE_COUNT>,
key_pointers: CachedKeyPointers<KEY, KEYS>,
}

impl<const PAGE_COUNT: usize, KEY: Eq, const KEYS: usize> KeyPointerCache<PAGE_COUNT, KEY, KEYS> {
impl<const PAGE_COUNT: usize, KEY: Key, const KEYS: usize> KeyPointerCache<PAGE_COUNT, KEY, KEYS> {
/// Construct a new instance
pub const fn new() -> Self {
Self {
Expand All @@ -436,15 +436,15 @@ impl<const PAGE_COUNT: usize, KEY: Eq, const KEYS: usize> KeyPointerCache<PAGE_C
}
}

impl<const PAGE_COUNT: usize, KEY: Eq, const KEYS: usize> Default
impl<const PAGE_COUNT: usize, KEY: Key, const KEYS: usize> Default
for KeyPointerCache<PAGE_COUNT, KEY, KEYS>
{
fn default() -> Self {
Self::new()
}
}

impl<const PAGE_COUNT: usize, KEY: Eq, const KEYS: usize> PrivateCacheImpl
impl<const PAGE_COUNT: usize, KEY: Key, const KEYS: usize> PrivateCacheImpl
for KeyPointerCache<PAGE_COUNT, KEY, KEYS>
{
type PSC = CachedPageStates<PAGE_COUNT>;
Expand All @@ -463,16 +463,16 @@ impl<const PAGE_COUNT: usize, KEY: Eq, const KEYS: usize> PrivateCacheImpl
}
}

impl<const PAGE_COUNT: usize, KEY: Eq, const KEYS: usize> CacheImpl
impl<const PAGE_COUNT: usize, KEY: Key, const KEYS: usize> CacheImpl
for KeyPointerCache<PAGE_COUNT, KEY, KEYS>
{
}
impl<const PAGE_COUNT: usize, KEY: Eq, const KEYS: usize> KeyCacheImpl<KEY>
impl<const PAGE_COUNT: usize, KEY: Key, const KEYS: usize> KeyCacheImpl<KEY>
for KeyPointerCache<PAGE_COUNT, KEY, KEYS>
{
}

impl<const PAGE_COUNT: usize, KEY: Eq, const KEYS: usize> Invalidate
impl<const PAGE_COUNT: usize, KEY: Key, const KEYS: usize> Invalidate
for KeyPointerCache<PAGE_COUNT, KEY, KEYS>
{
fn invalidate_cache_state(&mut self) {
Expand All @@ -483,7 +483,7 @@ impl<const PAGE_COUNT: usize, KEY: Eq, const KEYS: usize> Invalidate
}
}

impl<const PAGE_COUNT: usize, KEY: Eq, const KEYS: usize> PrivateKeyCacheImpl<KEY>
impl<const PAGE_COUNT: usize, KEY: Key, const KEYS: usize> PrivateKeyCacheImpl<KEY>
for KeyPointerCache<PAGE_COUNT, KEY, KEYS>
{
type KPC = CachedKeyPointers<KEY, KEYS>;
Expand Down
4 changes: 2 additions & 2 deletions src/cache/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ mod map_tests {
FLASH_RANGE,
cache,
&mut data_buffer,
i as u16,
&(i as u16),
&vec![i as u8; LENGHT_PER_KEY[i]].as_slice(),
)
.await
Expand All @@ -231,7 +231,7 @@ mod map_tests {
FLASH_RANGE,
cache,
&mut data_buffer,
i as u16,
&(i as u16),
)
.await
.unwrap()
Expand Down
Loading

0 comments on commit 9912929

Please sign in to comment.