1use std::cmp::Ordering;
4use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
5use std::sync::atomic::{AtomicU64, Ordering as AtomicOrdering};
6use std::sync::{Arc, Mutex};
7use std::time::{SystemTime, UNIX_EPOCH};
8
9use crate::api::{RedDBError, RedDBOptions, RedDBResult};
10use crate::catalog::{
11 CatalogAnalyticsJobStatus, CatalogAttentionSummary, CatalogGraphProjectionStatus,
12 CatalogIndexStatus, CatalogModelSnapshot, CollectionDescriptor,
13};
14use crate::health::{HealthProvider, HealthReport};
15use crate::index::IndexCatalog;
16use crate::physical::{
17 ExportDescriptor, ManifestEvent, PhysicalAnalyticsJob, PhysicalGraphProjection, PhysicalLayout,
18 SnapshotDescriptor,
19};
20use crate::serde_json::Value as JsonValue;
21use crate::storage::engine::pathfinding::{AStar, BellmanFord, Dijkstra, BFS, DFS};
22use crate::storage::engine::{
23 BetweennessCentrality, ClosenessCentrality, ClusteringCoefficient, ConnectedComponents,
24 CycleDetector, DegreeCentrality, EigenvectorCentrality, GraphStore, IvfConfig, IvfIndex,
25 IvfStats, LabelPropagation, Louvain, MetadataEntry, MetadataFilter as VectorMetadataFilter,
26 MetadataValue as VectorMetadataValue, PageRank, PersonalizedPageRank, PhysicalFileHeader,
27 StoredNode, StronglyConnectedComponents, WeaklyConnectedComponents, HITS,
28};
29use crate::storage::query::is_universal_entity_source as is_universal_query_source;
30use crate::storage::query::planner::{
31 CanonicalLogicalPlan, CanonicalPlanner, CostEstimator, QueryPlanner,
32};
33use crate::storage::query::unified::{UnifiedRecord, UnifiedResult};
34use crate::storage::unified::dsl::{
35 apply_filters, cosine_similarity, Filter as DslFilter, FilterOp as DslFilterOp,
36 FilterValue as DslFilterValue, GraphPatternDsl, HybridQueryBuilder, MatchComponents,
37 QueryResult as DslQueryResult, ScoredMatch, TextSearchBuilder,
38};
39use crate::storage::unified::store::{
40 NativeCatalogSummary, NativeManifestSummary, NativePhysicalState, NativeRecoverySummary,
41 NativeRegistrySummary,
42};
43use crate::storage::unified::{
44 Metadata, MetadataValue as UnifiedMetadataValue, RefTarget, UnifiedMetadataFilter,
45};
46use crate::storage::{
47 EntityData, EntityId, EntityKind, RedDB, RefType, SimilarResult, StoreStats, UnifiedEntity,
48 UnifiedStore,
49};
50use reddb_rql::ast::{
51 AlterOperation, AlterQueueQuery, AlterTableQuery, CompareOp, CreateCollectionQuery,
52 CreateIndexQuery, CreateQueueQuery, CreateTableQuery, CreateTimeSeriesQuery, CreateTreeQuery,
53 CreateVectorQuery, DeleteQuery, DropCollectionQuery, DropDocumentQuery, DropForkQuery,
54 DropGraphQuery, DropIndexQuery, DropKvQuery, DropQueueQuery, DropTableQuery,
55 DropTimeSeriesQuery, DropTreeQuery, DropVectorQuery, EventsBackfillQuery, ExplainAlterQuery,
56 ExplainFormat, FieldRef, Filter, ForkStoreQuery, FusionStrategy, GraphCommand, HybridQuery,
57 IndexMethod, InsertEntityType, InsertQuery, JoinQuery, JoinType, OrderByClause,
58 ProbabilisticCommand, Projection, PromoteForkQuery, QueryExpr, QueueCommand, QueueSelectQuery,
59 QueueSide, SearchCommand, TableQuery, TreeCommand, TruncateQuery, UpdateQuery, VectorQuery,
60 VectorSource,
61};
62use reddb_rql::modes::{detect_mode, parse_multi, QueryMode};
63use reddb_types::Value;
64
65static TIMESERIES_TAG_INDEX_OBSERVED_POINTS: AtomicU64 = AtomicU64::new(0);
66
67pub fn reset_timeseries_tag_index_observability() {
68 TIMESERIES_TAG_INDEX_OBSERVED_POINTS.store(0, AtomicOrdering::Relaxed);
69}
70
71pub fn timeseries_tag_index_observed_points() -> u64 {
72 TIMESERIES_TAG_INDEX_OBSERVED_POINTS.load(AtomicOrdering::Relaxed)
73}
74
75pub(crate) fn observe_timeseries_tag_index_point() {
76 TIMESERIES_TAG_INDEX_OBSERVED_POINTS.fetch_add(1, AtomicOrdering::Relaxed);
77}
78
79#[derive(Debug, Clone)]
80pub struct ConnectionPoolConfig {
81 pub max_connections: usize,
82 pub max_idle: usize,
83}
84
85impl Default for ConnectionPoolConfig {
86 fn default() -> Self {
87 Self {
88 max_connections: 64,
89 max_idle: 16,
90 }
91 }
92}
93
94#[derive(Debug, Clone, Copy, PartialEq, Eq)]
95pub struct ScanCursor {
96 pub offset: usize,
97}
98
99#[derive(Debug, Clone)]
100pub struct ScanPage {
101 pub collection: String,
102 pub items: Vec<UnifiedEntity>,
103 pub next: Option<ScanCursor>,
104 pub total: usize,
105}
106
107#[derive(Debug, Clone)]
108pub struct SystemInfo {
109 pub pid: u32,
110 pub cpu_cores: usize,
111 pub total_memory_bytes: u64,
112 pub available_memory_bytes: u64,
113 pub os: String,
114 pub arch: String,
115 pub hostname: String,
116}
117
118impl SystemInfo {
119 pub fn should_parallelize() -> bool {
122 reddb_engine::execution::should_parallelize()
123 }
124
125 pub fn collect() -> Self {
126 Self {
127 pid: std::process::id(),
128 cpu_cores: std::thread::available_parallelism()
129 .map(|p| p.get())
130 .unwrap_or(1),
131 total_memory_bytes: Self::read_total_memory(),
132 available_memory_bytes: Self::read_available_memory(),
133 os: std::env::consts::OS.to_string(),
134 arch: std::env::consts::ARCH.to_string(),
135 hostname: std::env::var("HOSTNAME")
136 .or_else(|_| std::env::var("COMPUTERNAME"))
137 .unwrap_or_else(|_| "unknown".to_string()),
138 }
139 }
140
141 #[cfg(target_os = "linux")]
142 fn read_total_memory() -> u64 {
143 std::fs::read_to_string("/proc/meminfo")
144 .ok()
145 .and_then(|s| {
146 s.lines()
147 .find(|l| l.starts_with("MemTotal:"))
148 .and_then(|l| {
149 l.split_whitespace()
150 .nth(1)
151 .and_then(|v| v.parse::<u64>().ok())
152 })
153 .map(|kb| kb * 1024)
154 })
155 .unwrap_or(0)
156 }
157
158 #[cfg(target_os = "linux")]
159 fn read_available_memory() -> u64 {
160 std::fs::read_to_string("/proc/meminfo")
161 .ok()
162 .and_then(|s| {
163 s.lines()
164 .find(|l| l.starts_with("MemAvailable:"))
165 .and_then(|l| {
166 l.split_whitespace()
167 .nth(1)
168 .and_then(|v| v.parse::<u64>().ok())
169 })
170 .map(|kb| kb * 1024)
171 })
172 .unwrap_or(0)
173 }
174
175 #[cfg(not(target_os = "linux"))]
176 fn read_total_memory() -> u64 {
177 0
178 }
179
180 #[cfg(not(target_os = "linux"))]
181 fn read_available_memory() -> u64 {
182 0
183 }
184}
185
186#[derive(Debug, Clone)]
187pub struct RuntimeStats {
188 pub active_connections: usize,
189 pub idle_connections: usize,
190 pub total_checkouts: u64,
191 pub paged_mode: bool,
192 pub started_at_unix_ms: u128,
193 pub store: StoreStats,
194 pub system: SystemInfo,
195 pub result_blob_cache: crate::storage::cache::BlobCacheStats,
196 pub kv: KvStats,
197 pub metrics_ingest: MetricsIngestStats,
198}
199
200#[derive(Debug, Clone, PartialEq, Eq)]
201pub struct MetricsTenantActivityStats {
202 pub tenant: String,
203 pub namespace: String,
204 pub operation: String,
205 pub count: u64,
206}
207
208#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
209pub struct MetricsIngestStats {
210 pub samples_accepted: u64,
211 pub series_accepted: u64,
212 pub samples_rejected: u64,
213 pub series_rejected: u64,
214 pub series_rejected_cardinality_budget: u64,
215}
216
217#[derive(Debug, Default)]
218pub(crate) struct MetricsIngestCounters {
219 samples_accepted: AtomicU64,
220 series_accepted: AtomicU64,
221 samples_rejected: AtomicU64,
222 series_rejected: AtomicU64,
223 series_rejected_cardinality_budget: AtomicU64,
224}
225
226impl MetricsIngestCounters {
227 pub(crate) fn record(
228 &self,
229 accepted_samples: u64,
230 accepted_series: u64,
231 rejected_samples: u64,
232 rejected_series: u64,
233 ) {
234 self.samples_accepted
235 .fetch_add(accepted_samples, AtomicOrdering::Relaxed);
236 self.series_accepted
237 .fetch_add(accepted_series, AtomicOrdering::Relaxed);
238 self.samples_rejected
239 .fetch_add(rejected_samples, AtomicOrdering::Relaxed);
240 self.series_rejected
241 .fetch_add(rejected_series, AtomicOrdering::Relaxed);
242 }
243
244 pub(crate) fn record_cardinality_budget_rejections(&self, rejected_series: u64) {
245 self.series_rejected_cardinality_budget
246 .fetch_add(rejected_series, AtomicOrdering::Relaxed);
247 }
248
249 pub(crate) fn snapshot(&self) -> MetricsIngestStats {
250 MetricsIngestStats {
251 samples_accepted: self.samples_accepted.load(AtomicOrdering::Relaxed),
252 series_accepted: self.series_accepted.load(AtomicOrdering::Relaxed),
253 samples_rejected: self.samples_rejected.load(AtomicOrdering::Relaxed),
254 series_rejected: self.series_rejected.load(AtomicOrdering::Relaxed),
255 series_rejected_cardinality_budget: self
256 .series_rejected_cardinality_budget
257 .load(AtomicOrdering::Relaxed),
258 }
259 }
260}
261
262#[derive(Debug, Default)]
263pub(crate) struct MetricsTenantActivityCounters {
264 inner: Mutex<BTreeMap<(String, String, String), u64>>,
265}
266
267impl MetricsTenantActivityCounters {
268 pub(crate) fn record(&self, tenant: &str, namespace: &str, operation: &str) {
269 let mut inner = self
270 .inner
271 .lock()
272 .unwrap_or_else(|poison| poison.into_inner());
273 let key = (
274 tenant.to_string(),
275 namespace.to_string(),
276 operation.to_string(),
277 );
278 *inner.entry(key).or_insert(0) += 1;
279 }
280
281 pub(crate) fn snapshot(&self) -> Vec<MetricsTenantActivityStats> {
282 let inner = self
283 .inner
284 .lock()
285 .unwrap_or_else(|poison| poison.into_inner());
286 inner
287 .iter()
288 .map(
289 |((tenant, namespace, operation), count)| MetricsTenantActivityStats {
290 tenant: tenant.clone(),
291 namespace: namespace.clone(),
292 operation: operation.clone(),
293 count: *count,
294 },
295 )
296 .collect()
297 }
298}
299
300#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
301pub struct KvStats {
302 pub puts: u64,
303 pub gets: u64,
304 pub deletes: u64,
305 pub incrs: u64,
306 pub cas_success: u64,
307 pub cas_conflict: u64,
308 pub watch_streams_active: u64,
309 pub watch_events_emitted: u64,
310 pub watch_drops: u64,
311}
312
313#[derive(Debug, Default)]
314pub(crate) struct KvStatsCounters {
315 puts: AtomicU64,
316 gets: AtomicU64,
317 deletes: AtomicU64,
318 incrs: AtomicU64,
319 cas_success: AtomicU64,
320 cas_conflict: AtomicU64,
321 watch_streams_active: AtomicU64,
322 watch_events_emitted: AtomicU64,
323 watch_drops: AtomicU64,
324}
325
326#[derive(Debug, Default)]
327pub(crate) struct KvTagIndex {
328 tag_to_entries: parking_lot::RwLock<HashMap<(String, String), HashMap<String, EntityId>>>,
329 key_to_tags: parking_lot::RwLock<HashMap<(String, String), BTreeSet<String>>>,
330}
331
332impl KvTagIndex {
333 pub(crate) fn replace(&self, collection: &str, key: &str, id: EntityId, tags: &[String]) {
334 let entry_key = (collection.to_string(), key.to_string());
335 let new_tags: BTreeSet<String> = tags
336 .iter()
337 .map(|tag| tag.trim())
338 .filter(|tag| !tag.is_empty())
339 .map(ToOwned::to_owned)
340 .collect();
341
342 let old_tags = {
343 let mut key_to_tags = self.key_to_tags.write();
344 if new_tags.is_empty() {
345 key_to_tags.remove(&entry_key)
346 } else {
347 key_to_tags.insert(entry_key.clone(), new_tags.clone())
348 }
349 };
350
351 let mut tag_to_entries = self.tag_to_entries.write();
352 if let Some(old_tags) = old_tags {
353 for tag in old_tags {
354 let scoped = (collection.to_string(), tag);
355 let remove_scoped = if let Some(entries) = tag_to_entries.get_mut(&scoped) {
356 entries.remove(key);
357 entries.is_empty()
358 } else {
359 false
360 };
361 if remove_scoped {
362 tag_to_entries.remove(&scoped);
363 }
364 }
365 }
366
367 for tag in new_tags {
368 tag_to_entries
369 .entry((collection.to_string(), tag))
370 .or_default()
371 .insert(key.to_string(), id);
372 }
373 }
374
375 pub(crate) fn remove(&self, collection: &str, key: &str) {
376 let entry_key = (collection.to_string(), key.to_string());
377 let old_tags = self.key_to_tags.write().remove(&entry_key);
378 let Some(old_tags) = old_tags else {
379 return;
380 };
381
382 let mut tag_to_entries = self.tag_to_entries.write();
383 for tag in old_tags {
384 let scoped = (collection.to_string(), tag);
385 let remove_scoped = if let Some(entries) = tag_to_entries.get_mut(&scoped) {
386 entries.remove(key);
387 entries.is_empty()
388 } else {
389 false
390 };
391 if remove_scoped {
392 tag_to_entries.remove(&scoped);
393 }
394 }
395 }
396
397 pub(crate) fn entries_for_tags(
398 &self,
399 collection: &str,
400 tags: &[String],
401 ) -> Vec<(String, EntityId)> {
402 if tags.is_empty() {
403 return Vec::new();
404 }
405
406 let tag_to_entries = self.tag_to_entries.read();
407 let mut out: HashMap<String, EntityId> = HashMap::new();
408 for tag in tags {
409 let scoped = (collection.to_string(), tag.trim().to_string());
410 if let Some(entries) = tag_to_entries.get(&scoped) {
411 for (key, id) in entries {
412 out.entry(key.clone()).or_insert(*id);
413 }
414 }
415 }
416 out.into_iter().collect()
417 }
418
419 pub(crate) fn tags_for_key(&self, collection: &str, key: &str) -> Vec<String> {
420 self.key_to_tags
421 .read()
422 .get(&(collection.to_string(), key.to_string()))
423 .map(|tags| tags.iter().cloned().collect())
424 .unwrap_or_default()
425 }
426}
427
428impl KvStatsCounters {
429 pub(crate) fn snapshot(&self) -> KvStats {
430 KvStats {
431 puts: self.puts.load(AtomicOrdering::Relaxed),
432 gets: self.gets.load(AtomicOrdering::Relaxed),
433 deletes: self.deletes.load(AtomicOrdering::Relaxed),
434 incrs: self.incrs.load(AtomicOrdering::Relaxed),
435 cas_success: self.cas_success.load(AtomicOrdering::Relaxed),
436 cas_conflict: self.cas_conflict.load(AtomicOrdering::Relaxed),
437 watch_streams_active: self.watch_streams_active.load(AtomicOrdering::Relaxed),
438 watch_events_emitted: self.watch_events_emitted.load(AtomicOrdering::Relaxed),
439 watch_drops: self.watch_drops.load(AtomicOrdering::Relaxed),
440 }
441 }
442
443 pub(crate) fn incr_puts(&self) {
444 self.puts.fetch_add(1, AtomicOrdering::Relaxed);
445 }
446
447 pub(crate) fn incr_gets(&self) {
448 self.gets.fetch_add(1, AtomicOrdering::Relaxed);
449 }
450
451 pub(crate) fn incr_deletes(&self) {
452 self.deletes.fetch_add(1, AtomicOrdering::Relaxed);
453 }
454
455 pub(crate) fn incr_incrs(&self) {
456 self.incrs.fetch_add(1, AtomicOrdering::Relaxed);
457 }
458
459 pub(crate) fn incr_cas_success(&self) {
460 self.cas_success.fetch_add(1, AtomicOrdering::Relaxed);
461 }
462
463 pub(crate) fn incr_cas_conflict(&self) {
464 self.cas_conflict.fetch_add(1, AtomicOrdering::Relaxed);
465 }
466
467 pub(crate) fn incr_watch_streams_active(&self) {
468 self.watch_streams_active
469 .fetch_add(1, AtomicOrdering::Relaxed);
470 }
471
472 pub(crate) fn decr_watch_streams_active(&self) {
473 self.watch_streams_active
474 .fetch_sub(1, AtomicOrdering::Relaxed);
475 }
476
477 pub(crate) fn incr_watch_events_emitted(&self) {
478 self.watch_events_emitted
479 .fetch_add(1, AtomicOrdering::Relaxed);
480 }
481
482 pub(crate) fn add_watch_drops(&self, count: u64) {
483 self.watch_drops.fetch_add(count, AtomicOrdering::Relaxed);
484 }
485}
486
487#[derive(Debug, Clone)]
488pub struct RuntimeQueryResult {
489 pub query: String,
490 pub mode: QueryMode,
491 pub statement: &'static str,
492 pub engine: &'static str,
493 pub result: UnifiedResult,
494 pub affected_rows: u64,
495 pub statement_type: &'static str,
497 pub bookmark: Option<String>,
498 pub notice: Option<String>,
499}
500
501impl RuntimeQueryResult {
502 pub(crate) fn is_materialized_read(&self) -> bool {
505 self.statement_type == "select"
506 && matches!(
507 self.statement,
508 "table" | "graph" | "join" | "path" | "vector" | "hybrid" | "select"
509 )
510 }
511
512 pub fn dml_result(
514 query: String,
515 affected: u64,
516 statement_type: &'static str,
517 engine: &'static str,
518 ) -> Self {
519 Self {
520 query,
521 mode: QueryMode::Sql,
522 statement: statement_type,
523 engine,
524 result: UnifiedResult::empty(),
525 affected_rows: affected,
526 statement_type,
527 bookmark: None,
528 notice: None,
529 }
530 }
531
532 pub fn ok_message(query: String, message: &str, statement_type: &'static str) -> Self {
534 let mut result = UnifiedResult::empty();
535 let mut record = UnifiedRecord::new();
536 record.set("message", Value::text(message.to_string()));
537 result.push(record);
538 result.columns = vec!["message".to_string()];
539
540 Self {
541 query,
542 mode: QueryMode::Sql,
543 statement: statement_type,
544 engine: "runtime-ddl",
545 result,
546 affected_rows: 0,
547 statement_type,
548 bookmark: None,
549 notice: None,
550 }
551 }
552
553 pub fn ok_records(
557 query: String,
558 columns: Vec<String>,
559 rows: Vec<Vec<(String, Value)>>,
560 statement_type: &'static str,
561 ) -> Self {
562 let mut result = UnifiedResult::empty();
563 for row in rows {
564 let mut record = UnifiedRecord::new();
565 for (k, v) in row {
566 record.set(&k, v);
567 }
568 result.push(record);
569 }
570 result.columns = columns;
571
572 Self {
573 query,
574 mode: QueryMode::Sql,
575 statement: statement_type,
576 engine: "runtime-meta",
577 result,
578 affected_rows: 0,
579 statement_type,
580 bookmark: None,
581 notice: None,
582 }
583 }
584
585 pub fn bookmark_token(&self) -> Option<&str> {
586 self.bookmark.as_deref()
587 }
588}
589
590#[derive(Debug, Clone)]
591pub struct RuntimeQueryExplain {
592 pub query: String,
593 pub mode: QueryMode,
594 pub statement: &'static str,
595 pub is_universal: bool,
596 pub plan_cost: crate::storage::query::planner::PlanCost,
597 pub estimated_rows: f64,
598 pub estimated_selectivity: f64,
599 pub estimated_confidence: f64,
600 pub passes_applied: Vec<String>,
601 pub logical_plan: CanonicalLogicalPlan,
602 pub cte_materializations: Vec<String>,
609}
610
611#[derive(Debug, Clone)]
612pub struct RuntimeIvfMatch {
613 pub entity_id: u64,
614 pub distance: f32,
615 pub entity: Option<UnifiedEntity>,
616}
617
618#[derive(Debug, Clone)]
619pub struct RuntimeIvfSearchResult {
620 pub collection: String,
621 pub k: usize,
622 pub n_lists: usize,
623 pub n_probes: usize,
624 pub stats: IvfStats,
625 pub matches: Vec<RuntimeIvfMatch>,
626}
627
628#[derive(Debug, Clone, Copy, PartialEq, Eq)]
629pub enum RuntimeGraphDirection {
630 Outgoing,
631 Incoming,
632 Both,
633}
634
635#[derive(Debug, Clone, Copy, PartialEq, Eq)]
636pub enum RuntimeGraphTraversalStrategy {
637 Bfs,
638 Dfs,
639}
640
641#[derive(Debug, Clone, Copy, PartialEq, Eq)]
642pub enum RuntimeGraphPathAlgorithm {
643 Bfs,
644 Dijkstra,
645 AStar,
646 BellmanFord,
647}
648
649#[derive(Debug, Clone)]
650pub struct RuntimeGraphNode {
651 pub id: String,
652 pub label: String,
653 pub node_type: String,
654 pub out_edge_count: u32,
655 pub in_edge_count: u32,
656}
657
658#[derive(Debug, Clone)]
659pub struct RuntimeGraphEdge {
660 pub source: String,
661 pub target: String,
662 pub edge_type: String,
663 pub weight: f32,
664}
665
666#[derive(Debug, Clone)]
667pub struct RuntimeGraphVisit {
668 pub depth: usize,
669 pub node: RuntimeGraphNode,
670}
671
672#[derive(Debug, Clone)]
673pub struct RuntimeGraphNeighborhoodResult {
674 pub source: String,
675 pub direction: RuntimeGraphDirection,
676 pub max_depth: usize,
677 pub nodes: Vec<RuntimeGraphVisit>,
678 pub edges: Vec<RuntimeGraphEdge>,
679}
680
681#[derive(Debug, Clone)]
682pub struct RuntimeGraphTraversalResult {
683 pub source: String,
684 pub direction: RuntimeGraphDirection,
685 pub strategy: RuntimeGraphTraversalStrategy,
686 pub max_depth: usize,
687 pub visits: Vec<RuntimeGraphVisit>,
688 pub edges: Vec<RuntimeGraphEdge>,
689}
690
691#[derive(Debug, Clone)]
692pub struct RuntimeGraphPath {
693 pub hop_count: usize,
694 pub total_weight: f64,
695 pub nodes: Vec<RuntimeGraphNode>,
696 pub edges: Vec<RuntimeGraphEdge>,
697}
698
699#[derive(Debug, Clone)]
700pub struct RuntimeGraphPathResult {
701 pub source: String,
702 pub target: String,
703 pub direction: RuntimeGraphDirection,
704 pub algorithm: RuntimeGraphPathAlgorithm,
705 pub nodes_visited: usize,
706 pub negative_cycle_detected: Option<bool>,
707 pub path: Option<RuntimeGraphPath>,
708}
709
710#[derive(Debug, Clone, Copy, PartialEq, Eq)]
711pub enum RuntimeGraphComponentsMode {
712 Connected,
713 Weak,
714 Strong,
715}
716
717#[derive(Debug, Clone, Copy, PartialEq, Eq)]
718pub enum RuntimeGraphCentralityAlgorithm {
719 Degree,
720 Closeness,
721 Betweenness,
722 Eigenvector,
723 PageRank,
724}
725
726#[derive(Debug, Clone, Copy, PartialEq, Eq)]
727pub enum RuntimeGraphCommunityAlgorithm {
728 LabelPropagation,
729 Louvain,
730}
731
732#[derive(Debug, Clone)]
733pub struct RuntimeGraphComponent {
734 pub id: String,
735 pub size: usize,
736 pub nodes: Vec<String>,
737}
738
739#[derive(Debug, Clone)]
740pub struct RuntimeGraphComponentsResult {
741 pub mode: RuntimeGraphComponentsMode,
742 pub count: usize,
743 pub components: Vec<RuntimeGraphComponent>,
744}
745
746#[derive(Debug, Clone)]
747pub struct RuntimeGraphCentralityScore {
748 pub node: RuntimeGraphNode,
749 pub score: f64,
750}
751
752#[derive(Debug, Clone)]
753pub struct RuntimeGraphDegreeScore {
754 pub node: RuntimeGraphNode,
755 pub in_degree: usize,
756 pub out_degree: usize,
757 pub total_degree: usize,
758}
759
760#[derive(Debug, Clone)]
761pub struct RuntimeGraphCentralityResult {
762 pub algorithm: RuntimeGraphCentralityAlgorithm,
763 pub normalized: Option<bool>,
764 pub iterations: Option<usize>,
765 pub converged: Option<bool>,
766 pub scores: Vec<RuntimeGraphCentralityScore>,
767 pub degree_scores: Vec<RuntimeGraphDegreeScore>,
768}
769
770#[derive(Debug, Clone)]
771pub struct RuntimeGraphCommunity {
772 pub id: String,
773 pub size: usize,
774 pub nodes: Vec<String>,
775}
776
777#[derive(Debug, Clone)]
778pub struct RuntimeGraphCommunityResult {
779 pub algorithm: RuntimeGraphCommunityAlgorithm,
780 pub count: usize,
781 pub iterations: Option<usize>,
782 pub converged: Option<bool>,
783 pub modularity: Option<f64>,
784 pub passes: Option<usize>,
785 pub communities: Vec<RuntimeGraphCommunity>,
786}
787
788#[derive(Debug, Clone)]
789pub struct RuntimeGraphClusteringResult {
790 pub global: f64,
791 pub local: Vec<RuntimeGraphCentralityScore>,
792 pub triangle_count: Option<usize>,
793}
794
795#[derive(Debug, Clone)]
796pub struct RuntimeGraphHitsResult {
797 pub iterations: usize,
798 pub converged: bool,
799 pub hubs: Vec<RuntimeGraphCentralityScore>,
800 pub authorities: Vec<RuntimeGraphCentralityScore>,
801}
802
803#[derive(Debug, Clone)]
804pub struct RuntimeGraphCyclesResult {
805 pub limit_reached: bool,
806 pub cycles: Vec<RuntimeGraphPath>,
807}
808
809#[derive(Debug, Clone)]
810pub struct RuntimeGraphTopologicalSortResult {
811 pub acyclic: bool,
812 pub ordered_nodes: Vec<RuntimeGraphNode>,
813}
814
815#[derive(Debug, Clone)]
816pub struct RuntimeGraphPropertiesResult {
817 pub node_count: usize,
818 pub edge_count: usize,
819 pub self_loop_count: usize,
820 pub negative_edge_count: usize,
821 pub connected_component_count: usize,
822 pub weak_component_count: usize,
823 pub strong_component_count: usize,
824 pub is_empty: bool,
825 pub is_connected: bool,
826 pub is_weakly_connected: bool,
827 pub is_strongly_connected: bool,
828 pub is_complete: bool,
829 pub is_complete_directed: bool,
830 pub is_cyclic: bool,
831 pub is_circular: bool,
832 pub is_acyclic: bool,
833 pub is_tree: bool,
834 pub density: f64,
835 pub density_directed: f64,
836}
837
838#[derive(Debug, Clone)]
843pub struct ContextSearchResult {
844 pub query: String,
845 pub tables: Vec<ContextEntity>,
846 pub graph: ContextGraphResult,
847 pub vectors: Vec<ContextEntity>,
848 pub documents: Vec<ContextEntity>,
849 pub key_values: Vec<ContextEntity>,
850 pub connections: Vec<ContextConnection>,
851 pub summary: ContextSummary,
852}
853
854#[derive(Debug, Clone)]
855pub struct ContextEntity {
856 pub entity: UnifiedEntity,
857 pub score: f32,
858 pub discovery: DiscoveryMethod,
859 pub collection: String,
860}
861
862#[derive(Debug, Clone)]
863pub enum DiscoveryMethod {
864 Indexed {
865 field: String,
866 },
867 GlobalScan,
868 CrossReference {
869 source_id: u64,
870 ref_type: String,
871 },
872 GraphTraversal {
873 source_id: u64,
874 edge_type: String,
875 depth: usize,
876 },
877 VectorQuery {
878 similarity: f32,
879 },
880}
881
882#[derive(Debug, Clone)]
883pub struct ContextGraphResult {
884 pub nodes: Vec<ContextEntity>,
885 pub edges: Vec<ContextEntity>,
886}
887
888#[derive(Debug, Clone)]
889pub struct ContextConnection {
890 pub from_id: u64,
891 pub to_id: u64,
892 pub connection_type: ContextConnectionType,
893 pub weight: f32,
894}
895
896#[derive(Debug, Clone)]
897pub enum ContextConnectionType {
898 CrossRef(String),
899 GraphEdge(String),
900 VectorSimilarity(f32),
901}
902
903#[derive(Debug, Clone)]
904pub struct ContextSummary {
905 pub total_entities: usize,
906 pub direct_matches: usize,
907 pub expanded_via_graph: usize,
908 pub expanded_via_cross_refs: usize,
909 pub expanded_via_vector_query: usize,
910 pub collections_searched: usize,
911 pub execution_time_us: u64,
912 pub tiers_used: Vec<String>,
913 pub entities_reindexed: usize,
914}
915
916struct PoolState {
917 next_id: u64,
918 active: usize,
919 pooled_active: usize,
920 idle: Vec<u64>,
921 total_checkouts: u64,
922}
923
924impl Default for PoolState {
925 fn default() -> Self {
926 Self {
927 next_id: 1,
928 active: 0,
929 pooled_active: 0,
930 idle: Vec::new(),
931 total_checkouts: 0,
932 }
933 }
934}
935
936#[derive(Debug, Clone)]
937struct RuntimeResultCacheEntry {
938 result: RuntimeQueryResult,
939 cached_at: std::time::Instant,
940 scopes: HashSet<String>,
941}
942
943pub const METRIC_CACHE_SHADOW_DIVERGENCE_TOTAL: &str = "cache_shadow_divergence_total";
944pub const METRIC_RESULT_CACHE_HIT_TOTAL: &str = "result_cache_hit_total";
949pub const METRIC_RESULT_CACHE_MISS_TOTAL: &str = "result_cache_miss_total";
950pub const METRIC_RESULT_CACHE_EVICT_TOTAL: &str = "result_cache_evict_total";
951pub(crate) const ASK_ANSWER_CACHE_NAMESPACE: &str = "runtime.ask_answer_cache";
952const RMW_LOCK_SHARDS: usize = 64;
953
954type RmwLockShard = parking_lot::Mutex<HashMap<String, std::sync::Weak<RmwRowLock>>>;
955
956struct RmwLockTable {
957 shards: Vec<Arc<RmwLockShard>>,
958}
959
960struct RmwRowLock {
961 mutex: Arc<parking_lot::Mutex<()>>,
962 shard: std::sync::Weak<RmwLockShard>,
963 key: String,
964}
965
966struct OwnedRmwRowLockGuard {
967 _guard: parking_lot::ArcMutexGuard<parking_lot::RawMutex, ()>,
969 _owner: Arc<RmwRowLock>,
970}
971
972impl RmwRowLock {
973 fn lock(&self) -> parking_lot::MutexGuard<'_, ()> {
974 self.mutex.lock()
975 }
976
977 fn try_lock(&self) -> Option<parking_lot::MutexGuard<'_, ()>> {
978 self.mutex.try_lock()
979 }
980
981 fn lock_owned(self: Arc<Self>) -> OwnedRmwRowLockGuard {
982 let guard = self.mutex.lock_arc();
983 OwnedRmwRowLockGuard {
984 _guard: guard,
985 _owner: self,
986 }
987 }
988}
989
990impl Drop for RmwRowLock {
991 fn drop(&mut self) {
992 let Some(shard) = self.shard.upgrade() else {
993 return;
994 };
995 let mut shard = shard.lock();
996 if shard
999 .get(&self.key)
1000 .is_some_and(|entry| std::ptr::eq(entry.as_ptr(), self))
1001 {
1002 shard.remove(&self.key);
1003 }
1004 }
1005}
1006
1007impl RmwLockTable {
1008 fn row_key(logical_id: crate::storage::EntityId) -> String {
1009 format!("row:{}", logical_id.raw())
1010 }
1011
1012 fn new() -> Self {
1013 let shards = (0..RMW_LOCK_SHARDS)
1014 .map(|_| Arc::new(parking_lot::Mutex::new(HashMap::new())))
1015 .collect();
1016 Self { shards }
1017 }
1018
1019 fn lock_for(&self, collection: &str, key: &str) -> Arc<RmwRowLock> {
1020 use std::hash::{Hash, Hasher};
1021 let mut hasher = std::collections::hash_map::DefaultHasher::new();
1022 collection.hash(&mut hasher);
1023 key.hash(&mut hasher);
1024 let shard_idx = (hasher.finish() as usize) % self.shards.len();
1025 let map_key = format!("{collection}\u{1f}{key}");
1026 let mut shard = self.shards[shard_idx].lock();
1027 if let Some(lock) = shard.get(&map_key).and_then(std::sync::Weak::upgrade) {
1028 return lock;
1029 }
1030 let lock = Arc::new(RmwRowLock {
1031 mutex: Arc::new(parking_lot::Mutex::new(())),
1032 shard: Arc::downgrade(&self.shards[shard_idx]),
1033 key: map_key.clone(),
1034 });
1035 shard.insert(map_key, Arc::downgrade(&lock));
1036 lock
1037 }
1038}
1039
1040#[derive(Debug, Default)]
1041pub(crate) struct CheckpointProjectionStats {
1042 last_materialized_lsn: std::sync::atomic::AtomicU64,
1043 checkpoints_completed: std::sync::atomic::AtomicU64,
1044 last_checkpoint_duration_ms: std::sync::atomic::AtomicU64,
1045}
1046
1047impl CheckpointProjectionStats {
1048 pub(crate) fn record_checkpoint(&self, lsn: u64, duration_ms: u64) {
1049 use std::sync::atomic::Ordering;
1050
1051 self.last_materialized_lsn.store(lsn, Ordering::Relaxed);
1052 self.last_checkpoint_duration_ms
1053 .store(duration_ms, Ordering::Relaxed);
1054 self.checkpoints_completed.fetch_add(1, Ordering::Relaxed);
1055 }
1056
1057 pub(crate) fn snapshot(&self, current_lsn: u64) -> CheckpointProjectionStatsSnapshot {
1058 use std::sync::atomic::Ordering;
1059
1060 let last_materialized_lsn = self.last_materialized_lsn.load(Ordering::Relaxed);
1061 CheckpointProjectionStatsSnapshot {
1062 current_lsn,
1063 last_materialized_lsn,
1064 projection_lag: current_lsn.saturating_sub(last_materialized_lsn),
1065 checkpoints_completed: self.checkpoints_completed.load(Ordering::Relaxed),
1066 last_checkpoint_duration_ms: self.last_checkpoint_duration_ms.load(Ordering::Relaxed),
1067 }
1068 }
1069}
1070
1071#[derive(Debug, Clone, Copy)]
1072pub(crate) struct CheckpointProjectionStatsSnapshot {
1073 pub(crate) current_lsn: u64,
1074 pub(crate) last_materialized_lsn: u64,
1075 pub(crate) projection_lag: u64,
1076 pub(crate) checkpoints_completed: u64,
1077 pub(crate) last_checkpoint_duration_ms: u64,
1078}
1079
1080#[derive(Debug, Clone)]
1081pub(crate) struct ScrubStatsSnapshot {
1082 pub(crate) last_run_unix_ms: u64,
1083 pub(crate) last_findings_count: u64,
1084 pub(crate) background_status: String,
1085 pub(crate) background_verified_objects: u64,
1086 pub(crate) background_total_objects: u64,
1087 pub(crate) verified: reddb_file::StorageScrubVerifiedCounters,
1088}
1089
1090#[derive(Debug, Clone)]
1091pub(crate) struct ScrubRuntimeState {
1092 pub(crate) last_run_unix_ms: u64,
1093 pub(crate) last_findings_count: u64,
1094 pub(crate) background_cursor: usize,
1095 pub(crate) background_status: String,
1096 pub(crate) background_verified_objects: u64,
1097 pub(crate) background_total_objects: u64,
1098 pub(crate) verified: reddb_file::StorageScrubVerifiedCounters,
1099}
1100
1101impl Default for ScrubRuntimeState {
1102 fn default() -> Self {
1103 Self {
1104 last_run_unix_ms: 0,
1105 last_findings_count: 0,
1106 background_cursor: 0,
1107 background_status: "idle".to_string(),
1108 background_verified_objects: 0,
1109 background_total_objects: 0,
1110 verified: reddb_file::StorageScrubVerifiedCounters::default(),
1111 }
1112 }
1113}
1114
1115impl ScrubRuntimeState {
1116 pub(crate) fn snapshot(&self) -> ScrubStatsSnapshot {
1117 ScrubStatsSnapshot {
1118 last_run_unix_ms: self.last_run_unix_ms,
1119 last_findings_count: self.last_findings_count,
1120 background_status: self.background_status.clone(),
1121 background_verified_objects: self.background_verified_objects,
1122 background_total_objects: self.background_total_objects,
1123 verified: self.verified.clone(),
1124 }
1125 }
1126}
1127
1128struct RuntimeInner {
1129 functions: parking_lot::RwLock<function_catalog::FunctionCatalog>,
1130 db: Arc<RedDB>,
1131 layout: PhysicalLayout,
1132 embedded_single_file: bool,
1133 pub(crate) memory_budget: crate::storage::memory_budget::MemoryBudget,
1136 pub(crate) memory_accounting: Arc<crate::storage::memory_pools::MemoryAccounting>,
1139 memory_reservations: parking_lot::Mutex<memory_admission::MemoryReservations>,
1140 mvcc_maintenance: parking_lot::Mutex<mvcc_maintenance::MvccMaintenance>,
1141 indices: IndexCatalog,
1142 pool_config: ConnectionPoolConfig,
1143 pool: Mutex<PoolState>,
1144 started_at_unix_ms: u128,
1145 probabilistic: probabilistic_store::ProbabilisticStore,
1146 index_store: index_store::IndexStore,
1147 cdc: crate::replication::cdc::CdcBuffer,
1148 pub(crate) checkpoint_projection_stats: CheckpointProjectionStats,
1149 pub(crate) scrub_state: parking_lot::Mutex<ScrubRuntimeState>,
1150 pub(crate) checkpoint_columnar_emission_budget_chunks: usize,
1151 pub(crate) columnar_projection_size_floor_rows: usize,
1152 backup_scheduler: crate::replication::scheduler::BackupScheduler,
1153 query_cache: parking_lot::RwLock<crate::storage::query::planner::cache::PlanCache>,
1154 result_cache: parking_lot::RwLock<(
1155 HashMap<String, RuntimeResultCacheEntry>,
1156 std::collections::VecDeque<String>,
1157 )>,
1158 result_blob_cache: crate::storage::cache::BlobCache,
1159 result_blob_entries: parking_lot::RwLock<(
1160 HashMap<String, RuntimeResultCacheEntry>,
1161 std::collections::VecDeque<String>,
1162 )>,
1163 ask_answer_cache_entries:
1164 parking_lot::RwLock<(HashSet<String>, std::collections::VecDeque<String>)>,
1165 result_cache_shadow_divergences: std::sync::atomic::AtomicU64,
1166 result_cache_hits: std::sync::atomic::AtomicU64,
1169 result_cache_misses: std::sync::atomic::AtomicU64,
1170 result_cache_evictions: std::sync::atomic::AtomicU64,
1171 ask_daily_spend:
1172 parking_lot::RwLock<HashMap<String, crate::runtime::ai::cost_guard::DailyState>>,
1173 queue_message_locks: parking_lot::RwLock<HashMap<String, Arc<parking_lot::Mutex<()>>>>,
1176 rmw_locks: RmwLockTable,
1180 planner_dirty_tables: parking_lot::RwLock<HashSet<String>>,
1181 ec_registry: Arc<crate::ec::config::EcRegistry>,
1182 config_registry: Arc<crate::auth::registry::ConfigRegistry>,
1183 ec_worker: crate::ec::worker::EcWorker,
1184 auth_store: parking_lot::RwLock<Option<Arc<crate::auth::store::AuthStore>>>,
1189 oauth_validator: parking_lot::RwLock<Option<Arc<crate::auth::oauth::OAuthValidator>>>,
1196 browser_token_authority:
1203 parking_lot::RwLock<Option<Arc<crate::auth::browser_token::BrowserTokenAuthority>>>,
1204 views: parking_lot::RwLock<HashMap<String, Arc<reddb_rql::ast::CreateViewQuery>>>,
1215 materialized_views: parking_lot::RwLock<crate::storage::cache::result::MaterializedViewCache>,
1216 pub(crate) retention_sweeper:
1221 parking_lot::RwLock<crate::runtime::retention_sweeper::RetentionSweeperState>,
1222 transaction_state: crate::runtime::transaction_state::TransactionState,
1225 lock_manager: Arc<crate::runtime::lock_manager::LockManager>,
1232 env_config_overrides: HashMap<String, String>,
1238 rls_policies:
1245 parking_lot::RwLock<HashMap<(String, String), Arc<reddb_rql::ast::CreatePolicyQuery>>>,
1246 rls_enabled_tables: parking_lot::RwLock<HashSet<String>>,
1247 foreign_tables: Arc<crate::storage::fdw::ForeignTableRegistry>,
1255 pending_tombstones: parking_lot::RwLock<
1267 HashMap<
1268 u64,
1269 Vec<(
1270 String,
1271 crate::storage::unified::entity::EntityId,
1272 crate::storage::transaction::snapshot::Xid,
1273 crate::storage::transaction::snapshot::Xid,
1274 )>,
1275 >,
1276 >,
1277 pending_versioned_updates: parking_lot::RwLock<
1283 HashMap<
1284 u64,
1285 Vec<(
1286 String,
1287 crate::storage::unified::entity::EntityId,
1288 crate::storage::unified::entity::EntityId,
1289 crate::storage::transaction::snapshot::Xid,
1290 crate::storage::transaction::snapshot::Xid,
1291 )>,
1292 >,
1293 >,
1294 pending_queue_dedup: parking_lot::RwLock<HashMap<u64, Vec<(String, String, EntityId)>>>,
1300 pending_kv_watch_events:
1301 parking_lot::RwLock<HashMap<u64, Vec<(u64, crate::replication::cdc::KvWatchEvent)>>>,
1302 pending_vault_writes: parking_lot::RwLock<HashMap<u64, Vec<impl_kv::PendingVaultWrite>>>,
1303 pending_store_wal_actions:
1304 parking_lot::RwLock<HashMap<u64, crate::storage::unified::DeferredStoreWalActions>>,
1305 pending_claim_locks: parking_lot::RwLock<HashMap<(String, EntityId), u64>>,
1311 tenant_tables: parking_lot::RwLock<HashMap<String, String>>,
1320 ddl_epoch: std::sync::atomic::AtomicU64,
1326 write_gate: Arc<crate::runtime::write_gate::WriteGate>,
1337 lifecycle: crate::runtime::lifecycle::Lifecycle,
1343 resource_limits: crate::runtime::resource_limits::ResourceLimits,
1348 query_budget_slots: AtomicU64,
1349 audit_log: Arc<crate::runtime::audit_log::AuditLogger>,
1353 control_event_ledger:
1357 parking_lot::RwLock<Arc<dyn crate::runtime::control_events::ControlEventLedger>>,
1358 control_event_config: crate::runtime::control_events::ControlEventConfig,
1359 query_audit: Arc<crate::runtime::query_audit::QueryAuditStream>,
1363 lease_lifecycle: std::sync::OnceLock<Arc<crate::runtime::lease_lifecycle::LeaseLifecycle>>,
1370 replica_apply_metrics: Arc<crate::replication::logical::ReplicaApplyMetrics>,
1374 replica_link_metrics: Arc<crate::replication::reconnect::ReplicaLinkMetrics>,
1379 quota_bucket: crate::runtime::quota_bucket::QuotaBucket,
1382 schema_vocabulary: parking_lot::RwLock<crate::runtime::schema_vocabulary::SchemaVocabulary>,
1387 slow_query_logger: Arc<crate::telemetry::slow_query_logger::SlowQueryLogger>,
1393 slow_query_store: Arc<crate::telemetry::slow_query_store::SlowQueryStore>,
1398 kv_stats: KvStatsCounters,
1401 metrics_ingest_stats: MetricsIngestCounters,
1402 metrics_tenant_activity_stats: MetricsTenantActivityCounters,
1403 claim_telemetry: std::sync::Arc<claim_telemetry::ClaimTelemetryCounters>,
1406 queue_telemetry: std::sync::Arc<queue_telemetry::QueueTelemetryCounters>,
1410 query_latency_telemetry: std::sync::Arc<query_latency_telemetry::QueryLatencyTelemetry>,
1415 occupancy_sampler: std::sync::Arc<occupancy_sampler::OccupancySampler>,
1420 node_load_telemetry: std::sync::Arc<node_load_telemetry::NodeLoadTelemetry>,
1425 queue_presence: std::sync::Arc<crate::storage::queue::presence::ConsumerPresenceRegistry>,
1432 vector_introspection:
1441 std::sync::Arc<crate::storage::vector::introspection::VectorIntrospectionRegistry>,
1442 queue_wait_registry: std::sync::Arc<queue_wait_registry::QueueWaitRegistry>,
1446 pending_queue_wakes: parking_lot::RwLock<HashMap<u64, Vec<(String, String)>>>,
1452 kv_tag_index: KvTagIndex,
1454 chain_tip_cache:
1460 parking_lot::Mutex<HashMap<String, crate::runtime::blockchain_kind::ChainTipFull>>,
1461 chain_integrity_broken: parking_lot::Mutex<HashMap<String, bool>>,
1466 integrity_tombstones:
1473 parking_lot::Mutex<Vec<crate::runtime::integrity_tombstone::TombstoneRange>>,
1474 integrity_tombstones_state: std::sync::atomic::AtomicU8,
1475}
1476
1477#[derive(Clone)]
1478pub struct RedDBRuntime {
1479 background_tasks: Option<Arc<background_tasks::RuntimeBackgroundTasks>>,
1482 inner: Arc<RuntimeInner>,
1483}
1484
1485pub struct RuntimeConnection {
1486 id: u64,
1487 uses_pool_slot: bool,
1488 background_tasks: Option<Arc<background_tasks::RuntimeBackgroundTasks>>,
1489 inner: Arc<RuntimeInner>,
1490}
1491
1492pub struct CausalSession {
1493 runtime: RedDBRuntime,
1494 bookmark: Option<crate::replication::CausalBookmark>,
1495 wait_timeout: std::time::Duration,
1496}
1497
1498impl CausalSession {
1499 pub fn bookmark_token(&self) -> Option<String> {
1500 self.bookmark.map(|bookmark| bookmark.encode())
1501 }
1502
1503 pub fn inject_bookmark(&mut self, token: &str) -> RedDBResult<()> {
1504 let bookmark = crate::replication::CausalBookmark::decode(token)
1505 .map_err(|err| RedDBError::InvalidOperation(err.to_string()))?;
1506 self.bookmark = Some(bookmark);
1507 Ok(())
1508 }
1509
1510 pub fn execute_query(&mut self, query: &str) -> RedDBResult<RuntimeQueryResult> {
1511 if is_select_query_text(query) {
1512 if let Some(bookmark) = self.bookmark {
1513 self.runtime
1514 .wait_for_bookmark(&bookmark, self.wait_timeout)?;
1515 }
1516 }
1517 let result = self.runtime.execute_query(query)?;
1518 if let Some(token) = result.bookmark.as_deref() {
1519 self.inject_bookmark(token)?;
1520 }
1521 Ok(result)
1522 }
1523}
1524
1525fn is_select_query_text(query: &str) -> bool {
1526 query
1527 .trim_start()
1528 .get(..6)
1529 .is_some_and(|prefix| prefix.eq_ignore_ascii_case("select"))
1530}
1531
1532pub mod ai;
1533mod allocator_pressure;
1534pub mod analytics_schema_registry;
1535pub(crate) mod analytics_source_catalog;
1536pub mod ask_pipeline;
1537pub mod audit_log;
1538pub mod audit_query;
1539pub mod authorized_search;
1540pub(crate) mod authz;
1541mod background_tasks;
1542pub mod batch_insert;
1543pub mod blockchain_kind;
1544mod collection_contract;
1545pub mod config_matrix;
1546pub mod config_overlay;
1547pub mod config_watcher;
1548pub mod continuous_materialized_view;
1549mod control_event_index;
1550pub mod control_events;
1551pub(crate) mod ddl;
1552mod delete_publication;
1553pub mod disk_space_monitor;
1554mod dml_target_scan;
1555pub mod evidence_export;
1556pub(crate) mod execution_context;
1557mod expr_eval;
1558mod graph_dsl;
1559mod graph_tvf;
1560mod health_connection;
1561mod impl_audit_control;
1562mod impl_backup;
1563mod impl_catalog_accessors;
1564mod impl_cdc;
1565mod impl_config;
1566mod impl_config_secret;
1567pub(crate) mod impl_core;
1568mod impl_core_outer_scope;
1569mod impl_core_result_cache_scopes;
1570mod impl_ddl;
1571mod impl_dml;
1572mod impl_dml_batch;
1573mod impl_dml_chain;
1574mod impl_dml_claim;
1575mod impl_dml_crypto;
1576mod impl_dml_returning;
1577pub(crate) mod impl_dml_support;
1578mod impl_dml_tenant;
1579mod impl_dml_ttl;
1580mod impl_dml_update_analysis;
1581mod impl_dml_update_target;
1582mod impl_ec;
1583pub mod impl_ephemeral;
1584mod impl_events;
1585mod impl_fast_path;
1586mod impl_graph;
1587mod impl_graph_commands;
1588pub mod impl_kv;
1589mod impl_lifecycle;
1590mod impl_materialized_view;
1591mod impl_migrations;
1592mod impl_native;
1593mod impl_physical;
1594mod impl_primary_replica_file;
1595mod impl_probabilistic;
1596pub mod impl_queue;
1597mod impl_ranking;
1598mod impl_replica_loop;
1599mod impl_replication_commit;
1600mod impl_runtime_index_registry;
1601mod impl_telemetry_accessors;
1602mod impl_tenant_registry;
1603pub(crate) use impl_queue::RedwireWaitOutcome;
1604pub(crate) mod claim_telemetry;
1605#[cfg(test)]
1606mod evaluator_differential;
1607mod function_budget;
1608pub(crate) mod function_catalog;
1609mod function_execution;
1610mod function_validation;
1611mod impl_scrub;
1612mod impl_search;
1613mod impl_serverless;
1614mod impl_timeseries;
1615mod impl_tree;
1616mod impl_vcs;
1617mod index_store;
1618mod paged_btree_index;
1619mod paged_count;
1620mod paged_hash_index;
1621#[cfg(test)]
1622pub(crate) use index_store::{IndexMethodKind as QualificationIndexMethodKind, MutationTestPhase};
1623#[cfg(test)]
1624mod cold_keyed_models;
1625mod hash_candidate_memory;
1626#[cfg(test)]
1627mod index_intersection_memory;
1628pub mod integrity_tombstone;
1629mod join_filter;
1630mod keyed_spine;
1631pub(crate) mod kv_read;
1632pub mod kv_watch;
1633pub(crate) mod kv_write;
1634pub mod lease_lifecycle;
1635pub mod lease_loop;
1636pub mod lease_timer_wheel;
1637pub mod lifecycle;
1638pub mod lock_manager;
1639pub mod locking;
1640pub(crate) mod materialization_limit;
1641pub mod memory_accounting;
1644pub(crate) mod memory_admission;
1645pub(crate) mod memory_buffers;
1646pub(crate) mod metric_descriptor_catalog;
1647pub(crate) mod mutation;
1648#[cfg(test)]
1649mod mutation_index_topology_tests;
1650#[cfg(test)]
1651mod mutation_memory_tests;
1652pub(crate) mod mvcc_lifecycle;
1653pub(crate) mod mvcc_maintenance;
1654pub(crate) mod node_load_telemetry;
1655pub(crate) mod occupancy_sampler;
1656pub(crate) mod owned_query_result;
1657pub use owned_query_result::OwnedQueryResult;
1658pub(crate) mod primary_queue_store;
1659mod probabilistic_store;
1660pub mod query_audit;
1661pub(crate) mod query_budget;
1662pub(crate) mod query_exec;
1663pub(crate) mod query_latency_telemetry;
1664pub mod query_request;
1665pub(crate) mod queue_lifecycle;
1666pub(crate) mod queue_telemetry;
1667pub(crate) mod queue_wait_registry;
1668pub mod quota_bucket;
1669pub(crate) mod ranking_descriptor_catalog;
1670mod record_search;
1671mod red_schema;
1672pub(crate) mod replica_queue_store;
1673pub mod resource_limits;
1674mod result_cache_runtime;
1675pub(crate) mod retention_filter;
1676pub(crate) mod retention_sweeper;
1677pub(crate) mod rls_injection;
1678pub mod schema_diff;
1679pub mod schema_vocabulary;
1680pub(crate) mod score_sketch;
1681mod search_graph;
1682pub(crate) mod sessionize;
1683pub mod signed_chain;
1684pub mod signed_writes_kind;
1685pub(crate) mod slo_descriptor_catalog;
1686pub mod snapshot_reuse;
1687mod statement_frame;
1688mod table_row_mvcc_resolver;
1689pub(crate) mod transaction_state;
1690pub mod turbo_crash_inject;
1691mod unique_index_admission;
1692mod vcs_command;
1693mod vector_index;
1694pub mod vector_turbo_kind;
1695pub(crate) mod window_phase;
1696pub mod within_clause;
1697pub mod write_gate;
1698
1699pub use self::claim_telemetry::ClaimTelemetrySnapshot;
1700pub use self::graph_dsl::*;
1701use self::join_filter::*;
1702use self::query_exec::*;
1703use self::record_search::*;
1704pub use self::statement_frame::EffectiveScope;
1705
1706pub mod mvcc {
1712 pub use super::impl_core::{
1713 capture_current_snapshot, clear_current_auth_identity, clear_current_connection_id,
1714 clear_current_snapshot, clear_current_tenant, current_connection_id, current_tenant,
1715 entity_visible_under_current_snapshot, entity_visible_with_context,
1716 set_current_auth_identity, set_current_connection_id, set_current_snapshot,
1717 set_current_tenant, snapshot_bundle, with_snapshot_bundle, SnapshotBundle, SnapshotContext,
1718 };
1719}
1720
1721pub mod record_search_helpers {
1723 use crate::storage::query::UnifiedRecord;
1724 use crate::storage::UnifiedEntity;
1725 use std::collections::BTreeSet;
1726
1727 pub fn entity_type_and_capabilities(
1728 entity: &UnifiedEntity,
1729 ) -> (&'static str, BTreeSet<String>) {
1730 super::record_search::runtime_entity_type_and_capabilities(entity)
1731 }
1732
1733 pub fn any_record_from_entity(entity: UnifiedEntity) -> Option<UnifiedRecord> {
1738 super::record_search::runtime_any_record_from_entity(entity)
1739 }
1740}