Skip to content

Commit 6dfe57b

Browse files
authored
Merge pull request #88 from tweedegolf/single-page-queue
Enable queue use on a single page
2 parents 66fb5c3 + 0d1d36b commit 6dfe57b

File tree

4 files changed

+57
-8
lines changed

4 files changed

+57
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
- Added `Key` implementation for the unit type `()` for easy storage of a single value
88
- *Breaking:* Changed API for map `fetch_all_items` such that the `Key` is captured in `MapItemIter`.
9+
- Fixed some logic so queue can be used on a single page. (It's still recommended to use at least 2 pages for both the queue and the map)
910

1011
## 4.0.3 18-06-25
1112

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,10 @@ where
434434
match self {
435435
Error::Storage { value, .. } => write!(f, "Storage error: {value}"),
436436
Error::FullStorage => write!(f, "Storage is full"),
437+
#[cfg(not(feature = "_test"))]
437438
Error::Corrupted { .. } => write!(f, "Storage is corrupted"),
439+
#[cfg(feature = "_test")]
440+
Error::Corrupted { backtrace } => write!(f, "Storage is corrupted\n{backtrace}"),
438441
Error::BufferTooBig => write!(f, "A provided buffer was to big to be used"),
439442
Error::BufferTooSmall(needed) => write!(
440443
f,

src/mock_flash.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use core::ops::{Add, AddAssign, Range};
1+
use core::{
2+
fmt::Display,
3+
ops::{Add, AddAssign, Range},
4+
};
25
use embedded_storage_async::nor_flash::{
36
ErrorType, MultiwriteNorFlash, NorFlash, NorFlashError, NorFlashErrorKind, ReadNorFlash,
47
};
@@ -374,6 +377,12 @@ pub enum MockFlashError {
374377
EarlyShutoff(u32, Operation),
375378
}
376379

380+
impl Display for MockFlashError {
381+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
382+
write!(f, "{self:?}")
383+
}
384+
}
385+
377386
impl NorFlashError for MockFlashError {
378387
fn kind(&self) -> NorFlashErrorKind {
379388
match self {

src/queue.rs

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -140,34 +140,45 @@ async fn push_inner<S: NorFlash>(
140140
if next_address.is_none() {
141141
// No cap left on this page, move to the next page
142142
let next_page = next_page::<S>(flash_range.clone(), current_page);
143-
match get_page_state(flash, flash_range.clone(), cache, next_page).await? {
144-
PageState::Open => {
143+
let next_page_state = get_page_state(flash, flash_range.clone(), cache, next_page).await?;
144+
let single_page = next_page == current_page;
145+
146+
match (next_page_state, single_page) {
147+
(PageState::Open, _) => {
145148
close_page(flash, flash_range.clone(), cache, current_page).await?;
146149
partial_close_page(flash, flash_range.clone(), cache, next_page).await?;
147150
next_address = Some(
148151
calculate_page_address::<S>(flash_range.clone(), next_page)
149152
+ S::WORD_SIZE as u32,
150153
);
151154
}
152-
state @ PageState::Closed => {
155+
(PageState::Closed, _) | (PageState::PartialOpen, true) => {
153156
let next_page_data_start_address =
154157
calculate_page_address::<S>(flash_range.clone(), next_page)
155158
+ S::WORD_SIZE as u32;
156159

157160
if !allow_overwrite_old_data
158-
&& !is_page_empty(flash, flash_range.clone(), cache, next_page, Some(state))
159-
.await?
161+
&& !is_page_empty(
162+
flash,
163+
flash_range.clone(),
164+
cache,
165+
next_page,
166+
Some(next_page_state),
167+
)
168+
.await?
160169
{
161170
cache.unmark_dirty();
162171
return Err(Error::FullStorage);
163172
}
164173

165174
open_page(flash, flash_range.clone(), cache, next_page).await?;
166-
close_page(flash, flash_range.clone(), cache, current_page).await?;
175+
if !single_page {
176+
close_page(flash, flash_range.clone(), cache, current_page).await?;
177+
}
167178
partial_close_page(flash, flash_range.clone(), cache, next_page).await?;
168179
next_address = Some(next_page_data_start_address);
169180
}
170-
PageState::PartialOpen => {
181+
(PageState::PartialOpen, false) => {
171182
// This should never happen
172183
return Err(Error::Corrupted {
173184
#[cfg(feature = "_test")]
@@ -1525,4 +1536,29 @@ mod tests {
15251536
Err(Error::ItemTooBig)
15261537
);
15271538
}
1539+
1540+
#[test]
1541+
async fn push_on_single_page() {
1542+
let mut flash =
1543+
mock_flash::MockFlashBase::<1, 4, 256>::new(WriteCountCheck::Twice, None, true);
1544+
const FLASH_RANGE: Range<u32> = 0x000..0x400;
1545+
1546+
for _ in 0..100 {
1547+
match push(
1548+
&mut flash,
1549+
FLASH_RANGE,
1550+
&mut cache::NoCache::new(),
1551+
&[0, 1, 2, 3, 4],
1552+
true,
1553+
)
1554+
.await
1555+
{
1556+
Ok(_) => {}
1557+
Err(e) => {
1558+
println!("{}", flash.print_items().await);
1559+
panic!("{e}");
1560+
}
1561+
}
1562+
}
1563+
}
15281564
}

0 commit comments

Comments
 (0)