Skip to main content

ic_storage/adapter/
set.rs

1//! Governed set collection implementation.
2use super::error::{CollectionError as Error, Result, ensure};
3use super::{MapIter, Memory, StableBTreeMap, Storable};
4use crate::DefaultMemoryImpl;
5use crate::RuntimeMemory;
6
7/// Governed ordered set sharing Storage’s owned map engine with unit values.
8pub struct StableBTreeSet<K: Storable + Ord + Clone, M: Memory = DefaultMemoryImpl> {
9    inner: StableBTreeMap<K, (), M>,
10}
11impl<K: Storable + Ord + Clone, M: Memory> StableBTreeSet<K, M> {
12    /// Create a collection only in zero-page memory.
13    ///
14    /// # Errors
15    /// Refuses nonempty memory or initial growth refusal; engine failures trap.
16    pub fn create(memory: RuntimeMemory<M>) -> Result<Self> {
17        ensure(memory.size() == 0, Error::NotEmpty)?;
18        Self::reset(memory)
19    }
20
21    /// Deliberately replace any contents in this admitted allocation.
22    ///
23    /// # Errors
24    /// Returns initial growth refusal; engine failures trap.
25    pub fn reset(memory: RuntimeMemory<M>) -> Result<Self> {
26        Ok(Self {
27            inner: StableBTreeMap::reset(memory)?,
28        })
29    }
30
31    /// Load retained collection state without initializing a replacement.
32    ///
33    /// # Errors
34    /// Refuses empty or foreign framing; malformed engine state traps.
35    pub fn load(memory: RuntimeMemory<M>) -> Result<Self> {
36        Ok(Self {
37            inner: StableBTreeMap::load(memory)?,
38        })
39    }
40    /// Perform `insert` on the governed ordered set.
41    ///
42    /// # Errors
43    /// Engine and codec failures trap, possibly after writes on native hosts.
44    pub fn insert(&mut self, key: K) -> Result<bool> {
45        Ok(self.inner.insert(key, ())?.is_none())
46    }
47    /// Perform `contains` on the governed ordered set.
48    ///
49    /// # Errors
50    /// Engine and codec failures trap instead of returning an ordinary error.
51    pub fn contains(&self, key: &K) -> Result<bool> {
52        self.inner.contains_key(key)
53    }
54    /// Perform `is_empty` on the governed ordered set.
55    ///
56    #[must_use]
57    pub const fn is_empty(&self) -> bool {
58        self.inner.is_empty()
59    }
60    /// Perform `len` on the governed ordered set.
61    #[must_use]
62    pub const fn len(&self) -> u64 {
63        self.inner.len()
64    }
65    /// Perform `remove` on the governed ordered set.
66    ///
67    /// # Errors
68    /// Engine and codec failures trap, possibly after writes on native hosts.
69    pub fn remove(&mut self, key: &K) -> Result<bool> {
70        Ok(self.inner.remove(key)?.is_some())
71    }
72    /// Perform `iter` on the governed ordered set.
73    #[must_use]
74    pub fn iter(&self) -> SetIter<'_, K, M> {
75        SetIter(self.inner.iter())
76    }
77}
78
79impl<'a, K: Storable + Ord + Clone, M: Memory> IntoIterator for &'a StableBTreeSet<K, M> {
80    type Item = Result<K>;
81    type IntoIter = SetIter<'a, K, M>;
82    fn into_iter(self) -> Self::IntoIter {
83        self.iter()
84    }
85}
86
87///
88/// `SetIter`
89///
90/// Lazy bidirectional key traversal over the shared ordered-tree engine.
91///
92pub struct SetIter<'a, K: Storable + Ord + Clone, M: Memory>(MapIter<'a, K, (), M>);
93impl<K: Storable + Ord + Clone, M: Memory> Iterator for SetIter<'_, K, M> {
94    type Item = Result<K>;
95    fn next(&mut self) -> Option<Result<K>> {
96        self.0
97            .next()
98            .map(|entry| entry.map(super::MapEntry::into_key))
99    }
100    fn nth(&mut self, n: usize) -> Option<Self::Item> {
101        self.0
102            .nth(n)
103            .map(|entry| entry.map(super::MapEntry::into_key))
104    }
105    fn count(self) -> usize {
106        self.0.count()
107    }
108    fn last(self) -> Option<Self::Item> {
109        self.0
110            .last()
111            .map(|entry| entry.map(super::MapEntry::into_key))
112    }
113    fn size_hint(&self) -> (usize, Option<usize>) {
114        self.0.size_hint()
115    }
116}
117impl<K: Storable + Ord + Clone, M: Memory> DoubleEndedIterator for SetIter<'_, K, M> {
118    fn next_back(&mut self) -> Option<Result<K>> {
119        self.0
120            .next_back()
121            .map(|entry| entry.map(super::MapEntry::into_key))
122    }
123    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
124        self.0
125            .nth_back(n)
126            .map(|entry| entry.map(super::MapEntry::into_key))
127    }
128}