icydb_core/db/index/
store.rs1use crate::{
7 db::{
8 data::StorageKey,
9 index::{entry::RawIndexEntry, key::RawIndexKey},
10 },
11 error::InternalError,
12};
13
14use canic_cdk::structures::{BTreeMap, DefaultMemoryImpl, memory::VirtualMemory};
15
16pub struct IndexStore {
25 pub(super) map: BTreeMap<RawIndexKey, RawIndexEntry, VirtualMemory<DefaultMemoryImpl>>,
26 generation: u64,
27 secondary_covering_authoritative: bool,
28 secondary_existence_witness_authoritative: bool,
29}
30
31impl IndexStore {
32 #[must_use]
33 pub fn init(memory: VirtualMemory<DefaultMemoryImpl>) -> Self {
34 Self {
35 map: BTreeMap::init(memory),
36 generation: 0,
37 secondary_covering_authoritative: false,
38 secondary_existence_witness_authoritative: false,
39 }
40 }
41
42 #[allow(clippy::redundant_closure_for_method_calls)]
44 pub(crate) fn entries(&self) -> Vec<(RawIndexKey, RawIndexEntry)> {
45 self.map.iter().map(|entry| entry.into_pair()).collect()
46 }
47
48 pub(in crate::db) fn get(&self, key: &RawIndexKey) -> Option<RawIndexEntry> {
49 self.map.get(key)
50 }
51
52 pub fn len(&self) -> u64 {
53 self.map.len()
54 }
55
56 pub fn is_empty(&self) -> bool {
57 self.map.is_empty()
58 }
59
60 #[must_use]
61 pub(in crate::db) const fn generation(&self) -> u64 {
62 self.generation
63 }
64
65 pub(crate) fn insert(
66 &mut self,
67 key: RawIndexKey,
68 entry: RawIndexEntry,
69 ) -> Option<RawIndexEntry> {
70 let previous = self.map.insert(key, entry);
71 self.bump_generation();
72 self.invalidate_secondary_covering_authority();
73 self.invalidate_secondary_existence_witness_authority();
74 previous
75 }
76
77 pub(crate) fn remove(&mut self, key: &RawIndexKey) -> Option<RawIndexEntry> {
78 let previous = self.map.remove(key);
79 self.bump_generation();
80 self.invalidate_secondary_covering_authority();
81 self.invalidate_secondary_existence_witness_authority();
82 previous
83 }
84
85 pub fn clear(&mut self) {
86 self.map.clear();
87 self.bump_generation();
88 self.invalidate_secondary_covering_authority();
89 self.invalidate_secondary_existence_witness_authority();
90 }
91
92 #[must_use]
95 pub(in crate::db) const fn secondary_covering_authoritative(&self) -> bool {
96 self.secondary_covering_authoritative
97 }
98
99 pub(in crate::db) const fn mark_secondary_covering_authoritative(&mut self) {
102 self.secondary_covering_authoritative = true;
103 }
104
105 #[must_use]
108 pub(in crate::db) const fn secondary_existence_witness_authoritative(&self) -> bool {
109 self.secondary_existence_witness_authoritative
110 }
111
112 pub(in crate::db) const fn mark_secondary_existence_witness_authoritative(&mut self) {
115 self.secondary_existence_witness_authoritative = true;
116 }
117
118 pub(in crate::db) fn mark_memberships_missing_for_storage_key(
121 &mut self,
122 storage_key: StorageKey,
123 ) -> Result<usize, InternalError> {
124 let mut entries = Vec::new();
125
126 for entry in self.map.iter() {
127 entries.push(entry.into_pair());
128 }
129
130 let mut marked = 0usize;
131
132 for (raw_key, mut raw_entry) in entries {
133 if raw_entry
134 .mark_key_missing(storage_key)
135 .map_err(InternalError::index_entry_decode_failed)?
136 {
137 self.map.insert(raw_key, raw_entry);
138 marked = marked.saturating_add(1);
139 }
140 }
141
142 if marked > 0 {
143 self.bump_generation();
144 self.invalidate_secondary_covering_authority();
145 self.invalidate_secondary_existence_witness_authority();
146 }
147
148 Ok(marked)
149 }
150
151 pub fn memory_bytes(&self) -> u64 {
153 self.map
154 .iter()
155 .map(|entry| entry.key().as_bytes().len() as u64 + entry.value().len() as u64)
156 .sum()
157 }
158
159 const fn bump_generation(&mut self) {
160 self.generation = self.generation.saturating_add(1);
161 }
162
163 const fn invalidate_secondary_covering_authority(&mut self) {
164 self.secondary_covering_authoritative = false;
165 }
166
167 const fn invalidate_secondary_existence_witness_authority(&mut self) {
168 self.secondary_existence_witness_authoritative = false;
169 }
170}