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    /// Engine and codec failures trap.
43    pub fn insert(&mut self, key: K) -> bool {
44        self.inner.insert(key, ()).is_none()
45    }
46    /// Perform `contains` on the governed ordered set.
47    ///
48    /// Engine and codec failures trap.
49    pub fn contains(&self, key: &K) -> bool {
50        self.inner.contains_key(key)
51    }
52    /// Perform `is_empty` on the governed ordered set.
53    ///
54    #[must_use]
55    pub const fn is_empty(&self) -> bool {
56        self.inner.is_empty()
57    }
58    /// Perform `len` on the governed ordered set.
59    #[must_use]
60    pub const fn len(&self) -> u64 {
61        self.inner.len()
62    }
63    /// Perform `remove` on the governed ordered set.
64    ///
65    /// Engine and codec failures trap.
66    pub fn remove(&mut self, key: &K) -> bool {
67        self.inner.remove(key).is_some()
68    }
69    /// Perform `iter` on the governed ordered set.
70    #[must_use]
71    pub fn iter(&self) -> SetIter<'_, K, M> {
72        SetIter(self.inner.iter())
73    }
74}
75
76impl<'a, K: Storable + Ord + Clone, M: Memory> IntoIterator for &'a StableBTreeSet<K, M> {
77    type Item = K;
78    type IntoIter = SetIter<'a, K, M>;
79    fn into_iter(self) -> Self::IntoIter {
80        self.iter()
81    }
82}
83
84///
85/// `SetIter`
86///
87/// Lazy bidirectional key traversal over the shared ordered-tree engine.
88///
89pub struct SetIter<'a, K: Storable + Ord + Clone, M: Memory>(MapIter<'a, K, (), M>);
90impl<K: Storable + Ord + Clone, M: Memory> Iterator for SetIter<'_, K, M> {
91    type Item = K;
92    fn next(&mut self) -> Option<K> {
93        self.0.next().map(super::MapEntry::into_key)
94    }
95    fn nth(&mut self, n: usize) -> Option<Self::Item> {
96        self.0.nth(n).map(super::MapEntry::into_key)
97    }
98    fn count(self) -> usize {
99        self.0.count()
100    }
101    fn last(self) -> Option<Self::Item> {
102        self.0.last().map(super::MapEntry::into_key)
103    }
104    fn size_hint(&self) -> (usize, Option<usize>) {
105        self.0.size_hint()
106    }
107}
108impl<K: Storable + Ord + Clone, M: Memory> DoubleEndedIterator for SetIter<'_, K, M> {
109    fn next_back(&mut self) -> Option<K> {
110        self.0.next_back().map(super::MapEntry::into_key)
111    }
112    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
113        self.0.nth_back(n).map(super::MapEntry::into_key)
114    }
115}