kvs/
lib.rs

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}