1use alloc::borrow::Cow;
18use alloc::boxed::Box;
19use alloc::vec::Vec;
20use core::borrow::Borrow;
21use core::cmp::{Ordering, max, min};
22use core::convert::TryFrom;
23#[cfg(feature = "std")]
24use std::collections::HashSet;
25
26use wasefire_error::{Code, Error, Space};
27
28use crate::format::{
29 CompactInfo, Format, Header, InitInfo, InternalEntry, Padding, ParsedWord, Position, Word,
30 WordState, is_erased,
31};
32#[cfg(feature = "std")]
33use crate::{BufferStorage, StoreOperation};
34use crate::{Nat, Storage, StorageIndex, usize_to_nat};
35
36pub const INVALID_ARGUMENT: Error =
40 Error::new_const(Space::User as u8, Code::InvalidArgument as u16);
41
42pub const NO_CAPACITY: Error = Error::new_const(Space::World as u8, Code::NotEnough as u16);
46
47pub const NO_LIFETIME: Error = Error::new_const(Space::World as u8, Code::OutOfBounds as u16);
52
53pub const INVALID_STORAGE: Error = Error::new_const(Space::World as u8, Code::InvalidState as u16);
58
59#[derive(Copy, Clone, Debug, PartialEq, Eq)]
68pub struct StoreRatio {
69 pub(crate) used: Nat,
71
72 pub(crate) total: Nat,
74}
75
76impl StoreRatio {
77 pub fn used(self) -> usize {
79 self.used as usize
80 }
81
82 pub fn total(self) -> usize {
84 self.total as usize
85 }
86
87 pub fn remaining(self) -> usize {
89 (self.total - self.used) as usize
90 }
91}
92
93#[derive(Clone, Debug)]
98pub struct StoreHandle {
99 key: Nat,
101
102 pos: Position,
104
105 len: Nat,
107}
108
109impl StoreHandle {
110 pub fn get_key(&self) -> usize {
112 self.key as usize
113 }
114
115 pub fn get_length<S: Storage>(&self, store: &Store<S>) -> Result<usize, Error> {
121 store.get_length(self)
122 }
123
124 pub fn get_value<S: Storage>(&self, store: &Store<S>) -> Result<Vec<u8>, Error> {
130 store.get_value(self)
131 }
132}
133
134#[derive(Clone, Debug)]
136pub enum StoreUpdate<ByteSlice: Borrow<[u8]>> {
137 Insert { key: usize, value: ByteSlice },
139
140 Remove { key: usize },
142}
143
144impl<ByteSlice: Borrow<[u8]>> StoreUpdate<ByteSlice> {
145 pub fn key(&self) -> usize {
147 match *self {
148 StoreUpdate::Insert { key, .. } => key,
149 StoreUpdate::Remove { key } => key,
150 }
151 }
152
153 pub fn value(&self) -> Option<&[u8]> {
155 match self {
156 StoreUpdate::Insert { value, .. } => Some(value.borrow()),
157 StoreUpdate::Remove { .. } => None,
158 }
159 }
160}
161
162pub type StoreIter<'a> = Box<dyn Iterator<Item = Result<StoreHandle, Error>> + 'a>;
163
164#[derive(Clone)]
166pub struct Store<S: Storage> {
167 storage: S,
169
170 format: Format,
172
173 head: Option<Position>,
175
176 entries: Option<Vec<u16>>,
180}
181
182impl<S: Storage> Store<S> {
183 pub fn new(storage: S) -> Result<Store<S>, (Error, S)> {
194 let format = match Format::new(&storage) {
195 None => return Err((INVALID_ARGUMENT, storage)),
196 Some(x) => x,
197 };
198 let mut store = Store { storage, format, head: None, entries: None };
199 if let Err(error) = store.recover() {
200 return Err((error, store.storage));
201 }
202 Ok(store)
203 }
204
205 pub fn extract_storage(self) -> S {
207 self.storage
208 }
209
210 pub fn iter(&self) -> Result<StoreIter<'_>, Error> {
212 let head = self.head.ok_or(INVALID_STORAGE)?;
213 Ok(Box::new(self.entries.as_ref().ok_or(INVALID_STORAGE)?.iter().map(move |&offset| {
214 let pos = head + offset as Nat;
215 match self.parse_entry(&mut pos.clone())? {
216 ParsedEntry::User(Header { key, length: len, .. }) => {
217 Ok(StoreHandle { key, pos, len })
218 }
219 _ => Err(INVALID_STORAGE),
220 }
221 })))
222 }
223
224 pub fn capacity(&self) -> Result<StoreRatio, Error> {
228 let total = self.format.total_capacity();
229 let mut used = 0;
230 for handle in self.iter()? {
231 let handle = handle?;
232 used += 1 + self.format.bytes_to_words(handle.len);
233 }
234 Ok(StoreRatio { used, total })
235 }
236
237 pub fn lifetime(&self) -> Result<StoreRatio, Error> {
243 let total = self.format.total_lifetime().get();
244 let used = self.tail()?.get();
245 Ok(StoreRatio { used, total })
246 }
247
248 pub fn transaction<ByteSlice: Borrow<[u8]>>(
258 &mut self, updates: &[StoreUpdate<ByteSlice>],
259 ) -> Result<(), Error> {
260 let count = usize_to_nat(updates.len());
261 if count == 0 {
262 return Ok(());
263 }
264 if count == 1 {
265 match updates[0] {
266 StoreUpdate::Insert { key, ref value } => return self.insert(key, value.borrow()),
267 StoreUpdate::Remove { key } => return self.remove(key),
268 }
269 }
270 let sorted_keys = match self.format.transaction_valid(updates) {
272 None => return Err(INVALID_ARGUMENT),
273 Some(x) => x,
274 };
275 self.reserve(self.format.transaction_capacity(updates))?;
277 let marker = self.tail()?;
279 let entry = self.format.build_internal(InternalEntry::Marker { count })?;
280 self.write_slice(marker, &entry)?;
281 self.init_page(marker, marker)?;
282 let mut tail = marker + 1;
284 for update in updates {
285 let length = match *update {
286 StoreUpdate::Insert { key, ref value } => {
287 let entry = self.format.build_user(usize_to_nat(key), value.borrow())?;
288 let word_size = self.format.word_size();
289 let footer = usize_to_nat(entry.len()) / word_size - 1;
290 self.write_slice(tail, &entry[.. (footer * word_size) as usize])?;
291 self.write_slice(tail + footer, &entry[(footer * word_size) as usize ..])?;
292 footer
293 }
294 StoreUpdate::Remove { key } => {
295 let key = usize_to_nat(key);
296 let remove = self.format.build_internal(InternalEntry::Remove { key })?;
297 self.write_slice(tail, &remove)?;
298 0
299 }
300 };
301 self.init_page(tail, tail + length)?;
302 tail += 1 + length;
303 }
304 self.transaction_apply(&sorted_keys, marker)
306 }
307
308 pub fn clear(&mut self, min_key: usize) -> Result<(), Error> {
312 let min_key = usize_to_nat(min_key);
313 if min_key > self.format.max_key() {
314 return Err(INVALID_ARGUMENT);
315 }
316 let clear = self.format.build_internal(InternalEntry::Clear { min_key })?;
317 while self.immediate_capacity()? < 1 {
320 self.compact()?;
321 }
322 let tail = self.tail()?;
323 self.write_slice(tail, &clear)?;
324 self.clear_delete(tail)
325 }
326
327 pub fn prepare(&mut self, length: usize) -> Result<(), Error> {
332 if self.capacity()?.remaining() < length {
333 return Err(NO_CAPACITY);
334 }
335 if self.immediate_capacity()? < usize_to_nat(length) {
336 self.compact()?;
337 }
338 Ok(())
339 }
340
341 pub fn recover(&mut self) -> Result<(), Error> {
345 self.recover_initialize()?;
346 self.recover_erase()?;
347 self.recover_compaction()?;
348 self.recover_operation()?;
349 Ok(())
350 }
351
352 pub fn find(&self, key: usize) -> Result<Option<Vec<u8>>, Error> {
354 Ok(match self.find_handle(key)? {
355 None => None,
356 Some(handle) => Some(self.get_value(&handle)?),
357 })
358 }
359
360 pub fn find_handle(&self, key: usize) -> Result<Option<StoreHandle>, Error> {
362 let key = usize_to_nat(key);
363 for handle in self.iter()? {
364 let handle = handle?;
365 if handle.key == key {
366 return Ok(Some(handle));
367 }
368 }
369 Ok(None)
370 }
371
372 pub fn insert(&mut self, key: usize, value: &[u8]) -> Result<(), Error> {
376 let key = usize_to_nat(key);
378 let value_len = usize_to_nat(value.len());
379 if key > self.format.max_key() || value_len > self.format.max_value_len() {
380 return Err(INVALID_ARGUMENT);
381 }
382 let entry = self.format.build_user(key, value)?;
383 let entry_len = usize_to_nat(entry.len());
384 self.reserve(entry_len / self.format.word_size())?;
385 let tail = self.tail()?;
386 let word_size = self.format.word_size();
387 let footer = entry_len / word_size - 1;
388 self.write_slice(tail, &entry[.. (footer * word_size) as usize])?;
389 self.write_slice(tail + footer, &entry[(footer * word_size) as usize ..])?;
390 self.push_entry(tail)?;
391 self.insert_init(tail, footer, key)
392 }
393
394 pub fn remove(&mut self, key: usize) -> Result<(), Error> {
398 let key = usize_to_nat(key);
399 if key > self.format.max_key() {
400 return Err(INVALID_ARGUMENT);
401 }
402 self.delete_keys(&[key], self.tail()?)
403 }
404
405 pub fn remove_handle(&mut self, handle: &StoreHandle) -> Result<(), Error> {
407 self.check_handle(handle)?;
408 self.delete_pos(handle.pos, self.format.bytes_to_words(handle.len))?;
409 self.remove_entry(handle.pos)
410 }
411
412 pub fn max_value_length(&self) -> usize {
414 self.format.max_value_len() as usize
415 }
416
417 fn get_length(&self, handle: &StoreHandle) -> Result<usize, Error> {
419 self.check_handle(handle)?;
420 let mut pos = handle.pos;
421 match self.parse_entry(&mut pos)? {
422 ParsedEntry::User(header) => Ok(header.length as usize),
423 ParsedEntry::Padding => Err(INVALID_ARGUMENT),
424 _ => Err(INVALID_STORAGE),
425 }
426 }
427
428 fn get_value(&self, handle: &StoreHandle) -> Result<Vec<u8>, Error> {
430 self.check_handle(handle)?;
431 let mut pos = handle.pos;
432 match self.parse_entry(&mut pos)? {
433 ParsedEntry::User(header) => {
434 let mut result = self.read_slice(handle.pos + 1, header.length);
435 if header.flipped {
436 let last_byte = result.len() - 1;
437 result[last_byte] = 0xff;
438 }
439 Ok(result)
440 }
441 ParsedEntry::Padding => Err(INVALID_ARGUMENT),
442 _ => Err(INVALID_STORAGE),
443 }
444 }
445
446 fn recover_initialize(&mut self) -> Result<(), Error> {
448 let word_size = self.format.word_size();
449 for page in 0 .. self.format.num_pages() {
450 let content = self.read_page(page);
451 let (init, rest) = content.split_at(word_size as usize);
452 if (page > 0 && !is_erased(init)) || !is_erased(rest) {
453 return Ok(());
454 }
455 }
456 let index = self.format.index_init(0);
457 let init_info = self.format.build_init(InitInfo { cycle: 0, prefix: 0 })?;
458 self.storage_write_slice(index, &init_info)
459 }
460
461 fn recover_erase(&mut self) -> Result<(), Error> {
463 let mut pos = self.get_extremum_page_head(Ordering::Greater)?;
464 let end = pos.next_page(&self.format);
465 while pos < end {
466 let entry_pos = pos;
467 match self.parse_entry(&mut pos)? {
468 ParsedEntry::Internal(InternalEntry::Erase { .. }) => {
469 return self.compact_erase(entry_pos);
470 }
471 ParsedEntry::Padding | ParsedEntry::User(_) => (),
472 _ => break,
473 }
474 }
475 Ok(())
476 }
477
478 fn recover_compaction(&mut self) -> Result<(), Error> {
480 let head = self.get_extremum_page_head(Ordering::Less)?;
481 self.head = Some(head);
482 let head_page = head.page(&self.format);
483 match self.parse_compact(head_page)? {
484 WordState::Erased => Ok(()),
485 WordState::Partial => self.compact(),
486 WordState::Valid(_) => self.compact_copy(),
487 }
488 }
489
490 fn recover_operation(&mut self) -> Result<(), Error> {
492 self.entries = Some(Vec::new());
493 let mut pos = self.head.ok_or(INVALID_STORAGE)?;
494 let mut prev_pos = pos;
495 let end = pos + self.format.window_size();
496 while pos < end {
497 let entry_pos = pos;
498 match self.parse_entry(&mut pos)? {
499 ParsedEntry::Tail => break,
500 ParsedEntry::User(_) => self.push_entry(entry_pos)?,
501 ParsedEntry::Padding => {
502 self.wipe_span(entry_pos + 1, pos - entry_pos - 1)?;
503 }
504 ParsedEntry::Internal(InternalEntry::Erase { .. }) => {
505 return Err(INVALID_STORAGE);
506 }
507 ParsedEntry::Internal(InternalEntry::Clear { .. }) => {
508 return self.clear_delete(entry_pos);
509 }
510 ParsedEntry::Internal(InternalEntry::Marker { .. }) => {
511 return self.recover_transaction(entry_pos, end);
512 }
513 ParsedEntry::Internal(InternalEntry::Remove { .. }) => {
514 self.set_padding(entry_pos)?;
515 }
516 ParsedEntry::Partial => {
517 return self.recover_wipe_partial(entry_pos, pos - entry_pos - 1);
518 }
519 ParsedEntry::PartialUser => {
520 return self.recover_delete_user(entry_pos, pos - entry_pos - 1);
521 }
522 }
523 prev_pos = entry_pos;
524 }
525 pos = prev_pos;
526 if let ParsedEntry::User(header) = self.parse_entry(&mut pos)? {
527 self.insert_init(prev_pos, pos - prev_pos - 1, header.key)?;
528 }
529 Ok(())
530 }
531
532 fn recover_transaction(&mut self, marker: Position, end: Position) -> Result<(), Error> {
534 let mut pos = marker;
535 let count = match self.parse_entry(&mut pos)? {
536 ParsedEntry::Internal(InternalEntry::Marker { count }) => count,
537 _ => return Err(INVALID_STORAGE),
538 };
539 let sorted_keys = self.recover_transaction_keys(count, pos, end)?;
540 match usize_to_nat(sorted_keys.len()).cmp(&count) {
541 Ordering::Less => (),
542 Ordering::Equal => return self.transaction_apply(&sorted_keys, marker),
543 Ordering::Greater => return Err(INVALID_STORAGE),
544 }
545 while pos < end {
546 let entry_pos = pos;
547 match self.parse_entry(&mut pos)? {
548 ParsedEntry::Tail => break,
549 ParsedEntry::Padding => (),
550 ParsedEntry::User(_) => {
551 self.delete_pos(entry_pos, pos - entry_pos - 1)?;
552 }
553 ParsedEntry::Internal(InternalEntry::Remove { .. }) => {
554 self.set_padding(entry_pos)?;
555 }
556 ParsedEntry::Partial => {
557 self.recover_wipe_partial(entry_pos, pos - entry_pos - 1)?;
558 break;
559 }
560 ParsedEntry::PartialUser => {
561 self.recover_delete_user(entry_pos, pos - entry_pos - 1)?;
562 break;
563 }
564 ParsedEntry::Internal(InternalEntry::Erase { .. })
565 | ParsedEntry::Internal(InternalEntry::Clear { .. })
566 | ParsedEntry::Internal(InternalEntry::Marker { .. }) => {
567 return Err(INVALID_STORAGE);
568 }
569 }
570 }
571 self.init_page(marker, marker)?;
572 self.set_padding(marker)?;
573 Ok(())
574 }
575
576 fn recover_transaction_keys(
580 &mut self, count: Nat, mut pos: Position, end: Position,
581 ) -> Result<Vec<Nat>, Error> {
582 let mut sorted_keys = Vec::with_capacity(count as usize);
583 let mut prev_pos = pos;
584 while pos < end {
585 let entry_pos = pos;
586 let key = match self.parse_entry(&mut pos)? {
587 ParsedEntry::Tail
588 | ParsedEntry::Padding
589 | ParsedEntry::Partial
590 | ParsedEntry::PartialUser => break,
591 ParsedEntry::User(header) => header.key,
592 ParsedEntry::Internal(InternalEntry::Remove { key }) => key,
593 ParsedEntry::Internal(_) => return Err(INVALID_STORAGE),
594 };
595 match sorted_keys.binary_search(&key) {
596 Ok(_) => return Err(INVALID_STORAGE),
597 Err(pos) => sorted_keys.insert(pos, key),
598 }
599 prev_pos = entry_pos;
600 }
601 pos = prev_pos;
602 match self.parse_entry(&mut pos)? {
603 ParsedEntry::User(_) | ParsedEntry::Internal(InternalEntry::Remove { .. }) => {
604 let length = pos - prev_pos - 1;
605 self.init_page(prev_pos, prev_pos + length)?;
606 }
607 _ => (),
608 }
609 Ok(sorted_keys)
610 }
611
612 fn recover_wipe_partial(&mut self, pos: Position, length: Nat) -> Result<(), Error> {
614 self.wipe_span(pos + 1, length)?;
615 self.init_page(pos, pos + length)?;
616 self.set_padding(pos)?;
617 Ok(())
618 }
619
620 fn recover_delete_user(&mut self, pos: Position, length: Nat) -> Result<(), Error> {
622 self.init_page(pos, pos + length)?;
623 self.delete_pos(pos, length)
624 }
625
626 fn check_handle(&self, handle: &StoreHandle) -> Result<(), Error> {
630 if handle.pos < self.head.ok_or(INVALID_STORAGE)? { Err(INVALID_ARGUMENT) } else { Ok(()) }
631 }
632
633 fn reserve(&mut self, length: Nat) -> Result<(), Error> {
638 if self.capacity()?.remaining() < length as usize {
639 return Err(NO_CAPACITY);
640 }
641 while self.immediate_capacity()? < length {
642 self.compact()?;
643 }
644 Ok(())
645 }
646
647 fn insert_init(&mut self, pos: Position, length: Nat, key: Nat) -> Result<(), Error> {
649 self.init_page(pos, pos + length)?;
650 self.delete_keys(&[key], pos)?;
651 Ok(())
652 }
653
654 fn compact(&mut self) -> Result<(), Error> {
656 let head = self.head.ok_or(INVALID_STORAGE)?;
657 if head.cycle(&self.format) >= self.format.max_page_erases() {
658 return Err(NO_LIFETIME);
659 }
660 let tail = max(self.tail()?, head.next_page(&self.format));
661 let index = self.format.index_compact(head.page(&self.format));
662 let compact_info = self.format.build_compact(CompactInfo { tail: tail - head })?;
663 self.storage_write_slice(index, &compact_info)?;
664 self.compact_copy()
665 }
666
667 fn compact_copy(&mut self) -> Result<(), Error> {
669 let mut head = self.head.ok_or(INVALID_STORAGE)?;
670 let page = head.page(&self.format);
671 let end = head.next_page(&self.format);
672 let mut tail = match self.parse_compact(page)? {
673 WordState::Valid(CompactInfo { tail }) => head + tail,
674 _ => return Err(INVALID_STORAGE),
675 };
676 if tail < end {
677 return Err(INVALID_STORAGE);
678 }
679 while head < end {
680 let pos = head;
681 match self.parse_entry(&mut head)? {
682 ParsedEntry::Tail => break,
683 ParsedEntry::Partial if head > end => break,
686 ParsedEntry::User(_) => (),
687 ParsedEntry::Padding => continue,
688 _ => return Err(INVALID_STORAGE),
689 };
690 let length = head - pos;
691 let entry = self.read_slice(pos, length * self.format.word_size());
693 self.remove_entry(pos)?;
694 self.write_slice(tail, &entry)?;
695 self.push_entry(tail)?;
696 self.init_page(tail, tail + (length - 1))?;
697 tail += length;
698 }
699 let erase = self.format.build_internal(InternalEntry::Erase { page })?;
700 self.write_slice(tail, &erase)?;
701 self.init_page(tail, tail)?;
702 self.compact_erase(tail)
703 }
704
705 fn compact_erase(&mut self, erase: Position) -> Result<(), Error> {
707 let mut page = match self.parse_entry(&mut erase.clone())? {
709 ParsedEntry::Internal(InternalEntry::Erase { page }) => page,
710 _ => return Err(INVALID_STORAGE),
711 };
712 self.storage_erase_page(page)?;
714 page = (page + 1) % self.format.num_pages();
716 let init = match self.parse_init(page)? {
717 WordState::Valid(x) => x,
718 _ => return Err(INVALID_STORAGE),
719 };
720 let head = self.format.page_head(init, page);
721 if let Some(entries) = &mut self.entries {
722 let head_offset = u16::try_from(head - self.head.ok_or(INVALID_STORAGE)?)
723 .map_err(|_| INVALID_STORAGE)?;
724 for entry in entries {
725 *entry = entry.checked_sub(head_offset).ok_or(INVALID_STORAGE)?;
726 }
727 }
728 self.head = Some(head);
729 let pos = head.page_begin(&self.format);
731 self.wipe_span(pos, head - pos)?;
732 self.set_padding(erase)?;
734 Ok(())
735 }
736
737 fn transaction_apply(&mut self, sorted_keys: &[Nat], marker: Position) -> Result<(), Error> {
739 self.delete_keys(sorted_keys, marker)?;
740 self.set_padding(marker)?;
741 let end = self.head.ok_or(INVALID_STORAGE)? + self.format.window_size();
742 let mut pos = marker + 1;
743 while pos < end {
744 let entry_pos = pos;
745 match self.parse_entry(&mut pos)? {
746 ParsedEntry::Tail => break,
747 ParsedEntry::User(_) => self.push_entry(entry_pos)?,
748 ParsedEntry::Internal(InternalEntry::Remove { .. }) => {
749 self.set_padding(entry_pos)?
750 }
751 _ => return Err(INVALID_STORAGE),
752 }
753 }
754 Ok(())
755 }
756
757 fn clear_delete(&mut self, clear: Position) -> Result<(), Error> {
759 self.init_page(clear, clear)?;
760 let min_key = match self.parse_entry(&mut clear.clone())? {
761 ParsedEntry::Internal(InternalEntry::Clear { min_key }) => min_key,
762 _ => return Err(INVALID_STORAGE),
763 };
764 self.delete_if(clear, |key| key >= min_key)?;
765 self.set_padding(clear)?;
766 Ok(())
767 }
768
769 fn delete_keys(&mut self, sorted_keys: &[Nat], end: Position) -> Result<(), Error> {
771 self.delete_if(end, |key| sorted_keys.binary_search(&key).is_ok())
772 }
773
774 fn delete_if(&mut self, end: Position, delete: impl Fn(Nat) -> bool) -> Result<(), Error> {
776 let head = self.head.ok_or(INVALID_STORAGE)?;
777 let mut entries = self.entries.take().ok_or(INVALID_STORAGE)?;
778 let mut i = 0;
779 while i < entries.len() {
780 let pos = head + entries[i] as Nat;
781 if pos >= end {
782 break;
783 }
784 let header = match self.parse_entry(&mut pos.clone())? {
785 ParsedEntry::User(x) => x,
786 _ => return Err(INVALID_STORAGE),
787 };
788 if delete(header.key) {
789 self.delete_pos(pos, self.format.bytes_to_words(header.length))?;
790 entries.swap_remove(i);
791 } else {
792 i += 1;
793 }
794 }
795 self.entries = Some(entries);
796 Ok(())
797 }
798
799 fn delete_pos(&mut self, pos: Position, length: Nat) -> Result<(), Error> {
801 self.set_deleted(pos)?;
802 self.wipe_span(pos + 1, length)?;
803 Ok(())
804 }
805
806 fn init_page(&mut self, first: Position, last: Position) -> Result<(), Error> {
813 debug_assert!(first <= last);
814 debug_assert!(last - first < self.format.virt_page_size());
815 let new_first = if first.word(&self.format) == 0 {
816 first
817 } else if first.page(&self.format) == last.page(&self.format) {
818 return Ok(());
819 } else {
820 last + 1
821 };
822 let page = new_first.page(&self.format);
823 if let WordState::Valid(_) = self.parse_init(page)? {
824 return Ok(());
825 }
826 let index = self.format.index_init(page);
827 let init_info = self.format.build_init(InitInfo {
828 cycle: new_first.cycle(&self.format),
829 prefix: new_first.word(&self.format),
830 })?;
831 self.storage_write_slice(index, &init_info)?;
832 Ok(())
833 }
834
835 fn set_padding(&mut self, pos: Position) -> Result<(), Error> {
837 let mut word = Word::from_slice(&self.read_word(pos));
838 self.format.set_padding(&mut word)?;
839 self.write_slice(pos, &word.as_slice())?;
840 Ok(())
841 }
842
843 fn set_deleted(&mut self, pos: Position) -> Result<(), Error> {
845 let mut word = Word::from_slice(&self.read_word(pos));
846 self.format.set_deleted(&mut word);
847 self.write_slice(pos, &word.as_slice())?;
848 Ok(())
849 }
850
851 fn wipe_span(&mut self, pos: Position, length: Nat) -> Result<(), Error> {
853 let length = (length * self.format.word_size()) as usize;
854 self.write_slice(pos, &vec![0x00; length])
855 }
856
857 fn get_extremum_page_head(&self, ordering: Ordering) -> Result<Position, Error> {
862 let mut best = None;
863 for page in 0 .. self.format.num_pages() {
864 let init = match self.parse_init(page)? {
865 WordState::Valid(x) => x,
866 _ => continue,
867 };
868 let pos = self.format.page_head(init, page);
869 if best.is_none_or(|x| pos.cmp(&x) == ordering) {
870 best = Some(pos);
871 }
872 }
873 best.ok_or(INVALID_STORAGE)
875 }
876
877 fn immediate_capacity(&self) -> Result<Nat, Error> {
879 let tail = self.tail()?;
880 let end = self.head.ok_or(INVALID_STORAGE)? + self.format.virt_size();
881 Ok(end.get().saturating_sub(tail.get()))
882 }
883
884 #[cfg(feature = "std")]
886 pub(crate) fn head(&self) -> Result<Position, Error> {
887 self.head.ok_or(INVALID_STORAGE)
888 }
889
890 pub(crate) fn tail(&self) -> Result<Position, Error> {
892 let mut pos = self.get_extremum_page_head(Ordering::Greater)?;
893 let end = pos.next_page(&self.format);
894 while pos < end {
895 if let ParsedEntry::Tail = self.parse_entry(&mut pos)? {
896 break;
897 }
898 }
899 Ok(pos)
900 }
901
902 fn push_entry(&mut self, pos: Position) -> Result<(), Error> {
903 let entries = match &mut self.entries {
904 None => return Ok(()),
905 Some(x) => x,
906 };
907 let head = self.head.ok_or(INVALID_STORAGE)?;
908 let offset = u16::try_from(pos - head).map_err(|_| INVALID_STORAGE)?;
909 debug_assert!(!entries.contains(&offset));
910 entries.push(offset);
911 Ok(())
912 }
913
914 fn remove_entry(&mut self, pos: Position) -> Result<(), Error> {
915 let entries = match &mut self.entries {
916 None => return Ok(()),
917 Some(x) => x,
918 };
919 let head = self.head.ok_or(INVALID_STORAGE)?;
920 let offset = u16::try_from(pos - head).map_err(|_| INVALID_STORAGE)?;
921 let i = entries.iter().position(|x| *x == offset).ok_or(INVALID_STORAGE)?;
922 entries.swap_remove(i);
923 Ok(())
924 }
925
926 fn parse_entry(&self, pos: &mut Position) -> Result<ParsedEntry, Error> {
930 let valid = match self.parse_word(*pos)? {
931 WordState::Erased | WordState::Partial => return Ok(self.parse_partial(pos)),
932 WordState::Valid(x) => x,
933 };
934 Ok(match valid {
935 ParsedWord::Padding(Padding { length }) => {
936 *pos += 1 + length;
937 ParsedEntry::Padding
938 }
939 ParsedWord::Header(header) if header.length > self.format.max_value_len() => {
940 self.parse_partial(pos)
941 }
942 ParsedWord::Header(header) => {
943 let length = self.format.bytes_to_words(header.length);
944 let footer = match length {
945 0 => None,
946 _ => Some(self.read_word(*pos + length)),
947 };
948 if header.check(footer.as_deref()) {
949 if header.key > self.format.max_key() {
950 return Err(INVALID_STORAGE);
951 }
952 *pos += 1 + length;
953 ParsedEntry::User(header)
954 } else if footer.is_none_or(|x| is_erased(&x)) {
955 self.parse_partial(pos)
956 } else {
957 *pos += 1 + length;
958 ParsedEntry::PartialUser
959 }
960 }
961 ParsedWord::Internal(internal) => {
962 *pos += 1;
963 ParsedEntry::Internal(internal)
964 }
965 })
966 }
967
968 fn parse_partial(&self, pos: &mut Position) -> ParsedEntry {
973 let mut length = None;
974 for i in 0 .. self.format.max_prefix_len() {
975 if !is_erased(&self.read_word(*pos + i)) {
976 length = Some(i);
977 }
978 }
979 match length {
980 None => ParsedEntry::Tail,
981 Some(length) => {
982 *pos += 1 + length;
983 ParsedEntry::Partial
984 }
985 }
986 }
987
988 fn parse_init(&self, page: Nat) -> Result<WordState<InitInfo>, Error> {
990 let index = self.format.index_init(page);
991 let word = self.storage_read_slice(index, self.format.word_size());
992 self.format.parse_init(Word::from_slice(&word))
993 }
994
995 fn parse_compact(&self, page: Nat) -> Result<WordState<CompactInfo>, Error> {
997 let index = self.format.index_compact(page);
998 let word = self.storage_read_slice(index, self.format.word_size());
999 self.format.parse_compact(Word::from_slice(&word))
1000 }
1001
1002 fn parse_word(&self, pos: Position) -> Result<WordState<ParsedWord>, Error> {
1004 self.format.parse_word(Word::from_slice(&self.read_word(pos)))
1005 }
1006
1007 fn read_slice(&self, pos: Position, length: Nat) -> Vec<u8> {
1011 let mut result = Vec::with_capacity(length as usize);
1012 let index = pos.index(&self.format);
1013 let max_length = self.format.page_size() - usize_to_nat(index.byte);
1014 result.extend_from_slice(&self.storage_read_slice(index, min(length, max_length)));
1015 if length > max_length {
1016 let index = pos.next_page(&self.format).index(&self.format);
1018 result.extend_from_slice(&self.storage_read_slice(index, length - max_length));
1019 }
1020 result
1021 }
1022
1023 fn read_word(&self, pos: Position) -> Cow<'_, [u8]> {
1025 self.storage_read_slice(pos.index(&self.format), self.format.word_size())
1026 }
1027
1028 fn read_page(&self, page: Nat) -> Cow<'_, [u8]> {
1030 let index = StorageIndex { page: page as usize, byte: 0 };
1031 self.storage_read_slice(index, self.format.page_size())
1032 }
1033
1034 fn storage_read_slice(&self, index: StorageIndex, length: Nat) -> Cow<'_, [u8]> {
1036 self.storage.read_slice(index, length as usize).unwrap()
1038 }
1039
1040 fn write_slice(&mut self, pos: Position, value: &[u8]) -> Result<(), Error> {
1044 let index = pos.index(&self.format);
1045 let max_length = (self.format.page_size() - usize_to_nat(index.byte)) as usize;
1046 self.storage_write_slice(index, &value[.. min(value.len(), max_length)])?;
1047 if value.len() > max_length {
1048 let index = pos.next_page(&self.format).index(&self.format);
1050 self.storage_write_slice(index, &value[max_length ..])?;
1051 }
1052 Ok(())
1053 }
1054
1055 fn storage_write_slice(&mut self, index: StorageIndex, value: &[u8]) -> Result<(), Error> {
1060 let word_size = self.format.word_size();
1061 debug_assert!(usize_to_nat(value.len()).is_multiple_of(word_size));
1062 let slice = self.storage.read_slice(index, value.len()).map_err(Error::pop)?;
1063 for start in (0 .. usize_to_nat(value.len())).step_by(word_size as usize) {
1065 if is_write_needed(
1066 &slice[start as usize ..][.. word_size as usize],
1067 &value[start as usize ..][.. word_size as usize],
1068 )? {
1069 let index = StorageIndex {
1071 page: index.page,
1072 byte: (usize_to_nat(index.byte) + start) as usize,
1073 };
1074 let value = &value[start as usize ..];
1075 self.storage.write_slice(index, value).map_err(Error::pop)?;
1076 break;
1077 }
1078 }
1079 Ok(())
1081 }
1082
1083 fn storage_erase_page(&mut self, page: Nat) -> Result<(), Error> {
1085 if !is_erased(&self.read_page(page)) {
1086 self.storage.erase_page(page as usize).map_err(Error::pop)?;
1087 }
1088 Ok(())
1089 }
1090}
1091
1092#[cfg(feature = "std")]
1094impl Store<BufferStorage> {
1095 pub fn format(&self) -> &Format {
1097 &self.format
1098 }
1099
1100 pub fn storage(&self) -> &BufferStorage {
1102 &self.storage
1103 }
1104
1105 pub fn storage_mut(&mut self) -> &mut BufferStorage {
1107 &mut self.storage
1108 }
1109
1110 pub fn inspect_value(&self, handle: &StoreHandle) -> Vec<u8> {
1115 let head = self.head.unwrap();
1116 let length = self.format.bytes_to_words(handle.len);
1117 if head <= handle.pos {
1118 self.read_slice(handle.pos + 1, handle.len)
1120 } else if (handle.pos + length).page(&self.format) == head.page(&self.format) {
1121 let next_page = handle.pos.next_page(&self.format);
1123 let erased_len = (next_page - (handle.pos + 1)) * self.format.word_size();
1124 self.read_slice(next_page, handle.len - erased_len)
1125 } else {
1126 Vec::new()
1128 }
1129 }
1130
1131 pub fn apply(&mut self, operation: &StoreOperation) -> (Vec<StoreHandle>, Result<(), Error>) {
1137 let deleted = |store: &Store<BufferStorage>, delete_key: &dyn Fn(usize) -> bool| {
1138 store
1139 .iter()
1140 .unwrap()
1141 .filter(|x| x.is_err() || delete_key(x.as_ref().unwrap().key as usize))
1142 .collect::<Result<Vec<_>, _>>()
1143 };
1144 match *operation {
1145 StoreOperation::Transaction { ref updates } => {
1146 let keys: HashSet<usize> = updates.iter().map(|x| x.key()).collect();
1147 match deleted(self, &|key| keys.contains(&key)) {
1148 Ok(deleted) => (deleted, self.transaction(updates)),
1149 Err(error) => (Vec::new(), Err(error)),
1150 }
1151 }
1152 StoreOperation::Clear { min_key } => match deleted(self, &|key| key >= min_key) {
1153 Ok(deleted) => (deleted, self.clear(min_key)),
1154 Err(error) => (Vec::new(), Err(error)),
1155 },
1156 StoreOperation::Prepare { length } => (Vec::new(), self.prepare(length)),
1157 }
1158 }
1159
1160 pub fn init_with_cycle(storage: &mut BufferStorage, cycle: usize) {
1162 let format = Format::new(storage).unwrap();
1163 let mut index = format.index_init(0);
1165 let init_info =
1166 format.build_init(InitInfo { cycle: usize_to_nat(cycle), prefix: 0 }).unwrap();
1167 storage.write_slice(index, &init_info).unwrap();
1168 index.byte += 2 * format.word_size() as usize;
1171 storage.write_slice(index, &vec![0; format.word_size() as usize]).unwrap();
1172 for page in 0 .. storage.num_pages() {
1174 storage.set_page_erases(page, cycle);
1175 }
1176 }
1177}
1178
1179#[derive(Debug)]
1181enum ParsedEntry {
1182 Padding,
1189
1190 User(Header),
1192
1193 Internal(InternalEntry),
1195
1196 PartialUser,
1202
1203 Partial,
1209
1210 Tail,
1214}
1215
1216fn is_write_needed(source: &[u8], target: &[u8]) -> Result<bool, Error> {
1220 debug_assert_eq!(source.len(), target.len());
1221 for (&source, &target) in source.iter().zip(target.iter()) {
1222 if source & target != target {
1223 return Err(INVALID_STORAGE);
1224 }
1225 if source != target {
1226 return Ok(true);
1227 }
1228 }
1229 Ok(false)
1230}
1231
1232#[cfg(test)]
1233mod tests {
1234 use super::*;
1235 use crate::test::MINIMAL;
1236
1237 #[test]
1238 fn is_write_needed_ok() {
1239 assert_eq!(is_write_needed(&[], &[]), Ok(false));
1240 assert_eq!(is_write_needed(&[0], &[0]), Ok(false));
1241 assert_eq!(is_write_needed(&[0], &[1]), Err(INVALID_STORAGE));
1242 assert_eq!(is_write_needed(&[1], &[0]), Ok(true));
1243 assert_eq!(is_write_needed(&[1], &[1]), Ok(false));
1244 }
1245
1246 #[test]
1247 fn init_ok() {
1248 assert!(MINIMAL.new_driver().power_on().is_ok());
1249 }
1250
1251 #[test]
1252 fn insert_ok() {
1253 let mut driver = MINIMAL.new_driver().power_on().unwrap();
1254 driver.insert(0, &[]).unwrap();
1256 driver.insert(1, &[]).unwrap();
1257 driver.check().unwrap();
1258 driver.insert(0, &[0xff]).unwrap();
1260 driver.insert(1, &[0xff]).unwrap();
1261 driver.check().unwrap();
1262 driver.insert(0, &[0xff, 0xff, 0xff, 0xff]).unwrap();
1264 driver.insert(1, &[0xff, 0xff, 0xff, 0xff]).unwrap();
1265 driver.insert(2, &[0x5c; 6]).unwrap();
1266 driver.check().unwrap();
1267 assert_eq!(driver.store().tail().unwrap().get(), 13);
1269 driver.insert(3, &[0x5c; 8]).unwrap();
1270 driver.check().unwrap();
1271 assert_eq!(driver.store().tail().unwrap().get(), 16);
1272 driver.insert(2, &[0x93; (28 - 16 - 1) * 4]).unwrap();
1274 driver.check().unwrap();
1275 assert_eq!(driver.store().tail().unwrap().get(), 28);
1276 driver.insert(3, &[0x81; 10]).unwrap();
1278 driver.check().unwrap();
1279 }
1280
1281 #[test]
1282 fn remove_ok() {
1283 let mut driver = MINIMAL.new_driver().power_on().unwrap();
1284 driver.remove(0).unwrap();
1286 driver.remove(1).unwrap();
1287 driver.check().unwrap();
1288 driver.insert(0, &[0x5c; 6]).unwrap();
1290 driver.remove(0).unwrap();
1291 driver.check().unwrap();
1292 driver.insert(0, &[]).unwrap();
1294 driver.insert(1, &[]).unwrap();
1295 driver.remove(0).unwrap();
1296 driver.remove(1).unwrap();
1297 driver.check().unwrap();
1298 driver.insert(0, &[0xff]).unwrap();
1300 driver.insert(1, &[0xff; 4]).unwrap();
1301 driver.remove(0).unwrap();
1302 driver.remove(1).unwrap();
1303 driver.check().unwrap();
1304 driver.insert(2, &[0x93; 9]).unwrap();
1306 assert_eq!(driver.store().tail().unwrap().get(), 13);
1307 driver.insert(3, &[0x81; 10]).unwrap();
1308 assert_eq!(driver.store().tail().unwrap().get(), 17);
1309 driver.insert(4, &[0x76; 11]).unwrap();
1310 driver.check().unwrap();
1311 driver.remove(3).unwrap();
1313 driver.check().unwrap();
1314 assert_eq!(driver.store().tail().unwrap().get(), 21);
1316 driver.insert(2, &[0xd7; (28 - 21 - 1) * 4]).unwrap();
1317 assert_eq!(driver.store().tail().unwrap().get(), 28);
1318 driver.insert(4, &[0xe2; 21]).unwrap();
1319 driver.check().unwrap();
1320 driver.remove(2).unwrap();
1322 driver.remove(4).unwrap();
1323 driver.check().unwrap();
1324 }
1325
1326 #[test]
1327 fn prepare_ok() {
1328 let mut driver = MINIMAL.new_driver().power_on().unwrap();
1329
1330 assert_eq!(driver.store().immediate_capacity().unwrap(), 39);
1332 assert_eq!(driver.store().capacity().unwrap().remaining(), 34);
1333 assert_eq!(driver.store().head().unwrap().get(), 0);
1334 driver.store_mut().prepare(34).unwrap();
1335 assert_eq!(driver.store().head().unwrap().get(), 0);
1336
1337 for key in 0 .. 4 {
1339 driver.insert(key, &[0x38; 28]).unwrap();
1340 }
1341 driver.check().unwrap();
1342 assert_eq!(driver.store().immediate_capacity().unwrap(), 7);
1343 assert_eq!(driver.store().capacity().unwrap().remaining(), 2);
1344 driver.remove(0).unwrap();
1346 driver.remove(2).unwrap();
1347 driver.check().unwrap();
1348 assert_eq!(driver.store().immediate_capacity().unwrap(), 7);
1349 assert_eq!(driver.store().capacity().unwrap().remaining(), 18);
1350
1351 assert_eq!(driver.store().head().unwrap().get(), 0);
1353 driver.store_mut().prepare(8).unwrap();
1354 driver.check().unwrap();
1355 assert_eq!(driver.store().head().unwrap().get(), 16);
1356 assert_eq!(driver.store().immediate_capacity().unwrap(), 14);
1358 assert_eq!(driver.store().capacity().unwrap().remaining(), 18);
1359 }
1360
1361 #[test]
1362 fn reboot_ok() {
1363 let mut driver = MINIMAL.new_driver().power_on().unwrap();
1364
1365 driver.insert(0, &[0x38; 24]).unwrap();
1367 driver.insert(1, &[0x5c; 13]).unwrap();
1368 driver = driver.power_off().power_on().unwrap();
1369 driver.check().unwrap();
1370
1371 driver.insert(2, &[0x93; 1]).unwrap();
1373 driver.remove(0).unwrap();
1374 driver.insert(3, &[0xde; 9]).unwrap();
1375 driver = driver.power_off().power_on().unwrap();
1376 driver.check().unwrap();
1377 }
1378
1379 #[test]
1380 fn entries_ok() {
1381 let mut driver = MINIMAL.new_driver().power_on().unwrap();
1382
1383 assert!(driver.store().entries.as_ref().unwrap().is_empty());
1385
1386 const LEN: usize = 6;
1388 driver.insert(0, &[0x38; (LEN - 1) * 4]).unwrap();
1389 driver.insert(1, &[0x5c; 4]).unwrap();
1390 assert_eq!(driver.store().entries, Some(vec![0, LEN as u16]));
1391
1392 driver.remove(0).unwrap();
1394 assert_eq!(driver.store().entries, Some(vec![LEN as u16]));
1395 }
1396}