Skip to main content

ic_storage/adapter/
set.rs

1//! Governed set collection implementation.
2use super::{Memory, SetIter, Storable};
3use crate::substrate::{self, DefaultMemoryImpl};
4use ic_memory::RuntimeMemory;
5use std::ops::RangeBounds;
6
7/// Governed upstream `BTreeSet`; initialization and failures follow upstream contracts.
8pub struct StableBTreeSet<K: Storable + Ord + Clone, M: Memory = DefaultMemoryImpl> {
9    inner: substrate::BTreeSet<K, RuntimeMemory<M>>,
10}
11impl<K: Storable + Ord + Clone, M: Memory> StableBTreeSet<K, M> {
12    /// Create a collection only in zero-page memory.
13    ///
14    /// # Panics
15    /// Refuses nonempty memory before writing. Growth and codec failures retain
16    /// upstream behavior.
17    pub fn create(memory: RuntimeMemory<M>) -> Self {
18        assert_eq!(memory.size(), 0, "collection memory is not empty");
19        Self::reset(memory)
20    }
21
22    /// Deliberately replace any contents in this admitted allocation.
23    ///
24    /// # Panics
25    /// Growth and codec failures retain upstream behavior.
26    pub fn reset(memory: RuntimeMemory<M>) -> Self {
27        Self {
28            inner: substrate::BTreeSet::new(memory),
29        }
30    }
31
32    /// Load retained collection state without initializing a replacement.
33    ///
34    /// # Panics
35    /// Refuses empty or foreign memory and incompatible layouts/bounds without
36    /// writing. Record decoding and backing failures retain upstream behavior.
37    pub fn load(memory: RuntimeMemory<M>) -> Self {
38        Self {
39            inner: substrate::BTreeSet::load(memory),
40        }
41    }
42    /// Delegates to upstream `BTreeSet::insert` with the governed allocation.
43    pub fn insert(&mut self, key: K) -> bool {
44        self.inner.insert(key)
45    }
46    /// Delegates to upstream `BTreeSet::contains` with the governed allocation.
47    pub fn contains(&self, key: &K) -> bool {
48        self.inner.contains(key)
49    }
50    /// Delegates to upstream `BTreeSet::is_empty` with the governed allocation.
51    pub fn is_empty(&self) -> bool {
52        self.inner.is_empty()
53    }
54    /// Delegates to upstream `BTreeSet::len` with the governed allocation.
55    pub fn len(&self) -> u64 {
56        self.inner.len()
57    }
58    /// Delegates to upstream `BTreeSet::remove` with the governed allocation.
59    pub fn remove(&mut self, key: &K) -> bool {
60        self.inner.remove(key)
61    }
62    /// Delegates to upstream `BTreeSet::first` with the governed allocation.
63    pub fn first(&self) -> Option<K> {
64        self.inner.first()
65    }
66    /// Delegates to upstream `BTreeSet::last` with the governed allocation.
67    pub fn last(&self) -> Option<K> {
68        self.inner.last()
69    }
70    /// Delegates to upstream `BTreeSet::pop_first` with the governed allocation.
71    pub fn pop_first(&mut self) -> Option<K> {
72        self.inner.pop_first()
73    }
74    /// Delegates to upstream `BTreeSet::pop_last` with the governed allocation.
75    pub fn pop_last(&mut self) -> Option<K> {
76        self.inner.pop_last()
77    }
78    /// Delegates to upstream `BTreeSet::iter` with the governed allocation.
79    pub fn iter(&self) -> SetIter<'_, K, M> {
80        self.inner.iter()
81    }
82    /// Delegates to upstream `BTreeSet::range` with the governed allocation.
83    pub fn range(&self, key_range: impl RangeBounds<K>) -> SetIter<'_, K, M> {
84        self.inner.range(key_range)
85    }
86    /// Delegates to upstream `BTreeSet::clear` with the governed allocation.
87    pub fn clear(&mut self) {
88        self.inner.clear();
89    }
90}
91
92impl<'a, K: Storable + Ord + Clone, M: Memory> IntoIterator for &'a StableBTreeSet<K, M> {
93    type Item = K;
94    type IntoIter = SetIter<'a, K, M>;
95    fn into_iter(self) -> Self::IntoIter {
96        self.iter()
97    }
98}