sequential_storage/cache/
array_impl.rs1use core::num::NonZeroU32;
2
3use crate::{
4 PageState,
5 cache::{
6 CacheImpl, DirtTracker, Invalidate, KeyCacheImpl, PagePointersCache, PageStatesCache,
7 PrivateCacheImpl, PrivateKeyCacheImpl,
8 key_pointers::{CachedKeyPointers, KeyPointersCache, UncachedKeyPointers},
9 page_pointers::{CachedPagePointers, UncachedPagePointers},
10 page_states::CachedPageStates,
11 },
12 map::Key,
13};
14
15#[derive(Debug)]
27#[cfg_attr(feature = "defmt", derive(defmt::Format))]
28pub struct PageStateCache<const PAGE_COUNT: usize> {
29 dirt_tracker: DirtTracker,
30 page_states: [Option<PageState>; PAGE_COUNT],
31}
32
33impl<const PAGE_COUNT: usize> PageStateCache<PAGE_COUNT> {
34 #[must_use]
36 pub const fn new() -> Self {
37 Self {
38 dirt_tracker: DirtTracker::new(),
39 page_states: [None; PAGE_COUNT],
40 }
41 }
42}
43
44impl<const PAGE_COUNT: usize> Default for PageStateCache<PAGE_COUNT> {
45 fn default() -> Self {
46 Self::new()
47 }
48}
49
50impl<const PAGE_COUNT: usize> PrivateCacheImpl for PageStateCache<PAGE_COUNT> {
51 type PSC<'a>
52 = CachedPageStates<'a>
53 where
54 Self: 'a;
55 type PPC<'a>
56 = UncachedPagePointers
57 where
58 Self: 'a;
59
60 fn dirt_tracker<R>(&mut self, f: impl FnOnce(&mut DirtTracker) -> R) -> Option<R> {
61 Some(f(&mut self.dirt_tracker))
62 }
63
64 fn page_states(&mut self) -> Self::PSC<'_> {
65 CachedPageStates::new(&mut self.page_states)
66 }
67
68 fn page_pointers(&mut self) -> Self::PPC<'_> {
69 UncachedPagePointers
70 }
71}
72
73impl<const PAGE_COUNT: usize> CacheImpl for PageStateCache<PAGE_COUNT> {}
74impl<KEY: Key, const PAGE_COUNT: usize> KeyCacheImpl<KEY> for PageStateCache<PAGE_COUNT> {}
75
76impl<const PAGE_COUNT: usize> Invalidate for PageStateCache<PAGE_COUNT> {
77 fn invalidate_cache_state(&mut self) {
78 self.dirt_tracker.unmark_dirty();
79 self.page_states().invalidate_cache_state();
80 self.page_pointers().invalidate_cache_state();
81 }
82}
83
84impl<KEY: Key, const PAGE_COUNT: usize> PrivateKeyCacheImpl<KEY> for PageStateCache<PAGE_COUNT> {
85 type KPC<'a>
86 = UncachedKeyPointers
87 where
88 Self: 'a;
89
90 fn key_pointers(&mut self) -> Self::KPC<'_> {
91 UncachedKeyPointers
92 }
93}
94
95#[derive(Debug)]
107#[cfg_attr(feature = "defmt", derive(defmt::Format))]
108pub struct PagePointerCache<const PAGE_COUNT: usize> {
109 dirt_tracker: DirtTracker,
110 page_states: [Option<PageState>; PAGE_COUNT],
111 after_erased_pointers: [Option<NonZeroU32>; PAGE_COUNT],
112 after_written_pointers: [Option<NonZeroU32>; PAGE_COUNT],
113}
114
115impl<const PAGE_COUNT: usize> PagePointerCache<PAGE_COUNT> {
116 #[must_use]
118 pub const fn new() -> Self {
119 Self {
120 dirt_tracker: DirtTracker::new(),
121 page_states: [None; PAGE_COUNT],
122 after_erased_pointers: [None; PAGE_COUNT],
123 after_written_pointers: [None; PAGE_COUNT],
124 }
125 }
126}
127
128impl<const PAGE_COUNT: usize> Default for PagePointerCache<PAGE_COUNT> {
129 fn default() -> Self {
130 Self::new()
131 }
132}
133
134impl<const PAGE_COUNT: usize> PrivateCacheImpl for PagePointerCache<PAGE_COUNT> {
135 type PSC<'a>
136 = CachedPageStates<'a>
137 where
138 Self: 'a;
139 type PPC<'a>
140 = CachedPagePointers<'a>
141 where
142 Self: 'a;
143
144 fn dirt_tracker<R>(&mut self, f: impl FnOnce(&mut DirtTracker) -> R) -> Option<R> {
145 Some(f(&mut self.dirt_tracker))
146 }
147
148 fn page_states(&mut self) -> Self::PSC<'_> {
149 CachedPageStates::new(&mut self.page_states)
150 }
151
152 fn page_pointers(&mut self) -> Self::PPC<'_> {
153 CachedPagePointers::new(
154 &mut self.after_erased_pointers,
155 &mut self.after_written_pointers,
156 )
157 }
158}
159
160impl<const PAGE_COUNT: usize> CacheImpl for PagePointerCache<PAGE_COUNT> {}
161impl<KEY: Key, const PAGE_COUNT: usize> KeyCacheImpl<KEY> for PagePointerCache<PAGE_COUNT> {}
162
163impl<const PAGE_COUNT: usize> Invalidate for PagePointerCache<PAGE_COUNT> {
164 fn invalidate_cache_state(&mut self) {
165 self.dirt_tracker.unmark_dirty();
166 self.page_states().invalidate_cache_state();
167 self.page_pointers().invalidate_cache_state();
168 }
169}
170
171impl<KEY: Key, const PAGE_COUNT: usize> PrivateKeyCacheImpl<KEY> for PagePointerCache<PAGE_COUNT> {
172 type KPC<'a>
173 = UncachedKeyPointers
174 where
175 Self: 'a;
176
177 fn key_pointers(&mut self) -> Self::KPC<'_> {
178 UncachedKeyPointers
179 }
180}
181
182#[derive(Debug)]
199#[cfg_attr(feature = "defmt", derive(defmt::Format))]
200pub struct KeyPointerCache<const PAGE_COUNT: usize, KEY: Key, const KEYS: usize> {
201 dirt_tracker: DirtTracker,
202 page_states: [Option<PageState>; PAGE_COUNT],
203 after_erased_pointers: [Option<NonZeroU32>; PAGE_COUNT],
204 after_written_pointers: [Option<NonZeroU32>; PAGE_COUNT],
205 key_pointers: [Option<(KEY, NonZeroU32)>; KEYS],
206}
207
208impl<const PAGE_COUNT: usize, KEY: Key, const KEYS: usize> KeyPointerCache<PAGE_COUNT, KEY, KEYS> {
209 #[must_use]
211 pub const fn new() -> Self {
212 Self {
213 dirt_tracker: DirtTracker::new(),
214 page_states: [None; PAGE_COUNT],
215 after_erased_pointers: [None; PAGE_COUNT],
216 after_written_pointers: [None; PAGE_COUNT],
217 key_pointers: [const { None }; KEYS],
218 }
219 }
220}
221
222impl<const PAGE_COUNT: usize, KEY: Key, const KEYS: usize> Default
223 for KeyPointerCache<PAGE_COUNT, KEY, KEYS>
224{
225 fn default() -> Self {
226 Self::new()
227 }
228}
229
230impl<const PAGE_COUNT: usize, KEY: Key, const KEYS: usize> PrivateCacheImpl
231 for KeyPointerCache<PAGE_COUNT, KEY, KEYS>
232{
233 type PSC<'a>
234 = CachedPageStates<'a>
235 where
236 Self: 'a;
237 type PPC<'a>
238 = CachedPagePointers<'a>
239 where
240 Self: 'a;
241
242 fn dirt_tracker<R>(&mut self, f: impl FnOnce(&mut DirtTracker) -> R) -> Option<R> {
243 Some(f(&mut self.dirt_tracker))
244 }
245
246 fn page_states(&mut self) -> Self::PSC<'_> {
247 CachedPageStates::new(&mut self.page_states)
248 }
249
250 fn page_pointers(&mut self) -> Self::PPC<'_> {
251 CachedPagePointers::new(
252 &mut self.after_erased_pointers,
253 &mut self.after_written_pointers,
254 )
255 }
256}
257
258impl<const PAGE_COUNT: usize, KEY: Key, const KEYS: usize> CacheImpl
259 for KeyPointerCache<PAGE_COUNT, KEY, KEYS>
260{
261}
262impl<const PAGE_COUNT: usize, KEY: Key, const KEYS: usize> KeyCacheImpl<KEY>
263 for KeyPointerCache<PAGE_COUNT, KEY, KEYS>
264{
265}
266
267impl<const PAGE_COUNT: usize, KEY: Key, const KEYS: usize> Invalidate
268 for KeyPointerCache<PAGE_COUNT, KEY, KEYS>
269{
270 fn invalidate_cache_state(&mut self) {
271 self.dirt_tracker.unmark_dirty();
272 self.page_states().invalidate_cache_state();
273 self.page_pointers().invalidate_cache_state();
274 self.key_pointers().invalidate_cache_state();
275 }
276}
277
278impl<const PAGE_COUNT: usize, KEY: Key, const KEYS: usize> PrivateKeyCacheImpl<KEY>
279 for KeyPointerCache<PAGE_COUNT, KEY, KEYS>
280{
281 type KPC<'a>
282 = CachedKeyPointers<'a, KEY>
283 where
284 Self: 'a;
285
286 fn key_pointers(&mut self) -> Self::KPC<'_> {
287 CachedKeyPointers::new(&mut self.key_pointers)
288 }
289}