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}