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::ast::{
30 AlterOperation, AlterQueueQuery, AlterTableQuery, CompareOp, CreateCollectionQuery,
31 CreateIndexQuery, CreateQueueQuery, CreateTableQuery, CreateTimeSeriesQuery, CreateTreeQuery,
32 CreateVectorQuery, DeleteQuery, DropCollectionQuery, DropDocumentQuery, DropForkQuery,
33 DropGraphQuery, DropIndexQuery, DropKvQuery, DropQueueQuery, DropTableQuery,
34 DropTimeSeriesQuery, DropTreeQuery, DropVectorQuery, EventsBackfillQuery, ExplainAlterQuery,
35 ExplainFormat, FieldRef, Filter, ForkStoreQuery, FusionStrategy, GraphCommand, HybridQuery,
36 IndexMethod, InsertEntityType, InsertQuery, JoinQuery, JoinType, OrderByClause,
37 ProbabilisticCommand, Projection, PromoteForkQuery, QueryExpr, QueueCommand, QueueSelectQuery,
38 QueueSide, SearchCommand, TableQuery, TreeCommand, TruncateQuery, UpdateQuery, VectorQuery,
39 VectorSource,
40};
41use crate::storage::query::is_universal_entity_source as is_universal_query_source;
42use crate::storage::query::modes::{detect_mode, parse_multi, QueryMode};
43use crate::storage::query::planner::{
44 CanonicalLogicalPlan, CanonicalPlanner, CostEstimator, QueryPlanner,
45};
46use crate::storage::query::unified::{UnifiedRecord, UnifiedResult};
47use crate::storage::schema::Value;
48use crate::storage::unified::dsl::{
49 apply_filters, cosine_similarity, Filter as DslFilter, FilterOp as DslFilterOp,
50 FilterValue as DslFilterValue, GraphPatternDsl, HybridQueryBuilder, MatchComponents,
51 QueryResult as DslQueryResult, ScoredMatch, TextSearchBuilder,
52};
53use crate::storage::unified::store::{
54 NativeCatalogSummary, NativeManifestSummary, NativePhysicalState, NativeRecoverySummary,
55 NativeRegistrySummary,
56};
57use crate::storage::unified::{
58 Metadata, MetadataValue as UnifiedMetadataValue, RefTarget, UnifiedMetadataFilter,
59};
60use crate::storage::{
61 EntityData, EntityId, EntityKind, RedDB, RefType, SimilarResult, StoreStats, UnifiedEntity,
62 UnifiedStore,
63};
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 std::thread::available_parallelism()
123 .map(|p| p.get() > 1)
124 .unwrap_or(false)
125 }
126
127 pub fn collect() -> Self {
128 Self {
129 pid: std::process::id(),
130 cpu_cores: std::thread::available_parallelism()
131 .map(|p| p.get())
132 .unwrap_or(1),
133 total_memory_bytes: Self::read_total_memory(),
134 available_memory_bytes: Self::read_available_memory(),
135 os: std::env::consts::OS.to_string(),
136 arch: std::env::consts::ARCH.to_string(),
137 hostname: std::env::var("HOSTNAME")
138 .or_else(|_| std::env::var("COMPUTERNAME"))
139 .unwrap_or_else(|_| "unknown".to_string()),
140 }
141 }
142
143 #[cfg(target_os = "linux")]
144 fn read_total_memory() -> u64 {
145 std::fs::read_to_string("/proc/meminfo")
146 .ok()
147 .and_then(|s| {
148 s.lines()
149 .find(|l| l.starts_with("MemTotal:"))
150 .and_then(|l| {
151 l.split_whitespace()
152 .nth(1)
153 .and_then(|v| v.parse::<u64>().ok())
154 })
155 .map(|kb| kb * 1024)
156 })
157 .unwrap_or(0)
158 }
159
160 #[cfg(target_os = "linux")]
161 fn read_available_memory() -> u64 {
162 std::fs::read_to_string("/proc/meminfo")
163 .ok()
164 .and_then(|s| {
165 s.lines()
166 .find(|l| l.starts_with("MemAvailable:"))
167 .and_then(|l| {
168 l.split_whitespace()
169 .nth(1)
170 .and_then(|v| v.parse::<u64>().ok())
171 })
172 .map(|kb| kb * 1024)
173 })
174 .unwrap_or(0)
175 }
176
177 #[cfg(not(target_os = "linux"))]
178 fn read_total_memory() -> u64 {
179 0
180 }
181
182 #[cfg(not(target_os = "linux"))]
183 fn read_available_memory() -> u64 {
184 0
185 }
186}
187
188#[derive(Debug, Clone)]
189pub struct RuntimeStats {
190 pub active_connections: usize,
191 pub idle_connections: usize,
192 pub total_checkouts: u64,
193 pub paged_mode: bool,
194 pub started_at_unix_ms: u128,
195 pub store: StoreStats,
196 pub system: SystemInfo,
197 pub result_blob_cache: crate::storage::cache::BlobCacheStats,
198 pub kv: KvStats,
199 pub metrics_ingest: MetricsIngestStats,
200}
201
202#[derive(Debug, Clone, PartialEq, Eq)]
203pub struct MetricsTenantActivityStats {
204 pub tenant: String,
205 pub namespace: String,
206 pub operation: String,
207 pub count: u64,
208}
209
210#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
211pub struct MetricsIngestStats {
212 pub samples_accepted: u64,
213 pub series_accepted: u64,
214 pub samples_rejected: u64,
215 pub series_rejected: u64,
216 pub series_rejected_cardinality_budget: u64,
217}
218
219#[derive(Debug, Default)]
220pub(crate) struct MetricsIngestCounters {
221 samples_accepted: AtomicU64,
222 series_accepted: AtomicU64,
223 samples_rejected: AtomicU64,
224 series_rejected: AtomicU64,
225 series_rejected_cardinality_budget: AtomicU64,
226}
227
228impl MetricsIngestCounters {
229 pub(crate) fn record(
230 &self,
231 accepted_samples: u64,
232 accepted_series: u64,
233 rejected_samples: u64,
234 rejected_series: u64,
235 ) {
236 self.samples_accepted
237 .fetch_add(accepted_samples, AtomicOrdering::Relaxed);
238 self.series_accepted
239 .fetch_add(accepted_series, AtomicOrdering::Relaxed);
240 self.samples_rejected
241 .fetch_add(rejected_samples, AtomicOrdering::Relaxed);
242 self.series_rejected
243 .fetch_add(rejected_series, AtomicOrdering::Relaxed);
244 }
245
246 pub(crate) fn record_cardinality_budget_rejections(&self, rejected_series: u64) {
247 self.series_rejected_cardinality_budget
248 .fetch_add(rejected_series, AtomicOrdering::Relaxed);
249 }
250
251 pub(crate) fn snapshot(&self) -> MetricsIngestStats {
252 MetricsIngestStats {
253 samples_accepted: self.samples_accepted.load(AtomicOrdering::Relaxed),
254 series_accepted: self.series_accepted.load(AtomicOrdering::Relaxed),
255 samples_rejected: self.samples_rejected.load(AtomicOrdering::Relaxed),
256 series_rejected: self.series_rejected.load(AtomicOrdering::Relaxed),
257 series_rejected_cardinality_budget: self
258 .series_rejected_cardinality_budget
259 .load(AtomicOrdering::Relaxed),
260 }
261 }
262}
263
264#[derive(Debug, Default)]
265pub(crate) struct MetricsTenantActivityCounters {
266 inner: Mutex<BTreeMap<(String, String, String), u64>>,
267}
268
269impl MetricsTenantActivityCounters {
270 pub(crate) fn record(&self, tenant: &str, namespace: &str, operation: &str) {
271 let mut inner = self
272 .inner
273 .lock()
274 .unwrap_or_else(|poison| poison.into_inner());
275 let key = (
276 tenant.to_string(),
277 namespace.to_string(),
278 operation.to_string(),
279 );
280 *inner.entry(key).or_insert(0) += 1;
281 }
282
283 pub(crate) fn snapshot(&self) -> Vec<MetricsTenantActivityStats> {
284 let inner = self
285 .inner
286 .lock()
287 .unwrap_or_else(|poison| poison.into_inner());
288 inner
289 .iter()
290 .map(
291 |((tenant, namespace, operation), count)| MetricsTenantActivityStats {
292 tenant: tenant.clone(),
293 namespace: namespace.clone(),
294 operation: operation.clone(),
295 count: *count,
296 },
297 )
298 .collect()
299 }
300}
301
302#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
303pub struct KvStats {
304 pub puts: u64,
305 pub gets: u64,
306 pub deletes: u64,
307 pub incrs: u64,
308 pub cas_success: u64,
309 pub cas_conflict: u64,
310 pub watch_streams_active: u64,
311 pub watch_events_emitted: u64,
312 pub watch_drops: u64,
313}
314
315#[derive(Debug, Default)]
316pub(crate) struct KvStatsCounters {
317 puts: AtomicU64,
318 gets: AtomicU64,
319 deletes: AtomicU64,
320 incrs: AtomicU64,
321 cas_success: AtomicU64,
322 cas_conflict: AtomicU64,
323 watch_streams_active: AtomicU64,
324 watch_events_emitted: AtomicU64,
325 watch_drops: AtomicU64,
326}
327
328#[derive(Debug, Default)]
329pub(crate) struct KvTagIndex {
330 tag_to_entries: parking_lot::RwLock<HashMap<(String, String), HashMap<String, EntityId>>>,
331 key_to_tags: parking_lot::RwLock<HashMap<(String, String), BTreeSet<String>>>,
332}
333
334impl KvTagIndex {
335 pub(crate) fn replace(&self, collection: &str, key: &str, id: EntityId, tags: &[String]) {
336 let entry_key = (collection.to_string(), key.to_string());
337 let new_tags: BTreeSet<String> = tags
338 .iter()
339 .map(|tag| tag.trim())
340 .filter(|tag| !tag.is_empty())
341 .map(ToOwned::to_owned)
342 .collect();
343
344 let old_tags = {
345 let mut key_to_tags = self.key_to_tags.write();
346 if new_tags.is_empty() {
347 key_to_tags.remove(&entry_key)
348 } else {
349 key_to_tags.insert(entry_key.clone(), new_tags.clone())
350 }
351 };
352
353 let mut tag_to_entries = self.tag_to_entries.write();
354 if let Some(old_tags) = old_tags {
355 for tag in old_tags {
356 let scoped = (collection.to_string(), tag);
357 let remove_scoped = if let Some(entries) = tag_to_entries.get_mut(&scoped) {
358 entries.remove(key);
359 entries.is_empty()
360 } else {
361 false
362 };
363 if remove_scoped {
364 tag_to_entries.remove(&scoped);
365 }
366 }
367 }
368
369 for tag in new_tags {
370 tag_to_entries
371 .entry((collection.to_string(), tag))
372 .or_default()
373 .insert(key.to_string(), id);
374 }
375 }
376
377 pub(crate) fn remove(&self, collection: &str, key: &str) {
378 let entry_key = (collection.to_string(), key.to_string());
379 let old_tags = self.key_to_tags.write().remove(&entry_key);
380 let Some(old_tags) = old_tags else {
381 return;
382 };
383
384 let mut tag_to_entries = self.tag_to_entries.write();
385 for tag in old_tags {
386 let scoped = (collection.to_string(), tag);
387 let remove_scoped = if let Some(entries) = tag_to_entries.get_mut(&scoped) {
388 entries.remove(key);
389 entries.is_empty()
390 } else {
391 false
392 };
393 if remove_scoped {
394 tag_to_entries.remove(&scoped);
395 }
396 }
397 }
398
399 pub(crate) fn entries_for_tags(
400 &self,
401 collection: &str,
402 tags: &[String],
403 ) -> Vec<(String, EntityId)> {
404 if tags.is_empty() {
405 return Vec::new();
406 }
407
408 let tag_to_entries = self.tag_to_entries.read();
409 let mut out: HashMap<String, EntityId> = HashMap::new();
410 for tag in tags {
411 let scoped = (collection.to_string(), tag.trim().to_string());
412 if let Some(entries) = tag_to_entries.get(&scoped) {
413 for (key, id) in entries {
414 out.entry(key.clone()).or_insert(*id);
415 }
416 }
417 }
418 out.into_iter().collect()
419 }
420
421 pub(crate) fn tags_for_key(&self, collection: &str, key: &str) -> Vec<String> {
422 self.key_to_tags
423 .read()
424 .get(&(collection.to_string(), key.to_string()))
425 .map(|tags| tags.iter().cloned().collect())
426 .unwrap_or_default()
427 }
428}
429
430impl KvStatsCounters {
431 pub(crate) fn snapshot(&self) -> KvStats {
432 KvStats {
433 puts: self.puts.load(AtomicOrdering::Relaxed),
434 gets: self.gets.load(AtomicOrdering::Relaxed),
435 deletes: self.deletes.load(AtomicOrdering::Relaxed),
436 incrs: self.incrs.load(AtomicOrdering::Relaxed),
437 cas_success: self.cas_success.load(AtomicOrdering::Relaxed),
438 cas_conflict: self.cas_conflict.load(AtomicOrdering::Relaxed),
439 watch_streams_active: self.watch_streams_active.load(AtomicOrdering::Relaxed),
440 watch_events_emitted: self.watch_events_emitted.load(AtomicOrdering::Relaxed),
441 watch_drops: self.watch_drops.load(AtomicOrdering::Relaxed),
442 }
443 }
444
445 pub(crate) fn incr_puts(&self) {
446 self.puts.fetch_add(1, AtomicOrdering::Relaxed);
447 }
448
449 pub(crate) fn incr_gets(&self) {
450 self.gets.fetch_add(1, AtomicOrdering::Relaxed);
451 }
452
453 pub(crate) fn incr_deletes(&self) {
454 self.deletes.fetch_add(1, AtomicOrdering::Relaxed);
455 }
456
457 pub(crate) fn incr_incrs(&self) {
458 self.incrs.fetch_add(1, AtomicOrdering::Relaxed);
459 }
460
461 pub(crate) fn incr_cas_success(&self) {
462 self.cas_success.fetch_add(1, AtomicOrdering::Relaxed);
463 }
464
465 pub(crate) fn incr_cas_conflict(&self) {
466 self.cas_conflict.fetch_add(1, AtomicOrdering::Relaxed);
467 }
468
469 pub(crate) fn incr_watch_streams_active(&self) {
470 self.watch_streams_active
471 .fetch_add(1, AtomicOrdering::Relaxed);
472 }
473
474 pub(crate) fn decr_watch_streams_active(&self) {
475 self.watch_streams_active
476 .fetch_sub(1, AtomicOrdering::Relaxed);
477 }
478
479 pub(crate) fn incr_watch_events_emitted(&self) {
480 self.watch_events_emitted
481 .fetch_add(1, AtomicOrdering::Relaxed);
482 }
483
484 pub(crate) fn add_watch_drops(&self, count: u64) {
485 self.watch_drops.fetch_add(count, AtomicOrdering::Relaxed);
486 }
487}
488
489#[derive(Debug, Clone)]
490pub struct RuntimeQueryResult {
491 pub query: String,
492 pub mode: QueryMode,
493 pub statement: &'static str,
494 pub engine: &'static str,
495 pub result: UnifiedResult,
496 pub affected_rows: u64,
497 pub statement_type: &'static str,
499 pub bookmark: Option<String>,
500 pub notice: Option<String>,
501}
502
503impl RuntimeQueryResult {
504 pub fn dml_result(
506 query: String,
507 affected: u64,
508 statement_type: &'static str,
509 engine: &'static str,
510 ) -> Self {
511 Self {
512 query,
513 mode: QueryMode::Sql,
514 statement: statement_type,
515 engine,
516 result: UnifiedResult::empty(),
517 affected_rows: affected,
518 statement_type,
519 bookmark: None,
520 notice: None,
521 }
522 }
523
524 pub fn ok_message(query: String, message: &str, statement_type: &'static str) -> Self {
526 let mut result = UnifiedResult::empty();
527 let mut record = UnifiedRecord::new();
528 record.set("message", Value::text(message.to_string()));
529 result.push(record);
530 result.columns = vec!["message".to_string()];
531
532 Self {
533 query,
534 mode: QueryMode::Sql,
535 statement: statement_type,
536 engine: "runtime-ddl",
537 result,
538 affected_rows: 0,
539 statement_type,
540 bookmark: None,
541 notice: None,
542 }
543 }
544
545 pub fn ok_records(
549 query: String,
550 columns: Vec<String>,
551 rows: Vec<Vec<(String, Value)>>,
552 statement_type: &'static str,
553 ) -> Self {
554 let mut result = UnifiedResult::empty();
555 for row in rows {
556 let mut record = UnifiedRecord::new();
557 for (k, v) in row {
558 record.set(&k, v);
559 }
560 result.push(record);
561 }
562 result.columns = columns;
563
564 Self {
565 query,
566 mode: QueryMode::Sql,
567 statement: statement_type,
568 engine: "runtime-meta",
569 result,
570 affected_rows: 0,
571 statement_type,
572 bookmark: None,
573 notice: None,
574 }
575 }
576
577 pub fn bookmark_token(&self) -> Option<&str> {
578 self.bookmark.as_deref()
579 }
580}
581
582#[derive(Debug, Clone)]
583pub struct RuntimeQueryExplain {
584 pub query: String,
585 pub mode: QueryMode,
586 pub statement: &'static str,
587 pub is_universal: bool,
588 pub plan_cost: crate::storage::query::planner::PlanCost,
589 pub estimated_rows: f64,
590 pub estimated_selectivity: f64,
591 pub estimated_confidence: f64,
592 pub passes_applied: Vec<String>,
593 pub logical_plan: CanonicalLogicalPlan,
594 pub cte_materializations: Vec<String>,
601}
602
603#[derive(Debug, Clone)]
604pub struct RuntimeIvfMatch {
605 pub entity_id: u64,
606 pub distance: f32,
607 pub entity: Option<UnifiedEntity>,
608}
609
610#[derive(Debug, Clone)]
611pub struct RuntimeIvfSearchResult {
612 pub collection: String,
613 pub k: usize,
614 pub n_lists: usize,
615 pub n_probes: usize,
616 pub stats: IvfStats,
617 pub matches: Vec<RuntimeIvfMatch>,
618}
619
620#[derive(Debug, Clone, Copy, PartialEq, Eq)]
621pub enum RuntimeGraphDirection {
622 Outgoing,
623 Incoming,
624 Both,
625}
626
627#[derive(Debug, Clone, Copy, PartialEq, Eq)]
628pub enum RuntimeGraphTraversalStrategy {
629 Bfs,
630 Dfs,
631}
632
633#[derive(Debug, Clone, Copy, PartialEq, Eq)]
634pub enum RuntimeGraphPathAlgorithm {
635 Bfs,
636 Dijkstra,
637 AStar,
638 BellmanFord,
639}
640
641#[derive(Debug, Clone)]
642pub struct RuntimeGraphNode {
643 pub id: String,
644 pub label: String,
645 pub node_type: String,
646 pub out_edge_count: u32,
647 pub in_edge_count: u32,
648}
649
650#[derive(Debug, Clone)]
651pub struct RuntimeGraphEdge {
652 pub source: String,
653 pub target: String,
654 pub edge_type: String,
655 pub weight: f32,
656}
657
658#[derive(Debug, Clone)]
659pub struct RuntimeGraphVisit {
660 pub depth: usize,
661 pub node: RuntimeGraphNode,
662}
663
664#[derive(Debug, Clone)]
665pub struct RuntimeGraphNeighborhoodResult {
666 pub source: String,
667 pub direction: RuntimeGraphDirection,
668 pub max_depth: usize,
669 pub nodes: Vec<RuntimeGraphVisit>,
670 pub edges: Vec<RuntimeGraphEdge>,
671}
672
673#[derive(Debug, Clone)]
674pub struct RuntimeGraphTraversalResult {
675 pub source: String,
676 pub direction: RuntimeGraphDirection,
677 pub strategy: RuntimeGraphTraversalStrategy,
678 pub max_depth: usize,
679 pub visits: Vec<RuntimeGraphVisit>,
680 pub edges: Vec<RuntimeGraphEdge>,
681}
682
683#[derive(Debug, Clone)]
684pub struct RuntimeGraphPath {
685 pub hop_count: usize,
686 pub total_weight: f64,
687 pub nodes: Vec<RuntimeGraphNode>,
688 pub edges: Vec<RuntimeGraphEdge>,
689}
690
691#[derive(Debug, Clone)]
692pub struct RuntimeGraphPathResult {
693 pub source: String,
694 pub target: String,
695 pub direction: RuntimeGraphDirection,
696 pub algorithm: RuntimeGraphPathAlgorithm,
697 pub nodes_visited: usize,
698 pub negative_cycle_detected: Option<bool>,
699 pub path: Option<RuntimeGraphPath>,
700}
701
702#[derive(Debug, Clone, Copy, PartialEq, Eq)]
703pub enum RuntimeGraphComponentsMode {
704 Connected,
705 Weak,
706 Strong,
707}
708
709#[derive(Debug, Clone, Copy, PartialEq, Eq)]
710pub enum RuntimeGraphCentralityAlgorithm {
711 Degree,
712 Closeness,
713 Betweenness,
714 Eigenvector,
715 PageRank,
716}
717
718#[derive(Debug, Clone, Copy, PartialEq, Eq)]
719pub enum RuntimeGraphCommunityAlgorithm {
720 LabelPropagation,
721 Louvain,
722}
723
724#[derive(Debug, Clone)]
725pub struct RuntimeGraphComponent {
726 pub id: String,
727 pub size: usize,
728 pub nodes: Vec<String>,
729}
730
731#[derive(Debug, Clone)]
732pub struct RuntimeGraphComponentsResult {
733 pub mode: RuntimeGraphComponentsMode,
734 pub count: usize,
735 pub components: Vec<RuntimeGraphComponent>,
736}
737
738#[derive(Debug, Clone)]
739pub struct RuntimeGraphCentralityScore {
740 pub node: RuntimeGraphNode,
741 pub score: f64,
742}
743
744#[derive(Debug, Clone)]
745pub struct RuntimeGraphDegreeScore {
746 pub node: RuntimeGraphNode,
747 pub in_degree: usize,
748 pub out_degree: usize,
749 pub total_degree: usize,
750}
751
752#[derive(Debug, Clone)]
753pub struct RuntimeGraphCentralityResult {
754 pub algorithm: RuntimeGraphCentralityAlgorithm,
755 pub normalized: Option<bool>,
756 pub iterations: Option<usize>,
757 pub converged: Option<bool>,
758 pub scores: Vec<RuntimeGraphCentralityScore>,
759 pub degree_scores: Vec<RuntimeGraphDegreeScore>,
760}
761
762#[derive(Debug, Clone)]
763pub struct RuntimeGraphCommunity {
764 pub id: String,
765 pub size: usize,
766 pub nodes: Vec<String>,
767}
768
769#[derive(Debug, Clone)]
770pub struct RuntimeGraphCommunityResult {
771 pub algorithm: RuntimeGraphCommunityAlgorithm,
772 pub count: usize,
773 pub iterations: Option<usize>,
774 pub converged: Option<bool>,
775 pub modularity: Option<f64>,
776 pub passes: Option<usize>,
777 pub communities: Vec<RuntimeGraphCommunity>,
778}
779
780#[derive(Debug, Clone)]
781pub struct RuntimeGraphClusteringResult {
782 pub global: f64,
783 pub local: Vec<RuntimeGraphCentralityScore>,
784 pub triangle_count: Option<usize>,
785}
786
787#[derive(Debug, Clone)]
788pub struct RuntimeGraphHitsResult {
789 pub iterations: usize,
790 pub converged: bool,
791 pub hubs: Vec<RuntimeGraphCentralityScore>,
792 pub authorities: Vec<RuntimeGraphCentralityScore>,
793}
794
795#[derive(Debug, Clone)]
796pub struct RuntimeGraphCyclesResult {
797 pub limit_reached: bool,
798 pub cycles: Vec<RuntimeGraphPath>,
799}
800
801#[derive(Debug, Clone)]
802pub struct RuntimeGraphTopologicalSortResult {
803 pub acyclic: bool,
804 pub ordered_nodes: Vec<RuntimeGraphNode>,
805}
806
807#[derive(Debug, Clone)]
808pub struct RuntimeGraphPropertiesResult {
809 pub node_count: usize,
810 pub edge_count: usize,
811 pub self_loop_count: usize,
812 pub negative_edge_count: usize,
813 pub connected_component_count: usize,
814 pub weak_component_count: usize,
815 pub strong_component_count: usize,
816 pub is_empty: bool,
817 pub is_connected: bool,
818 pub is_weakly_connected: bool,
819 pub is_strongly_connected: bool,
820 pub is_complete: bool,
821 pub is_complete_directed: bool,
822 pub is_cyclic: bool,
823 pub is_circular: bool,
824 pub is_acyclic: bool,
825 pub is_tree: bool,
826 pub density: f64,
827 pub density_directed: f64,
828}
829
830#[derive(Debug, Clone)]
835pub struct ContextSearchResult {
836 pub query: String,
837 pub tables: Vec<ContextEntity>,
838 pub graph: ContextGraphResult,
839 pub vectors: Vec<ContextEntity>,
840 pub documents: Vec<ContextEntity>,
841 pub key_values: Vec<ContextEntity>,
842 pub connections: Vec<ContextConnection>,
843 pub summary: ContextSummary,
844}
845
846#[derive(Debug, Clone)]
847pub struct ContextEntity {
848 pub entity: UnifiedEntity,
849 pub score: f32,
850 pub discovery: DiscoveryMethod,
851 pub collection: String,
852}
853
854#[derive(Debug, Clone)]
855pub enum DiscoveryMethod {
856 Indexed {
857 field: String,
858 },
859 GlobalScan,
860 CrossReference {
861 source_id: u64,
862 ref_type: String,
863 },
864 GraphTraversal {
865 source_id: u64,
866 edge_type: String,
867 depth: usize,
868 },
869 VectorQuery {
870 similarity: f32,
871 },
872}
873
874#[derive(Debug, Clone)]
875pub struct ContextGraphResult {
876 pub nodes: Vec<ContextEntity>,
877 pub edges: Vec<ContextEntity>,
878}
879
880#[derive(Debug, Clone)]
881pub struct ContextConnection {
882 pub from_id: u64,
883 pub to_id: u64,
884 pub connection_type: ContextConnectionType,
885 pub weight: f32,
886}
887
888#[derive(Debug, Clone)]
889pub enum ContextConnectionType {
890 CrossRef(String),
891 GraphEdge(String),
892 VectorSimilarity(f32),
893}
894
895#[derive(Debug, Clone)]
896pub struct ContextSummary {
897 pub total_entities: usize,
898 pub direct_matches: usize,
899 pub expanded_via_graph: usize,
900 pub expanded_via_cross_refs: usize,
901 pub expanded_via_vector_query: usize,
902 pub collections_searched: usize,
903 pub execution_time_us: u64,
904 pub tiers_used: Vec<String>,
905 pub entities_reindexed: usize,
906}
907
908struct PoolState {
909 next_id: u64,
910 active: usize,
911 idle: Vec<u64>,
912 total_checkouts: u64,
913}
914
915impl Default for PoolState {
916 fn default() -> Self {
917 Self {
918 next_id: 1,
919 active: 0,
920 idle: Vec::new(),
921 total_checkouts: 0,
922 }
923 }
924}
925
926#[derive(Debug, Clone)]
927struct RuntimeResultCacheEntry {
928 result: RuntimeQueryResult,
929 cached_at: std::time::Instant,
930 scopes: HashSet<String>,
931}
932
933pub const METRIC_CACHE_SHADOW_DIVERGENCE_TOTAL: &str = "cache_shadow_divergence_total";
934pub const METRIC_RESULT_CACHE_HIT_TOTAL: &str = "result_cache_hit_total";
939pub const METRIC_RESULT_CACHE_MISS_TOTAL: &str = "result_cache_miss_total";
940pub const METRIC_RESULT_CACHE_EVICT_TOTAL: &str = "result_cache_evict_total";
941pub(crate) const ASK_ANSWER_CACHE_NAMESPACE: &str = "runtime.ask_answer_cache";
942const RMW_LOCK_SHARDS: usize = 64;
943
944struct RmwLockTable {
945 shards: Vec<parking_lot::Mutex<HashMap<String, Arc<parking_lot::Mutex<()>>>>>,
946}
947
948impl RmwLockTable {
949 fn new() -> Self {
950 let shards = (0..RMW_LOCK_SHARDS)
951 .map(|_| parking_lot::Mutex::new(HashMap::new()))
952 .collect();
953 Self { shards }
954 }
955
956 fn lock_for(&self, collection: &str, key: &str) -> Arc<parking_lot::Mutex<()>> {
957 use std::hash::{Hash, Hasher};
958
959 let mut hasher = std::collections::hash_map::DefaultHasher::new();
960 collection.hash(&mut hasher);
961 key.hash(&mut hasher);
962 let shard_idx = (hasher.finish() as usize) % self.shards.len();
963 let map_key = format!("{collection}\u{1f}{key}");
964 let mut shard = self.shards[shard_idx].lock();
965 shard
966 .entry(map_key)
967 .or_insert_with(|| Arc::new(parking_lot::Mutex::new(())))
968 .clone()
969 }
970}
971
972#[derive(Debug, Default)]
973pub(crate) struct CheckpointProjectionStats {
974 last_materialized_lsn: std::sync::atomic::AtomicU64,
975 checkpoints_completed: std::sync::atomic::AtomicU64,
976 last_checkpoint_duration_ms: std::sync::atomic::AtomicU64,
977}
978
979impl CheckpointProjectionStats {
980 pub(crate) fn record_checkpoint(&self, lsn: u64, duration_ms: u64) {
981 use std::sync::atomic::Ordering;
982
983 self.last_materialized_lsn.store(lsn, Ordering::Relaxed);
984 self.last_checkpoint_duration_ms
985 .store(duration_ms, Ordering::Relaxed);
986 self.checkpoints_completed.fetch_add(1, Ordering::Relaxed);
987 }
988
989 pub(crate) fn snapshot(&self, current_lsn: u64) -> CheckpointProjectionStatsSnapshot {
990 use std::sync::atomic::Ordering;
991
992 let last_materialized_lsn = self.last_materialized_lsn.load(Ordering::Relaxed);
993 CheckpointProjectionStatsSnapshot {
994 current_lsn,
995 last_materialized_lsn,
996 projection_lag: current_lsn.saturating_sub(last_materialized_lsn),
997 checkpoints_completed: self.checkpoints_completed.load(Ordering::Relaxed),
998 last_checkpoint_duration_ms: self.last_checkpoint_duration_ms.load(Ordering::Relaxed),
999 }
1000 }
1001}
1002
1003#[derive(Debug, Clone, Copy)]
1004pub(crate) struct CheckpointProjectionStatsSnapshot {
1005 pub(crate) current_lsn: u64,
1006 pub(crate) last_materialized_lsn: u64,
1007 pub(crate) projection_lag: u64,
1008 pub(crate) checkpoints_completed: u64,
1009 pub(crate) last_checkpoint_duration_ms: u64,
1010}
1011
1012#[derive(Debug, Clone)]
1013pub(crate) struct ScrubStatsSnapshot {
1014 pub(crate) last_run_unix_ms: u64,
1015 pub(crate) last_findings_count: u64,
1016 pub(crate) background_status: String,
1017 pub(crate) background_verified_objects: u64,
1018 pub(crate) background_total_objects: u64,
1019 pub(crate) verified: reddb_file::StorageScrubVerifiedCounters,
1020}
1021
1022#[derive(Debug, Clone)]
1023pub(crate) struct ScrubRuntimeState {
1024 pub(crate) last_run_unix_ms: u64,
1025 pub(crate) last_findings_count: u64,
1026 pub(crate) background_cursor: usize,
1027 pub(crate) background_status: String,
1028 pub(crate) background_verified_objects: u64,
1029 pub(crate) background_total_objects: u64,
1030 pub(crate) verified: reddb_file::StorageScrubVerifiedCounters,
1031}
1032
1033impl Default for ScrubRuntimeState {
1034 fn default() -> Self {
1035 Self {
1036 last_run_unix_ms: 0,
1037 last_findings_count: 0,
1038 background_cursor: 0,
1039 background_status: "idle".to_string(),
1040 background_verified_objects: 0,
1041 background_total_objects: 0,
1042 verified: reddb_file::StorageScrubVerifiedCounters::default(),
1043 }
1044 }
1045}
1046
1047impl ScrubRuntimeState {
1048 pub(crate) fn snapshot(&self) -> ScrubStatsSnapshot {
1049 ScrubStatsSnapshot {
1050 last_run_unix_ms: self.last_run_unix_ms,
1051 last_findings_count: self.last_findings_count,
1052 background_status: self.background_status.clone(),
1053 background_verified_objects: self.background_verified_objects,
1054 background_total_objects: self.background_total_objects,
1055 verified: self.verified.clone(),
1056 }
1057 }
1058}
1059
1060struct RuntimeInner {
1061 db: Arc<RedDB>,
1062 layout: PhysicalLayout,
1063 embedded_single_file: bool,
1064 pub(crate) memory_budget: crate::storage::memory_budget::MemoryBudget,
1067 pub(crate) memory_accounting: Arc<crate::storage::memory_pools::MemoryAccounting>,
1070 indices: IndexCatalog,
1071 pool_config: ConnectionPoolConfig,
1072 pool: Mutex<PoolState>,
1073 started_at_unix_ms: u128,
1074 probabilistic: probabilistic_store::ProbabilisticStore,
1075 index_store: index_store::IndexStore,
1076 cdc: crate::replication::cdc::CdcBuffer,
1077 pub(crate) checkpoint_projection_stats: CheckpointProjectionStats,
1078 pub(crate) scrub_state: parking_lot::Mutex<ScrubRuntimeState>,
1079 pub(crate) checkpoint_columnar_emission_budget_chunks: usize,
1080 pub(crate) columnar_projection_size_floor_rows: usize,
1081 backup_scheduler: crate::replication::scheduler::BackupScheduler,
1082 query_cache: parking_lot::RwLock<crate::storage::query::planner::cache::PlanCache>,
1083 result_cache: parking_lot::RwLock<(
1084 HashMap<String, RuntimeResultCacheEntry>,
1085 std::collections::VecDeque<String>,
1086 )>,
1087 result_blob_cache: crate::storage::cache::BlobCache,
1088 result_blob_entries: parking_lot::RwLock<(
1089 HashMap<String, RuntimeResultCacheEntry>,
1090 std::collections::VecDeque<String>,
1091 )>,
1092 ask_answer_cache_entries:
1093 parking_lot::RwLock<(HashSet<String>, std::collections::VecDeque<String>)>,
1094 result_cache_shadow_divergences: std::sync::atomic::AtomicU64,
1095 result_cache_hits: std::sync::atomic::AtomicU64,
1098 result_cache_misses: std::sync::atomic::AtomicU64,
1099 result_cache_evictions: std::sync::atomic::AtomicU64,
1100 ask_daily_spend:
1101 parking_lot::RwLock<HashMap<String, crate::runtime::ai::cost_guard::DailyState>>,
1102 queue_message_locks: parking_lot::RwLock<HashMap<String, Arc<parking_lot::Mutex<()>>>>,
1105 rmw_locks: RmwLockTable,
1109 planner_dirty_tables: parking_lot::RwLock<HashSet<String>>,
1110 ec_registry: Arc<crate::ec::config::EcRegistry>,
1111 config_registry: Arc<crate::auth::registry::ConfigRegistry>,
1112 ec_worker: crate::ec::worker::EcWorker,
1113 auth_store: parking_lot::RwLock<Option<Arc<crate::auth::store::AuthStore>>>,
1118 oauth_validator: parking_lot::RwLock<Option<Arc<crate::auth::oauth::OAuthValidator>>>,
1125 browser_token_authority:
1132 parking_lot::RwLock<Option<Arc<crate::auth::browser_token::BrowserTokenAuthority>>>,
1133 views: parking_lot::RwLock<HashMap<String, Arc<crate::storage::query::ast::CreateViewQuery>>>,
1144 materialized_views: parking_lot::RwLock<crate::storage::cache::result::MaterializedViewCache>,
1145 pub(crate) retention_sweeper:
1150 parking_lot::RwLock<crate::runtime::retention_sweeper::RetentionSweeperState>,
1151 snapshot_manager: Arc<crate::storage::transaction::snapshot::SnapshotManager>,
1159 tx_contexts:
1166 parking_lot::RwLock<HashMap<u64, crate::storage::transaction::snapshot::TxnContext>>,
1167 lock_manager: Arc<crate::runtime::lock_manager::LockManager>,
1174 env_config_overrides: HashMap<String, String>,
1180 tx_local_tenants: parking_lot::RwLock<HashMap<u64, Option<String>>>,
1188 rls_policies: parking_lot::RwLock<
1195 HashMap<(String, String), Arc<crate::storage::query::ast::CreatePolicyQuery>>,
1196 >,
1197 rls_enabled_tables: parking_lot::RwLock<HashSet<String>>,
1198 foreign_tables: Arc<crate::storage::fdw::ForeignTableRegistry>,
1206 pending_tombstones: parking_lot::RwLock<
1218 HashMap<
1219 u64,
1220 Vec<(
1221 String,
1222 crate::storage::unified::entity::EntityId,
1223 crate::storage::transaction::snapshot::Xid,
1224 crate::storage::transaction::snapshot::Xid,
1225 )>,
1226 >,
1227 >,
1228 pending_versioned_updates: parking_lot::RwLock<
1234 HashMap<
1235 u64,
1236 Vec<(
1237 String,
1238 crate::storage::unified::entity::EntityId,
1239 crate::storage::unified::entity::EntityId,
1240 crate::storage::transaction::snapshot::Xid,
1241 crate::storage::transaction::snapshot::Xid,
1242 )>,
1243 >,
1244 >,
1245 pending_queue_dedup: parking_lot::RwLock<HashMap<u64, Vec<(String, String, EntityId)>>>,
1251 pending_kv_watch_events:
1252 parking_lot::RwLock<HashMap<u64, Vec<crate::replication::cdc::KvWatchEvent>>>,
1253 pending_store_wal_actions:
1254 parking_lot::RwLock<HashMap<u64, crate::storage::unified::DeferredStoreWalActions>>,
1255 pending_claim_locks: parking_lot::RwLock<HashMap<(String, EntityId), u64>>,
1261 tenant_tables: parking_lot::RwLock<HashMap<String, String>>,
1270 ddl_epoch: std::sync::atomic::AtomicU64,
1276 write_gate: Arc<crate::runtime::write_gate::WriteGate>,
1287 lifecycle: crate::runtime::lifecycle::Lifecycle,
1293 resource_limits: crate::runtime::resource_limits::ResourceLimits,
1298 audit_log: Arc<crate::runtime::audit_log::AuditLogger>,
1302 control_event_ledger:
1306 parking_lot::RwLock<Arc<dyn crate::runtime::control_events::ControlEventLedger>>,
1307 control_event_config: crate::runtime::control_events::ControlEventConfig,
1308 query_audit: Arc<crate::runtime::query_audit::QueryAuditStream>,
1312 lease_lifecycle: std::sync::OnceLock<Arc<crate::runtime::lease_lifecycle::LeaseLifecycle>>,
1319 replica_apply_metrics: Arc<crate::replication::logical::ReplicaApplyMetrics>,
1323 replica_link_metrics: Arc<crate::replication::reconnect::ReplicaLinkMetrics>,
1328 quota_bucket: crate::runtime::quota_bucket::QuotaBucket,
1331 schema_vocabulary: parking_lot::RwLock<crate::runtime::schema_vocabulary::SchemaVocabulary>,
1336 slow_query_logger: Arc<crate::telemetry::slow_query_logger::SlowQueryLogger>,
1342 slow_query_store: Arc<crate::telemetry::slow_query_store::SlowQueryStore>,
1347 kv_stats: KvStatsCounters,
1350 metrics_ingest_stats: MetricsIngestCounters,
1351 metrics_tenant_activity_stats: MetricsTenantActivityCounters,
1352 claim_telemetry: std::sync::Arc<claim_telemetry::ClaimTelemetryCounters>,
1355 queue_telemetry: std::sync::Arc<queue_telemetry::QueueTelemetryCounters>,
1359 query_latency_telemetry: std::sync::Arc<query_latency_telemetry::QueryLatencyTelemetry>,
1364 occupancy_sampler: std::sync::Arc<occupancy_sampler::OccupancySampler>,
1369 node_load_telemetry: std::sync::Arc<node_load_telemetry::NodeLoadTelemetry>,
1374 queue_presence: std::sync::Arc<crate::storage::queue::presence::ConsumerPresenceRegistry>,
1381 vector_introspection:
1390 std::sync::Arc<crate::storage::vector::introspection::VectorIntrospectionRegistry>,
1391 queue_wait_registry: std::sync::Arc<queue_wait_registry::QueueWaitRegistry>,
1395 pending_queue_wakes: parking_lot::RwLock<HashMap<u64, Vec<(String, String)>>>,
1401 kv_tag_index: KvTagIndex,
1403 chain_tip_cache:
1409 parking_lot::Mutex<HashMap<String, crate::runtime::blockchain_kind::ChainTipFull>>,
1410 chain_integrity_broken: parking_lot::Mutex<HashMap<String, bool>>,
1415 integrity_tombstones:
1422 parking_lot::Mutex<Vec<crate::runtime::integrity_tombstone::TombstoneRange>>,
1423 integrity_tombstones_state: std::sync::atomic::AtomicU8,
1424}
1425
1426#[derive(Clone)]
1427pub struct RedDBRuntime {
1428 inner: Arc<RuntimeInner>,
1429}
1430
1431pub struct RuntimeConnection {
1432 id: u64,
1433 inner: Arc<RuntimeInner>,
1434}
1435
1436pub struct CausalSession {
1437 runtime: RedDBRuntime,
1438 bookmark: Option<crate::replication::CausalBookmark>,
1439 wait_timeout: std::time::Duration,
1440}
1441
1442impl CausalSession {
1443 pub fn bookmark_token(&self) -> Option<String> {
1444 self.bookmark.map(|bookmark| bookmark.encode())
1445 }
1446
1447 pub fn inject_bookmark(&mut self, token: &str) -> RedDBResult<()> {
1448 let bookmark = crate::replication::CausalBookmark::decode(token)
1449 .map_err(|err| RedDBError::InvalidOperation(err.to_string()))?;
1450 self.bookmark = Some(bookmark);
1451 Ok(())
1452 }
1453
1454 pub fn execute_query(&mut self, query: &str) -> RedDBResult<RuntimeQueryResult> {
1455 if is_select_query_text(query) {
1456 if let Some(bookmark) = self.bookmark {
1457 self.runtime
1458 .wait_for_bookmark(&bookmark, self.wait_timeout)?;
1459 }
1460 }
1461 let result = self.runtime.execute_query(query)?;
1462 if let Some(token) = result.bookmark.as_deref() {
1463 self.inject_bookmark(token)?;
1464 }
1465 Ok(result)
1466 }
1467}
1468
1469fn is_select_query_text(query: &str) -> bool {
1470 query
1471 .trim_start()
1472 .get(..6)
1473 .is_some_and(|prefix| prefix.eq_ignore_ascii_case("select"))
1474}
1475
1476pub mod ai;
1477pub mod analytics_schema_registry;
1478pub(crate) mod analytics_source_catalog;
1479pub mod ask_pipeline;
1480pub mod audit_log;
1481pub mod audit_query;
1482pub mod authorized_search;
1483pub(crate) mod authz;
1484pub mod batch_insert;
1485pub mod blockchain_kind;
1486mod collection_contract;
1487pub mod config_matrix;
1488pub mod config_overlay;
1489pub mod config_watcher;
1490pub mod continuous_materialized_view;
1491pub mod control_events;
1492pub(crate) mod ddl;
1493pub mod disk_space_monitor;
1494mod dml_target_scan;
1495pub mod evidence_export;
1496pub(crate) mod execution_context;
1497mod expr_eval;
1498mod graph_dsl;
1499mod graph_tvf;
1500mod health_connection;
1501mod impl_audit_control;
1502mod impl_backup;
1503mod impl_catalog_accessors;
1504mod impl_cdc;
1505mod impl_config;
1506mod impl_config_secret;
1507pub(crate) mod impl_core;
1508mod impl_core_outer_scope;
1509mod impl_core_result_cache_scopes;
1510mod impl_ddl;
1511mod impl_dml;
1512mod impl_dml_batch;
1513mod impl_dml_chain;
1514mod impl_dml_claim;
1515mod impl_dml_crypto;
1516mod impl_dml_returning;
1517mod impl_dml_support;
1518mod impl_dml_tenant;
1519mod impl_dml_ttl;
1520mod impl_dml_update_analysis;
1521mod impl_dml_update_target;
1522mod impl_ec;
1523pub mod impl_ephemeral;
1524mod impl_events;
1525mod impl_fast_path;
1526mod impl_graph;
1527mod impl_graph_commands;
1528pub mod impl_kv;
1529mod impl_lifecycle;
1530mod impl_materialized_view;
1531mod impl_migrations;
1532mod impl_native;
1533mod impl_physical;
1534mod impl_primary_replica_file;
1535mod impl_probabilistic;
1536pub mod impl_queue;
1537mod impl_ranking;
1538mod impl_replica_loop;
1539mod impl_replication_commit;
1540mod impl_runtime_index_registry;
1541mod impl_telemetry_accessors;
1542mod impl_tenant_registry;
1543pub(crate) use impl_queue::RedwireWaitOutcome;
1544pub(crate) mod claim_telemetry;
1545mod impl_scrub;
1546mod impl_search;
1547mod impl_serverless;
1548mod impl_timeseries;
1549mod impl_tree;
1550mod impl_vcs;
1551mod index_store;
1552pub mod integrity_tombstone;
1553mod join_filter;
1554mod keyed_spine;
1555pub mod kv_watch;
1556pub mod lease_lifecycle;
1557pub mod lease_loop;
1558pub mod lease_timer_wheel;
1559pub mod lifecycle;
1560pub mod lock_manager;
1561pub mod locking;
1562pub(crate) mod materialization_limit;
1563pub mod memory_accounting;
1566pub(crate) mod memory_admission;
1567pub(crate) mod metric_descriptor_catalog;
1568pub(crate) mod mutation;
1569pub(crate) mod mvcc_lifecycle;
1570pub(crate) mod node_load_telemetry;
1571pub(crate) mod occupancy_sampler;
1572pub(crate) mod primary_queue_store;
1573mod probabilistic_store;
1574pub mod query_audit;
1575pub(crate) mod query_exec;
1576pub(crate) mod query_latency_telemetry;
1577pub(crate) mod queue_lifecycle;
1578pub(crate) mod queue_telemetry;
1579pub(crate) mod queue_wait_registry;
1580pub mod quota_bucket;
1581pub(crate) mod ranking_descriptor_catalog;
1582mod record_search;
1583mod red_schema;
1584pub(crate) mod replica_queue_store;
1585pub mod resource_limits;
1586mod result_cache_runtime;
1587pub(crate) mod retention_filter;
1588pub(crate) mod retention_sweeper;
1589mod rls_injection;
1590pub(crate) mod scalar_evaluator;
1591pub mod schema_diff;
1592pub mod schema_vocabulary;
1593pub(crate) mod score_sketch;
1594pub(crate) mod sessionize;
1595pub mod signed_chain;
1596pub mod signed_writes_kind;
1597pub(crate) mod slo_descriptor_catalog;
1598pub mod snapshot_reuse;
1599mod statement_frame;
1600mod table_row_mvcc_resolver;
1601pub mod turbo_crash_inject;
1602mod vcs_command;
1603mod vector_index;
1604pub mod vector_turbo_kind;
1605pub(crate) mod window_phase;
1606pub mod within_clause;
1607pub mod write_gate;
1608
1609pub use self::claim_telemetry::ClaimTelemetrySnapshot;
1610pub use self::graph_dsl::*;
1611use self::join_filter::*;
1612use self::query_exec::*;
1613use self::record_search::*;
1614pub use self::statement_frame::EffectiveScope;
1615
1616pub mod mvcc {
1622 pub use super::impl_core::{
1623 capture_current_snapshot, clear_current_auth_identity, clear_current_connection_id,
1624 clear_current_snapshot, clear_current_tenant, current_connection_id, current_tenant,
1625 entity_visible_under_current_snapshot, entity_visible_with_context,
1626 set_current_auth_identity, set_current_connection_id, set_current_snapshot,
1627 set_current_tenant, snapshot_bundle, with_snapshot_bundle, SnapshotBundle, SnapshotContext,
1628 };
1629}
1630
1631pub mod record_search_helpers {
1633 use crate::storage::query::UnifiedRecord;
1634 use crate::storage::UnifiedEntity;
1635 use std::collections::BTreeSet;
1636
1637 pub fn entity_type_and_capabilities(
1638 entity: &UnifiedEntity,
1639 ) -> (&'static str, BTreeSet<String>) {
1640 super::record_search::runtime_entity_type_and_capabilities(entity)
1641 }
1642
1643 pub fn any_record_from_entity(entity: UnifiedEntity) -> Option<UnifiedRecord> {
1648 super::record_search::runtime_any_record_from_entity(entity)
1649 }
1650}