1#![no_std]
2
3use core::str::Utf8Error;
4
5use adapters::StoreAdapter;
6use modular_bitfield::prelude::*;
7
8mod alloc;
9mod grasshopper;
10mod store;
11
12pub mod adapters;
13
14pub use alloc::*;
15pub use grasshopper::*;
16pub use store::*;
17
18pub const MAX_KEY_LEN: usize = 256;
19pub const MAX_VALUE_LEN: usize = 64 * 1024;
20
21pub type Address = usize;
22
23#[derive(Debug)]
24pub struct Bucket {
25 index: usize,
26 raw: RawBucket,
27}
28
29impl Bucket {
30 pub fn val_address(&self) -> Address {
31 let addr = self.raw.address() + self.raw.key_len() as u32;
32 addr as Address
33 }
34
35 pub(crate) fn index(&self) -> usize {
36 self.index
37 }
38
39 pub(crate) fn address(&self) -> Address {
40 self.raw.address() as Address
41 }
42
43 pub fn key_len(&self) -> usize {
44 self.raw.key_len() as usize
45 }
46
47 pub fn val_len(&self) -> usize {
48 self.raw.val_len() as usize
49 }
50
51 pub fn record_len(&self) -> usize {
52 self.key_len() + self.val_len()
53 }
54}
55
56#[derive(Debug, PartialEq)]
57pub enum Error<E> {
58 AdapterError(E),
59 IndexOverflow,
60 InvalidCapacity,
61 InvalidNonce,
62 InvalidPatchOffset,
63 KeyNotFound,
64 ReadOnlyStore,
65 StoreNotFound,
66 StoreOverflow,
67 ValueOverflow,
68 KeyOverflow,
69 Utf8Error(Utf8Error),
70 #[cfg(feature = "serde")]
71 SerializationError(postcard::Error),
72}
73
74#[bitfield]
75pub(crate) struct StoreHeader {
76 magic: B32,
77 nonce: B16,
78 buckets: B16,
79}
80
81#[bitfield]
82#[derive(Default, Debug, Clone)]
83pub(crate) struct RawBucket {
84 val_len: B16,
85 key_len: B8,
86 address: B24,
87 hash: B16,
88}
89
90pub struct KeysIterator<'a, 'b, A, const BUCKETS: usize, const SLOTS: usize>
91where
92 A: StoreAdapter,
93{
94 store: &'a mut KVStore<A, BUCKETS, SLOTS>,
95 prefix: Option<&'b [u8]>,
96 cursor: usize,
97}
98
99impl<'a, 'b, A, const BUCKETS: usize, const SLOTS: usize> KeysIterator<'a, 'b, A, BUCKETS, SLOTS>
100where
101 A: StoreAdapter,
102{
103 pub fn new(store: &'a mut KVStore<A, BUCKETS, SLOTS>) -> Self {
104 Self {
105 store,
106 cursor: 0,
107 prefix: None,
108 }
109 }
110
111 pub fn with_prefix(store: &'a mut KVStore<A, BUCKETS, SLOTS>, prefix: &'b [u8]) -> Self {
112 Self {
113 store,
114 cursor: 0,
115 prefix: Some(prefix),
116 }
117 }
118}
119
120impl<'a, 'b, A, const BUCKETS: usize, const SLOTS: usize> Iterator
121 for KeysIterator<'a, 'b, A, BUCKETS, SLOTS>
122where
123 A: StoreAdapter,
124{
125 type Item = KeyReference;
126
127 fn next(&mut self) -> Option<Self::Item> {
128 loop {
129 if self.cursor >= BUCKETS {
130 return None;
131 }
132
133 let raw = self.store.load_bucket(self.cursor).unwrap_or_default();
134 let index = self.cursor;
135 self.cursor += 1;
136
137 let key_len = raw.key_len() as usize;
138 let prefix_len = self.prefix.map_or(0, |prefix| prefix.len());
139
140 if key_len > prefix_len {
141 let val_len = raw.val_len() as usize;
142 let bucket = Bucket { index, raw };
143 let address = bucket.raw.address() as Address;
144 let mut scratch = [0; MAX_KEY_LEN];
145
146 self.store
147 .adapter()
148 .read(address, &mut scratch[..key_len])
149 .ok();
150
151 if matches!(self.prefix, Some(prefix) if &scratch[..prefix_len] != prefix) {
152 continue;
153 }
154
155 return Some(KeyReference {
156 key_len,
157 val_len,
158 scratch,
159 });
160 }
161 }
162 }
163}
164
165pub struct KeyReference {
166 key_len: usize,
167 val_len: usize,
168 scratch: [u8; MAX_KEY_LEN],
169}
170
171impl KeyReference {
172 pub fn key(&self) -> &[u8] {
173 &self.scratch[..self.key_len]
174 }
175
176 pub fn val_len(&self) -> usize {
177 self.val_len
178 }
179}