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