Skip to main content

reddb_server/runtime/
impl_native.rs

1use super::*;
2
3impl RedDBRuntime {
4    pub fn snapshots(&self) -> RedDBResult<Vec<SnapshotDescriptor>> {
5        let snapshots = self.inner.db.snapshots();
6        if snapshots.is_empty() {
7            return Err(RedDBError::NotFound("physical metadata".to_string()));
8        }
9        Ok(snapshots)
10    }
11
12    pub fn create_snapshot(&self) -> RedDBResult<SnapshotDescriptor> {
13        self.checkpoint()?;
14        self.inner
15            .db
16            .snapshots()
17            .last()
18            .cloned()
19            .ok_or_else(|| RedDBError::Internal("snapshot metadata was not recorded".to_string()))
20    }
21
22    pub fn exports(&self) -> RedDBResult<Vec<ExportDescriptor>> {
23        Ok(self.inner.db.exports())
24    }
25
26    pub fn native_header(&self) -> RedDBResult<PhysicalFileHeader> {
27        self.inner
28            .db
29            .store()
30            .physical_file_header()
31            .ok_or_else(|| RedDBError::NotFound("native physical header".to_string()))
32    }
33
34    pub fn native_collection_roots(&self) -> RedDBResult<std::collections::BTreeMap<String, u64>> {
35        self.inner
36            .db
37            .native_collection_roots()
38            .ok_or_else(|| RedDBError::NotFound("native collection roots".to_string()))
39    }
40
41    pub fn native_manifest_summary(&self) -> RedDBResult<NativeManifestSummary> {
42        self.inner
43            .db
44            .native_manifest_summary()
45            .ok_or_else(|| RedDBError::NotFound("native manifest summary".to_string()))
46    }
47
48    pub fn native_registry_summary(&self) -> RedDBResult<NativeRegistrySummary> {
49        self.inner
50            .db
51            .native_registry_summary()
52            .ok_or_else(|| RedDBError::NotFound("native registry summary".to_string()))
53    }
54
55    pub fn native_recovery_summary(&self) -> RedDBResult<NativeRecoverySummary> {
56        self.inner
57            .db
58            .native_recovery_summary()
59            .ok_or_else(|| RedDBError::NotFound("native recovery summary".to_string()))
60    }
61
62    pub fn native_catalog_summary(&self) -> RedDBResult<NativeCatalogSummary> {
63        self.inner
64            .db
65            .native_catalog_summary()
66            .ok_or_else(|| RedDBError::NotFound("native catalog summary".to_string()))
67    }
68
69    pub fn native_physical_state(&self) -> RedDBResult<NativePhysicalState> {
70        self.inner
71            .db
72            .native_physical_state()
73            .ok_or_else(|| RedDBError::NotFound("native physical state".to_string()))
74    }
75
76    pub fn native_vector_artifact_pages(
77        &self,
78    ) -> RedDBResult<Vec<crate::storage::unified::store::NativeVectorArtifactPageSummary>> {
79        self.inner
80            .db
81            .native_vector_artifact_pages()
82            .ok_or_else(|| RedDBError::NotFound("native vector artifact pages".to_string()))
83    }
84
85    pub fn inspect_native_vector_artifact(
86        &self,
87        collection: &str,
88        artifact_kind: Option<&str>,
89    ) -> RedDBResult<crate::storage::unified::devx::NativeVectorArtifactInspection> {
90        self.inner
91            .db
92            .inspect_native_vector_artifact(collection, artifact_kind)
93            .map_err(|err| {
94                if err.contains("not found") || err.contains("not available") {
95                    RedDBError::NotFound(err)
96                } else {
97                    RedDBError::Internal(err)
98                }
99            })
100    }
101
102    pub fn warmup_native_vector_artifact(
103        &self,
104        collection: &str,
105        artifact_kind: Option<&str>,
106    ) -> RedDBResult<crate::storage::unified::devx::NativeVectorArtifactInspection> {
107        self.inner
108            .db
109            .warmup_native_vector_artifact(collection, artifact_kind)
110            .map_err(|err| {
111                if err.contains("not found") || err.contains("not available") {
112                    RedDBError::NotFound(err)
113                } else {
114                    RedDBError::Internal(err)
115                }
116            })
117    }
118
119    pub fn inspect_native_vector_artifacts(
120        &self,
121    ) -> RedDBResult<crate::storage::unified::devx::NativeVectorArtifactBatchInspection> {
122        self.inner
123            .db
124            .inspect_native_vector_artifacts()
125            .map_err(|err| {
126                if err.contains("not available") {
127                    RedDBError::NotFound(err)
128                } else {
129                    RedDBError::Internal(err)
130                }
131            })
132    }
133
134    pub fn warmup_native_vector_artifacts(
135        &self,
136    ) -> RedDBResult<crate::storage::unified::devx::NativeVectorArtifactBatchInspection> {
137        self.inner
138            .db
139            .warmup_native_vector_artifacts()
140            .map_err(|err| {
141                if err.contains("not available") {
142                    RedDBError::NotFound(err)
143                } else {
144                    RedDBError::Internal(err)
145                }
146            })
147    }
148
149    pub fn native_header_repair_policy(&self) -> RedDBResult<String> {
150        let policy = self.inner.db.native_header_repair_policy().ok_or_else(|| {
151            RedDBError::NotFound("native physical header repair policy".to_string())
152        })?;
153        Ok(match policy {
154            crate::storage::NativeHeaderRepairPolicy::InSync => "in_sync",
155            crate::storage::NativeHeaderRepairPolicy::RepairNativeFromMetadata => {
156                "repair_native_from_metadata"
157            }
158            crate::storage::NativeHeaderRepairPolicy::NativeAheadOfMetadata => {
159                "native_ahead_of_metadata"
160            }
161        }
162        .to_string())
163    }
164
165    pub fn repair_native_header_from_metadata(&self) -> RedDBResult<String> {
166        let policy = self
167            .inner
168            .db
169            .repair_native_header_from_metadata()
170            .map_err(|err| RedDBError::Internal(err.to_string()))?;
171        Ok(match policy {
172            crate::storage::NativeHeaderRepairPolicy::InSync => "in_sync",
173            crate::storage::NativeHeaderRepairPolicy::RepairNativeFromMetadata => {
174                "repair_native_from_metadata"
175            }
176            crate::storage::NativeHeaderRepairPolicy::NativeAheadOfMetadata => {
177                "native_ahead_of_metadata"
178            }
179        }
180        .to_string())
181    }
182
183    pub fn rebuild_physical_metadata_from_native_state(&self) -> RedDBResult<bool> {
184        self.inner
185            .db
186            .rebuild_physical_metadata_from_native_state()
187            .map_err(|err| RedDBError::Internal(err.to_string()))
188    }
189
190    pub fn repair_native_physical_state_from_metadata(&self) -> RedDBResult<bool> {
191        self.inner
192            .db
193            .repair_native_physical_state_from_metadata()
194            .map_err(|err| RedDBError::Internal(err.to_string()))
195    }
196
197    pub fn native_metadata_state_summary(
198        &self,
199    ) -> RedDBResult<crate::storage::unified::store::NativeMetadataStateSummary> {
200        self.inner
201            .db
202            .native_metadata_state_summary()
203            .ok_or_else(|| RedDBError::NotFound("native metadata state".to_string()))
204    }
205
206    pub fn physical_authority_status(
207        &self,
208    ) -> crate::storage::unified::devx::PhysicalAuthorityStatus {
209        self.inner.db.physical_authority_status()
210    }
211
212    pub fn readiness_for_query(&self) -> bool {
213        self.inner.db.readiness_for_query()
214    }
215
216    pub fn readiness_for_query_serverless(&self) -> bool {
217        self.inner.db.readiness_for_query_serverless()
218    }
219
220    pub fn readiness_for_write(&self) -> bool {
221        self.inner.db.readiness_for_write()
222    }
223
224    pub fn readiness_for_write_serverless(&self) -> bool {
225        self.inner.db.readiness_for_write_serverless()
226    }
227
228    pub fn readiness_for_repair(&self) -> bool {
229        self.inner.db.readiness_for_repair()
230    }
231
232    pub fn readiness_for_repair_serverless(&self) -> bool {
233        self.inner.db.readiness_for_repair_serverless()
234    }
235
236    pub fn manifest_events(&self) -> RedDBResult<Vec<ManifestEvent>> {
237        if let Some(metadata) = self.inner.db.physical_metadata() {
238            return Ok(metadata.manifest_events);
239        }
240        if let Some(summary) = self.inner.db.native_manifest_summary() {
241            return Ok(summary
242                .recent_events
243                .into_iter()
244                .map(|event| ManifestEvent {
245                    collection: event.collection,
246                    object_key: event.object_key,
247                    kind: match event.kind.as_str() {
248                        "insert" => crate::physical::ManifestEventKind::Insert,
249                        "update" => crate::physical::ManifestEventKind::Update,
250                        "remove" => crate::physical::ManifestEventKind::Remove,
251                        _ => crate::physical::ManifestEventKind::Checkpoint,
252                    },
253                    block: crate::physical::BlockReference {
254                        index: event.block_index,
255                        checksum: event.block_checksum,
256                    },
257                    snapshot_min: event.snapshot_min,
258                    snapshot_max: event.snapshot_max,
259                })
260                .collect());
261        }
262        Err(RedDBError::NotFound("physical metadata".to_string()))
263    }
264
265    pub fn manifest_events_filtered(
266        &self,
267        collection: Option<&str>,
268        kind: Option<&str>,
269        since_snapshot: Option<u64>,
270    ) -> RedDBResult<Vec<ManifestEvent>> {
271        let mut events = self.manifest_events()?;
272        if let Some(collection) = collection {
273            events.retain(|event| event.collection == collection);
274        }
275        if let Some(kind) = kind {
276            let kind = normalize_graph_token(kind);
277            events.retain(|event| {
278                normalize_graph_token(match event.kind {
279                    crate::physical::ManifestEventKind::Insert => "insert",
280                    crate::physical::ManifestEventKind::Update => "update",
281                    crate::physical::ManifestEventKind::Remove => "remove",
282                    crate::physical::ManifestEventKind::Checkpoint => "checkpoint",
283                }) == kind
284            });
285        }
286        if let Some(since_snapshot) = since_snapshot {
287            events.retain(|event| event.snapshot_min >= since_snapshot);
288        }
289        Ok(events)
290    }
291
292    pub fn collection_roots(&self) -> RedDBResult<std::collections::BTreeMap<String, u64>> {
293        if let Some(metadata) = self.inner.db.physical_metadata() {
294            return Ok(metadata.superblock.collection_roots);
295        }
296        if let Some(state) = self.inner.db.native_physical_state() {
297            return Ok(state.collection_roots);
298        }
299        Err(RedDBError::NotFound("physical metadata".to_string()))
300    }
301}