sequential_storage/cache/
heap_impl.rs1extern crate alloc;
2
3use alloc::{vec, vec::Vec};
4use core::num::NonZeroU32;
5
6use crate::{
7 PageState,
8 cache::{
9 CacheImpl, DirtTracker, Invalidate, KeyCacheImpl, PagePointersCache, PageStatesCache,
10 PrivateCacheImpl, PrivateKeyCacheImpl,
11 key_pointers::{CachedKeyPointers, KeyPointersCache, UncachedKeyPointers},
12 page_pointers::{CachedPagePointers, UncachedPagePointers},
13 page_states::CachedPageStates,
14 },
15 map::Key,
16};
17
18#[derive(Debug)]
30#[cfg_attr(feature = "defmt", derive(defmt::Format))]
31pub struct HeapPageStateCache {
32 dirt_tracker: DirtTracker,
33 page_states: Vec<Option<PageState>>,
34}
35
36impl HeapPageStateCache {
37 pub fn new(pages: usize) -> Self {
39 Self {
40 dirt_tracker: DirtTracker::new(),
41 page_states: vec![None; pages],
42 }
43 }
44}
45
46impl PrivateCacheImpl for HeapPageStateCache {
47 type PSC<'a>
48 = CachedPageStates<'a>
49 where
50 Self: 'a;
51 type PPC<'a>
52 = UncachedPagePointers
53 where
54 Self: 'a;
55
56 fn dirt_tracker<R>(&mut self, f: impl FnOnce(&mut DirtTracker) -> R) -> Option<R> {
57 Some(f(&mut self.dirt_tracker))
58 }
59
60 fn page_states(&mut self) -> Self::PSC<'_> {
61 CachedPageStates::new(&mut self.page_states)
62 }
63
64 fn page_pointers(&mut self) -> Self::PPC<'_> {
65 UncachedPagePointers
66 }
67}
68
69impl CacheImpl for HeapPageStateCache {}
70impl<KEY: Key> KeyCacheImpl<KEY> for HeapPageStateCache {}
71
72impl Invalidate for HeapPageStateCache {
73 fn invalidate_cache_state(&mut self) {
74 self.dirt_tracker.unmark_dirty();
75 self.page_states().invalidate_cache_state();
76 self.page_pointers().invalidate_cache_state();
77 }
78}
79
80impl<KEY: Key> PrivateKeyCacheImpl<KEY> for HeapPageStateCache {
81 type KPC<'a>
82 = UncachedKeyPointers
83 where
84 Self: 'a;
85
86 fn key_pointers(&mut self) -> Self::KPC<'_> {
87 UncachedKeyPointers
88 }
89}
90
91#[derive(Debug)]
103#[cfg_attr(feature = "defmt", derive(defmt::Format))]
104pub struct HeapPagePointerCache {
105 dirt_tracker: DirtTracker,
106 page_states: Vec<Option<PageState>>,
107 after_erased_pointers: Vec<Option<NonZeroU32>>,
108 after_written_pointers: Vec<Option<NonZeroU32>>,
109}
110
111impl HeapPagePointerCache {
112 pub fn new(pages: usize) -> Self {
114 Self {
115 dirt_tracker: DirtTracker::new(),
116 page_states: vec![None; pages],
117 after_erased_pointers: vec![None; pages],
118 after_written_pointers: vec![None; pages],
119 }
120 }
121}
122
123impl PrivateCacheImpl for HeapPagePointerCache {
124 type PSC<'a>
125 = CachedPageStates<'a>
126 where
127 Self: 'a;
128 type PPC<'a>
129 = CachedPagePointers<'a>
130 where
131 Self: 'a;
132
133 fn dirt_tracker<R>(&mut self, f: impl FnOnce(&mut DirtTracker) -> R) -> Option<R> {
134 Some(f(&mut self.dirt_tracker))
135 }
136
137 fn page_states(&mut self) -> Self::PSC<'_> {
138 CachedPageStates::new(&mut self.page_states)
139 }
140
141 fn page_pointers(&mut self) -> Self::PPC<'_> {
142 CachedPagePointers::new(
143 &mut self.after_erased_pointers,
144 &mut self.after_written_pointers,
145 )
146 }
147}
148
149impl CacheImpl for HeapPagePointerCache {}
150impl<KEY: Key> KeyCacheImpl<KEY> for HeapPagePointerCache {}
151
152impl Invalidate for HeapPagePointerCache {
153 fn invalidate_cache_state(&mut self) {
154 self.dirt_tracker.unmark_dirty();
155 self.page_states().invalidate_cache_state();
156 self.page_pointers().invalidate_cache_state();
157 }
158}
159
160impl<KEY: Key> PrivateKeyCacheImpl<KEY> for HeapPagePointerCache {
161 type KPC<'a>
162 = UncachedKeyPointers
163 where
164 Self: 'a;
165
166 fn key_pointers(&mut self) -> Self::KPC<'_> {
167 UncachedKeyPointers
168 }
169}
170
171#[derive(Debug)]
188#[cfg_attr(feature = "defmt", derive(defmt::Format))]
189pub struct HeapKeyPointerCache<KEY: Key> {
190 dirt_tracker: DirtTracker,
191 page_states: Vec<Option<PageState>>,
192 after_erased_pointers: Vec<Option<NonZeroU32>>,
193 after_written_pointers: Vec<Option<NonZeroU32>>,
194 key_pointers: Vec<Option<(KEY, NonZeroU32)>>,
195}
196
197impl<KEY: Key> HeapKeyPointerCache<KEY> {
198 pub fn new(pages: usize, keys: usize) -> Self {
200 Self {
201 dirt_tracker: DirtTracker::new(),
202 page_states: vec![None; pages],
203 after_erased_pointers: vec![None; pages],
204 after_written_pointers: vec![None; pages],
205 key_pointers: vec![const { None }; keys],
206 }
207 }
208}
209
210impl<KEY: Key> PrivateCacheImpl for HeapKeyPointerCache<KEY> {
211 type PSC<'a>
212 = CachedPageStates<'a>
213 where
214 Self: 'a;
215 type PPC<'a>
216 = CachedPagePointers<'a>
217 where
218 Self: 'a;
219
220 fn dirt_tracker<R>(&mut self, f: impl FnOnce(&mut DirtTracker) -> R) -> Option<R> {
221 Some(f(&mut self.dirt_tracker))
222 }
223
224 fn page_states(&mut self) -> Self::PSC<'_> {
225 CachedPageStates::new(&mut self.page_states)
226 }
227
228 fn page_pointers(&mut self) -> Self::PPC<'_> {
229 CachedPagePointers::new(
230 &mut self.after_erased_pointers,
231 &mut self.after_written_pointers,
232 )
233 }
234}
235
236impl<KEY: Key> CacheImpl for HeapKeyPointerCache<KEY> {}
237impl<KEY: Key> KeyCacheImpl<KEY> for HeapKeyPointerCache<KEY> {}
238
239impl<KEY: Key> Invalidate for HeapKeyPointerCache<KEY> {
240 fn invalidate_cache_state(&mut self) {
241 self.dirt_tracker.unmark_dirty();
242 self.page_states().invalidate_cache_state();
243 self.page_pointers().invalidate_cache_state();
244 self.key_pointers().invalidate_cache_state();
245 }
246}
247
248impl<KEY: Key> PrivateKeyCacheImpl<KEY> for HeapKeyPointerCache<KEY> {
249 type KPC<'a>
250 = CachedKeyPointers<'a, KEY>
251 where
252 Self: 'a;
253
254 fn key_pointers(&mut self) -> Self::KPC<'_> {
255 CachedKeyPointers::new(&mut self.key_pointers)
256 }
257}