Skip to main content

ic_storage/
adapter.rs

1//! Supported upstream collections with governed memory and an explicit API.
2//!
3//! Constructors preserve upstream initialization, panic and persisted-format
4//! contracts. These wrappers expose neither raw memory nor unrestricted
5//! upstream collections.
6//! Use distinct admitted allocations and drop collections before reopening.
7//! IC Memory 0.46 enforces one live lease per allocation within each runtime;
8//! hosts retain exclusive custody of the backing across runtimes.
9use crate::substrate::{self, DefaultMemoryImpl, Memory};
10use ic_memory::RuntimeMemory;
11use std::ops::RangeBounds;
12pub use substrate::{Storable, storable};
13
14#[cfg(all(test, not(target_arch = "wasm32")))]
15mod tests;
16
17/// Governed upstream `BTreeMap`; initialization and failures follow upstream contracts.
18pub struct StableBTreeMap<K: Storable + Ord + Clone, V: Storable, M: Memory = DefaultMemoryImpl> {
19    inner: substrate::BTreeMap<K, V, RuntimeMemory<M>>,
20}
21impl<K: Storable + Ord + Clone, V: Storable, M: Memory> StableBTreeMap<K, V, M> {
22    /// Delegates to upstream `BTreeMap::new` with the governed allocation.
23    pub fn new(memory: RuntimeMemory<M>) -> Self {
24        Self {
25            inner: substrate::BTreeMap::new(memory),
26        }
27    }
28    /// Delegates to upstream `BTreeMap::init` with the governed allocation.
29    pub fn init(memory: RuntimeMemory<M>) -> Self {
30        Self {
31            inner: substrate::BTreeMap::init(memory),
32        }
33    }
34    /// Delegates to upstream `BTreeMap::load` with the governed allocation.
35    pub fn load(memory: RuntimeMemory<M>) -> Self {
36        Self {
37            inner: substrate::BTreeMap::load(memory),
38        }
39    }
40    /// Delegates to upstream `BTreeMap::insert` with the governed allocation.
41    pub fn insert(&mut self, key: K, value: V) -> Option<V> {
42        self.inner.insert(key, value)
43    }
44    /// Delegates to upstream `BTreeMap::get` with the governed allocation.
45    pub fn get(&self, key: &K) -> Option<V> {
46        self.inner.get(key)
47    }
48    /// Delegates to upstream `BTreeMap::contains_key` with the governed allocation.
49    pub fn contains_key(&self, key: &K) -> bool {
50        self.inner.contains_key(key)
51    }
52    /// Delegates to upstream `BTreeMap::is_empty` with the governed allocation.
53    pub fn is_empty(&self) -> bool {
54        self.inner.is_empty()
55    }
56    /// Delegates to upstream `BTreeMap::len` with the governed allocation.
57    pub fn len(&self) -> u64 {
58        self.inner.len()
59    }
60    /// Delegates to upstream `BTreeMap::remove` with the governed allocation.
61    pub fn remove(&mut self, key: &K) -> Option<V> {
62        self.inner.remove(key)
63    }
64    /// Delegates to upstream `BTreeMap::first_key_value` with the governed allocation.
65    pub fn first_key_value(&self) -> Option<(K, V)> {
66        self.inner.first_key_value()
67    }
68    /// Delegates to upstream `BTreeMap::last_key_value` with the governed allocation.
69    pub fn last_key_value(&self) -> Option<(K, V)> {
70        self.inner.last_key_value()
71    }
72    /// Delegates to upstream `BTreeMap::pop_first` with the governed allocation.
73    pub fn pop_first(&mut self) -> Option<(K, V)> {
74        self.inner.pop_first()
75    }
76    /// Delegates to upstream `BTreeMap::pop_last` with the governed allocation.
77    pub fn pop_last(&mut self) -> Option<(K, V)> {
78        self.inner.pop_last()
79    }
80    /// Delegates to upstream `BTreeMap::iter` with the governed allocation.
81    pub fn iter(&self) -> MapIter<'_, K, V, M> {
82        self.inner.iter()
83    }
84    /// Delegates to upstream `BTreeMap::range` with the governed allocation.
85    pub fn range(&self, key_range: impl RangeBounds<K>) -> MapIter<'_, K, V, M> {
86        self.inner.range(key_range)
87    }
88    /// Delegates to upstream `BTreeMap::keys` with the governed allocation.
89    pub fn keys(&self) -> impl DoubleEndedIterator<Item = K> + '_ {
90        self.inner.keys()
91    }
92    /// Delegates to upstream `BTreeMap::values` with the governed allocation.
93    pub fn values(&self) -> impl DoubleEndedIterator<Item = V> + '_ {
94        self.inner.values()
95    }
96}
97
98/// Governed upstream `BTreeSet`; initialization and failures follow upstream contracts.
99pub struct StableBTreeSet<K: Storable + Ord + Clone, M: Memory = DefaultMemoryImpl> {
100    inner: substrate::BTreeSet<K, RuntimeMemory<M>>,
101}
102impl<K: Storable + Ord + Clone, M: Memory> StableBTreeSet<K, M> {
103    /// Delegates to upstream `BTreeSet::new` with the governed allocation.
104    pub fn new(memory: RuntimeMemory<M>) -> Self {
105        Self {
106            inner: substrate::BTreeSet::new(memory),
107        }
108    }
109    /// Delegates to upstream `BTreeSet::init` with the governed allocation.
110    pub fn init(memory: RuntimeMemory<M>) -> Self {
111        Self {
112            inner: substrate::BTreeSet::init(memory),
113        }
114    }
115    /// Delegates to upstream `BTreeSet::load` with the governed allocation.
116    pub fn load(memory: RuntimeMemory<M>) -> Self {
117        Self {
118            inner: substrate::BTreeSet::load(memory),
119        }
120    }
121    /// Delegates to upstream `BTreeSet::insert` with the governed allocation.
122    pub fn insert(&mut self, key: K) -> bool {
123        self.inner.insert(key)
124    }
125    /// Delegates to upstream `BTreeSet::contains` with the governed allocation.
126    pub fn contains(&self, key: &K) -> bool {
127        self.inner.contains(key)
128    }
129    /// Delegates to upstream `BTreeSet::is_empty` with the governed allocation.
130    pub fn is_empty(&self) -> bool {
131        self.inner.is_empty()
132    }
133    /// Delegates to upstream `BTreeSet::len` with the governed allocation.
134    pub fn len(&self) -> u64 {
135        self.inner.len()
136    }
137    /// Delegates to upstream `BTreeSet::remove` with the governed allocation.
138    pub fn remove(&mut self, key: &K) -> bool {
139        self.inner.remove(key)
140    }
141    /// Delegates to upstream `BTreeSet::first` with the governed allocation.
142    pub fn first(&self) -> Option<K> {
143        self.inner.first()
144    }
145    /// Delegates to upstream `BTreeSet::last` with the governed allocation.
146    pub fn last(&self) -> Option<K> {
147        self.inner.last()
148    }
149    /// Delegates to upstream `BTreeSet::pop_first` with the governed allocation.
150    pub fn pop_first(&mut self) -> Option<K> {
151        self.inner.pop_first()
152    }
153    /// Delegates to upstream `BTreeSet::pop_last` with the governed allocation.
154    pub fn pop_last(&mut self) -> Option<K> {
155        self.inner.pop_last()
156    }
157    /// Delegates to upstream `BTreeSet::iter` with the governed allocation.
158    pub fn iter(&self) -> SetIter<'_, K, M> {
159        self.inner.iter()
160    }
161    /// Delegates to upstream `BTreeSet::range` with the governed allocation.
162    pub fn range(&self, key_range: impl RangeBounds<K>) -> SetIter<'_, K, M> {
163        self.inner.range(key_range)
164    }
165    /// Delegates to upstream `BTreeSet::clear` with the governed allocation.
166    pub fn clear(&mut self) {
167        self.inner.clear();
168    }
169}
170
171/// Governed upstream `Cell`; initialization and failures follow upstream contracts.
172pub struct StableCell<T: Storable, M: Memory = DefaultMemoryImpl> {
173    inner: substrate::Cell<T, RuntimeMemory<M>>,
174}
175impl<T: Storable, M: Memory> StableCell<T, M> {
176    /// Delegates to upstream `Cell::new` with the governed allocation.
177    pub fn new(memory: RuntimeMemory<M>, value: T) -> Self {
178        Self {
179            inner: substrate::Cell::new(memory, value),
180        }
181    }
182    /// Delegates to upstream `Cell::init` with the governed allocation.
183    pub fn init(memory: RuntimeMemory<M>, default_value: T) -> Self {
184        Self {
185            inner: substrate::Cell::init(memory, default_value),
186        }
187    }
188    /// Delegates to upstream `Cell::get` with the governed allocation.
189    pub fn get(&self) -> &T {
190        self.inner.get()
191    }
192    /// Delegates to upstream `Cell::set` with the governed allocation.
193    pub fn set(&mut self, value: T) -> T {
194        self.inner.set(value)
195    }
196}
197
198/// Governed upstream `Vec`; initialization and failures follow upstream contracts.
199pub struct StableVec<T: Storable, M: Memory = DefaultMemoryImpl> {
200    inner: substrate::Vec<T, RuntimeMemory<M>>,
201}
202impl<T: Storable, M: Memory> StableVec<T, M> {
203    /// Delegates to upstream `Vec::new` with the governed allocation.
204    pub fn new(memory: RuntimeMemory<M>) -> Self {
205        Self {
206            inner: substrate::Vec::new(memory),
207        }
208    }
209    /// Delegates to upstream `Vec::init` with the governed allocation.
210    pub fn init(memory: RuntimeMemory<M>) -> Self {
211        Self {
212            inner: substrate::Vec::init(memory),
213        }
214    }
215    /// Delegates to upstream `Vec::get` with the governed allocation.
216    pub fn get(&self, index: u64) -> Option<T> {
217        self.inner.get(index)
218    }
219    /// Delegates to upstream `Vec::set` with the governed allocation.
220    pub fn set(&self, index: u64, item: &T) {
221        self.inner.set(index, item);
222    }
223    /// Delegates to upstream `Vec::push` with the governed allocation.
224    pub fn push(&self, item: &T) {
225        self.inner.push(item);
226    }
227    /// Delegates to upstream `Vec::pop` with the governed allocation.
228    pub fn pop(&self) -> Option<T> {
229        self.inner.pop()
230    }
231    /// Delegates to upstream `Vec::len` with the governed allocation.
232    pub fn len(&self) -> u64 {
233        self.inner.len()
234    }
235    /// Delegates to upstream `Vec::is_empty` with the governed allocation.
236    pub fn is_empty(&self) -> bool {
237        self.inner.is_empty()
238    }
239    /// Delegates to upstream `Vec::iter` with the governed allocation.
240    pub fn iter(&self) -> impl DoubleEndedIterator<Item = T> + '_ {
241        self.inner.iter()
242    }
243}
244
245/// Governed upstream `MinHeap`; initialization and failures follow upstream contracts.
246pub struct StableMinHeap<T: Storable + Ord, M: Memory = DefaultMemoryImpl> {
247    inner: substrate::MinHeap<T, RuntimeMemory<M>>,
248}
249impl<T: Storable + Ord, M: Memory> StableMinHeap<T, M> {
250    /// Delegates to upstream `MinHeap::new` with the governed allocation.
251    pub fn new(memory: RuntimeMemory<M>) -> Self {
252        Self {
253            inner: substrate::MinHeap::new(memory),
254        }
255    }
256    /// Delegates to upstream `MinHeap::init` with the governed allocation.
257    pub fn init(memory: RuntimeMemory<M>) -> Self {
258        Self {
259            inner: substrate::MinHeap::init(memory),
260        }
261    }
262    /// Delegates to upstream `MinHeap::push` with the governed allocation.
263    pub fn push(&mut self, item: &T) {
264        self.inner.push(item);
265    }
266    /// Delegates to upstream `MinHeap::pop` with the governed allocation.
267    pub fn pop(&mut self) -> Option<T> {
268        self.inner.pop()
269    }
270    /// Delegates to upstream `MinHeap::peek` with the governed allocation.
271    pub fn peek(&self) -> Option<T> {
272        self.inner.peek()
273    }
274    /// Delegates to upstream `MinHeap::len` with the governed allocation.
275    pub fn len(&self) -> u64 {
276        self.inner.len()
277    }
278    /// Delegates to upstream `MinHeap::is_empty` with the governed allocation.
279    pub fn is_empty(&self) -> bool {
280        self.inner.is_empty()
281    }
282    /// Delegates to upstream `MinHeap::iter` with the governed allocation.
283    pub fn iter(&self) -> impl Iterator<Item = T> + '_ {
284        self.inner.iter()
285    }
286}
287
288/// Governed upstream `Log`; initialization and failures follow upstream contracts.
289pub struct StableLog<T: Storable, M: Memory = DefaultMemoryImpl> {
290    inner: substrate::Log<T, RuntimeMemory<M>, RuntimeMemory<M>>,
291}
292impl<T: Storable, M: Memory> StableLog<T, M> {
293    /// Delegates to upstream `Log::new` with the governed allocation.
294    pub fn new(index_memory: RuntimeMemory<M>, data_memory: RuntimeMemory<M>) -> Self {
295        Self {
296            inner: substrate::Log::new(index_memory, data_memory),
297        }
298    }
299    /// Delegates to upstream `Log::init` with the governed allocation.
300    pub fn init(index_memory: RuntimeMemory<M>, data_memory: RuntimeMemory<M>) -> Self {
301        Self {
302            inner: substrate::Log::init(index_memory, data_memory),
303        }
304    }
305    /// Delegates to upstream `Log::first` with the governed allocation.
306    pub fn first(&self) -> Option<T> {
307        self.inner.first()
308    }
309    /// Delegates to upstream `Log::last` with the governed allocation.
310    pub fn last(&self) -> Option<T> {
311        self.inner.last()
312    }
313    /// Delegates to upstream `Log::get` with the governed allocation.
314    pub fn get(&self, idx: u64) -> Option<T> {
315        self.inner.get(idx)
316    }
317    /// Delegates to upstream `Log::len` with the governed allocation.
318    pub fn len(&self) -> u64 {
319        self.inner.len()
320    }
321    /// Delegates to upstream `Log::is_empty` with the governed allocation.
322    pub fn is_empty(&self) -> bool {
323        self.inner.is_empty()
324    }
325    /// Delegates to upstream `Log::append` with the governed allocation.
326    /// # Errors
327    /// Returns the upstream write error if memory cannot grow.
328    pub fn append(&self, item: &T) -> Result<u64, LogWriteError> {
329        self.inner.append(item)
330    }
331    /// Delegates to upstream `Log::iter` with the governed allocation.
332    pub fn iter(&self) -> LogIter<'_, T, M> {
333        self.inner.iter()
334    }
335}
336
337/// Upstream map iterator with governed memory.
338pub type MapIter<'a, K, V, M = DefaultMemoryImpl> =
339    substrate::btreemap::Iter<'a, K, V, RuntimeMemory<M>>;
340/// Upstream set iterator with governed memory.
341pub type SetIter<'a, K, M = DefaultMemoryImpl> = substrate::btreeset::Iter<'a, K, RuntimeMemory<M>>;
342/// Upstream log iterator with governed index and data memories.
343pub type LogIter<'a, T, M = DefaultMemoryImpl> =
344    substrate::log::Iter<'a, T, RuntimeMemory<M>, RuntimeMemory<M>>;
345
346pub use substrate::log::WriteError as LogWriteError;
347
348impl<'a, K: Storable + Ord + Clone, V: Storable, M: Memory> IntoIterator
349    for &'a StableBTreeMap<K, V, M>
350{
351    type Item = <MapIter<'a, K, V, M> as Iterator>::Item;
352    type IntoIter = MapIter<'a, K, V, M>;
353    fn into_iter(self) -> Self::IntoIter {
354        self.iter()
355    }
356}
357
358impl<'a, K: Storable + Ord + Clone, M: Memory> IntoIterator for &'a StableBTreeSet<K, M> {
359    type Item = K;
360    type IntoIter = SetIter<'a, K, M>;
361    fn into_iter(self) -> Self::IntoIter {
362        self.iter()
363    }
364}
365
366impl<'a, T: Storable, M: Memory> IntoIterator for &'a StableLog<T, M> {
367    type Item = T;
368    type IntoIter = LogIter<'a, T, M>;
369    fn into_iter(self) -> Self::IntoIter {
370        self.iter()
371    }
372}