Skip to main content

ic_storage/adapter/
map.rs

1//! Governed map collection implementation.
2use super::error::{CollectionError as Error, Result, ensure};
3use super::tree::Tree;
4use super::{MapIter, Memory, Storable};
5use crate::DefaultMemoryImpl;
6use crate::RuntimeMemory;
7use std::ops::RangeBounds;
8
9/// Governed ordered map backed by Storage’s owned B-tree and reusable blocks.
10pub struct StableBTreeMap<K: Storable + Ord + Clone, V: Storable, M: Memory = DefaultMemoryImpl> {
11    inner: Tree<K, V, RuntimeMemory<M>>,
12}
13impl<K: Storable + Ord + Clone, V: Storable, M: Memory> StableBTreeMap<K, V, M> {
14    /// Create a collection only in zero-page memory.
15    ///
16    /// # Errors
17    /// Refuses nonempty memory, invalid encoding or capacity exhaustion before writes.
18    pub fn create(memory: RuntimeMemory<M>) -> Result<Self> {
19        ensure(memory.size() == 0, Error::NotEmpty)?;
20        Self::reset(memory)
21    }
22
23    /// Deliberately replace any contents in this admitted allocation.
24    ///
25    /// # Errors
26    /// Returns encoding, capacity or structural admission errors.
27    pub fn reset(memory: RuntimeMemory<M>) -> Result<Self> {
28        Ok(Self {
29            inner: Tree::reset(memory)?,
30        })
31    }
32
33    /// Load retained collection state without initializing a replacement.
34    ///
35    /// # Errors
36    /// Refuses empty, foreign or corrupt memory and incompatible bounds without writing.
37    pub fn load(memory: RuntimeMemory<M>) -> Result<Self> {
38        Ok(Self {
39            inner: Tree::load(memory)?,
40        })
41    }
42    /// Clear entries while retaining this allocation's exclusive lease.
43    ///
44    /// # Errors
45    /// Reports a poisoned owner or metadata encoding/capacity refusal.
46    pub fn clear(&mut self) -> Result<()> {
47        self.inner.clear()
48    }
49    /// Reserve a minimum virtual extent without exposing or duplicating the lease.
50    ///
51    /// Returns the map on both success and ordinary growth refusal. Entries are
52    /// preserved; the cached tree remains unchanged.
53    /// Backing traps follow the host transaction contract.
54    ///
55    /// `minimum` is an absolute virtual extent in 65,536-byte Wasm pages, not an
56    /// entry count or additional pages. Existing extents never shrink. A request
57    /// already covered performs no growth or writes. This reserves backing only:
58    /// it does not promise that any particular number or encoding of entries fits.
59    /// Callers own their byte/page budget and must qualify it for their codecs;
60    /// internal node-layout constants are not a supported capacity contract.
61    pub fn reserve_pages(
62        self,
63        minimum: u64,
64    ) -> (Self, std::result::Result<(), crate::RuntimeGrowError>) {
65        let additional = minimum.saturating_sub(self.inner.memory.size());
66        let result = self.inner.memory.grow(additional).map(|_| ());
67        (self, result)
68    }
69    /// Observe the virtual extent in 65,536-byte pages while retaining the lease.
70    ///
71    /// Consumes and returns the map while retaining the exclusive lease.
72    /// Observing the allocation performs no writes or growth.
73    /// This is allocated extent, not free space or guaranteed entry capacity.
74    #[must_use]
75    pub fn allocated_pages(self) -> (Self, u64) {
76        let pages = self.inner.memory.size();
77        (self, pages)
78    }
79    /// Perform `insert` on the governed ordered map.
80    ///
81    /// # Errors
82    /// Rejects encoding, decoding, structural or capacity errors before committing writes.
83    pub fn insert(&mut self, key: K, value: V) -> Result<Option<V>> {
84        self.inner.insert(key, value)
85    }
86    /// Perform `get` on the governed ordered map.
87    ///
88    /// # Errors
89    /// Reports structural, integrity or application decoding failures without writing.
90    pub fn get(&self, key: &K) -> Result<Option<V>> {
91        self.inner.get(key)
92    }
93    /// Perform `contains_key` on the governed ordered map.
94    ///
95    /// # Errors
96    /// Reports structural, integrity or application decoding failures without writing.
97    pub fn contains_key(&self, key: &K) -> Result<bool> {
98        self.inner.contains_key(key)
99    }
100    /// Perform `is_empty` on the governed ordered map.
101    ///
102    /// # Errors
103    /// Reports invalid region metadata or incompatible codec bounds.
104    pub fn is_empty(&self) -> bool {
105        self.inner.len() == 0
106    }
107    /// Perform `len` on the governed ordered map.
108    pub fn len(&self) -> u64 {
109        self.inner.len()
110    }
111    /// Perform `remove` on the governed ordered map.
112    ///
113    /// # Errors
114    /// Rejects decoding or structural errors before committing removal.
115    pub fn remove(&mut self, key: &K) -> Result<Option<V>> {
116        self.inner.remove(key)
117    }
118    /// Perform `first_key_value` on the governed ordered map.
119    ///
120    /// # Errors
121    /// Reports invalid structure, integrity failures or application codec errors.
122    pub fn first_key_value(&self) -> Result<Option<(K, V)>> {
123        self.iter()
124            .next()
125            .map(|entry| entry?.into_pair())
126            .transpose()
127    }
128    /// Perform `last_key_value` on the governed ordered map.
129    ///
130    /// # Errors
131    /// Reports invalid structure, integrity failures or application codec errors.
132    pub fn last_key_value(&self) -> Result<Option<(K, V)>> {
133        self.iter()
134            .next_back()
135            .map(|entry| entry?.into_pair())
136            .transpose()
137    }
138    /// Perform `iter` on the governed ordered map.
139    pub fn iter(&self) -> MapIter<'_, K, V, M> {
140        self.inner.range(..)
141    }
142    /// Perform `range` on the governed ordered map.
143    pub fn range(&self, key_range: impl RangeBounds<K>) -> MapIter<'_, K, V, M> {
144        self.inner.range(key_range)
145    }
146    /// Perform `keys` on the governed ordered map.
147    pub fn keys(&self) -> impl DoubleEndedIterator<Item = Result<K>> + '_ {
148        self.inner.keys_range(..)
149    }
150    /// Perform `values` on the governed ordered map.
151    pub fn values(&self) -> impl DoubleEndedIterator<Item = Result<V>> + '_ {
152        self.iter().map(|entry| entry?.into_value())
153    }
154}
155
156impl<'a, K: Storable + Ord + Clone, V: Storable, M: Memory> IntoIterator
157    for &'a StableBTreeMap<K, V, M>
158{
159    type Item = <MapIter<'a, K, V, M> as Iterator>::Item;
160    type IntoIter = MapIter<'a, K, V, M>;
161    fn into_iter(self) -> Self::IntoIter {
162        self.iter()
163    }
164}