reddb_server/runtime/
impl_dml_chain.rs1use super::*;
10use crate::storage::query::unified::UnifiedResult;
11
12impl RedDBRuntime {
13 pub fn chain_tip_for_collection(
19 &self,
20 collection: &str,
21 ) -> Option<crate::runtime::blockchain_kind::ChainTipFull> {
22 let store = self.inner.db.store();
23 if !crate::runtime::blockchain_kind::is_chain(&store, collection) {
24 return None;
25 }
26 let mut cache = self.inner.chain_tip_cache.lock();
27 if let Some(existing) = cache.get(collection) {
28 return Some(existing.clone());
29 }
30 let scanned = crate::runtime::blockchain_kind::chain_tip_full(&store, collection)?;
31 cache.insert(collection.to_string(), scanned.clone());
32 Some(scanned)
33 }
34
35 pub fn verify_chain_for_collection(
42 &self,
43 collection: &str,
44 ) -> Option<crate::runtime::blockchain_kind::VerifyChainOutcome> {
45 let store = self.inner.db.store();
46 let outcome = crate::runtime::blockchain_kind::verify_chain_outcome(&store, collection)?;
47 if !outcome.ok {
48 crate::runtime::blockchain_kind::persist_integrity_flag(&store, collection, true);
49 self.inner
50 .chain_integrity_broken
51 .lock()
52 .insert(collection.to_string(), true);
53 }
54 Some(outcome)
55 }
56
57 pub fn clear_chain_integrity_flag(&self, collection: &str) -> bool {
61 let store = self.inner.db.store();
62 if !crate::runtime::blockchain_kind::is_chain(&store, collection) {
63 return false;
64 }
65 crate::runtime::blockchain_kind::persist_integrity_flag(&store, collection, false);
66 self.inner
67 .chain_integrity_broken
68 .lock()
69 .insert(collection.to_string(), false);
70 true
71 }
72
73 pub(super) fn is_chain_integrity_broken(&self, collection: &str) -> bool {
77 {
78 let cache = self.inner.chain_integrity_broken.lock();
79 if let Some(v) = cache.get(collection) {
80 return *v;
81 }
82 }
83 let store = self.inner.db.store();
84 let persisted =
85 crate::runtime::blockchain_kind::is_integrity_broken_persisted(&store, collection)
86 .unwrap_or(false);
87 self.inner
88 .chain_integrity_broken
89 .lock()
90 .insert(collection.to_string(), persisted);
91 persisted
92 }
93
94 fn ensure_integrity_tombstones_loaded(&self) -> bool {
99 use std::sync::atomic::Ordering;
100 match self
101 .inner
102 .integrity_tombstones_state
103 .load(Ordering::Relaxed)
104 {
105 1 => return false,
106 2 => return true,
107 _ => {}
108 }
109 let mut guard = self.inner.integrity_tombstones.lock();
112 if self
113 .inner
114 .integrity_tombstones_state
115 .load(Ordering::Relaxed)
116 == 0
117 {
118 let ranges = crate::runtime::integrity_tombstone::load_ranges(&self.inner.db.store());
119 let present = !ranges.is_empty();
120 *guard = ranges;
121 self.inner
122 .integrity_tombstones_state
123 .store(if present { 2 } else { 1 }, Ordering::Relaxed);
124 }
125 self.inner
126 .integrity_tombstones_state
127 .load(Ordering::Relaxed)
128 == 2
129 }
130
131 pub fn record_integrity_tombstone(&self, table: &str, lo: u64, hi: u64) {
137 use std::sync::atomic::Ordering;
138 self.ensure_integrity_tombstones_loaded();
139 let mut guard = self.inner.integrity_tombstones.lock();
140 guard.push(crate::runtime::integrity_tombstone::TombstoneRange::new(
141 table.to_string(),
142 lo,
143 hi,
144 ));
145 crate::runtime::integrity_tombstone::persist_ranges(&self.inner.db.store(), &guard);
146 self.inner
147 .integrity_tombstones_state
148 .store(2, Ordering::Relaxed);
149 }
150
151 pub fn integrity_tombstone_ranges(
155 &self,
156 ) -> Vec<crate::runtime::integrity_tombstone::TombstoneRange> {
157 self.ensure_integrity_tombstones_loaded();
158 self.inner.integrity_tombstones.lock().clone()
159 }
160
161 pub fn filter_integrity_tombstoned(&self, result: &mut UnifiedResult) {
166 if !self.ensure_integrity_tombstones_loaded() {
167 return;
168 }
169 let guard = self.inner.integrity_tombstones.lock();
170 if guard.is_empty() {
171 return;
172 }
173 let before = result.records.len();
174 result.records.retain(|record| {
175 !crate::runtime::integrity_tombstone::record_tombstoned(&guard, record)
176 });
177 if result.records.len() != before {
178 result.pre_serialized_json = None;
179 }
180 }
181}