reddb_server/runtime/
impl_native.rs1use 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}