quill_sql/catalog/
registry.rs

1use std::sync::Arc;
2
3use dashmap::DashMap;
4// Use a simple static with lazy_init to avoid adding new dependencies.
5use std::sync::OnceLock;
6
7use crate::storage::index::btree_index::BPlusTreeIndex;
8use crate::storage::table_heap::TableHeap;
9use crate::utils::table_ref::TableReference;
10
11/// Global registry of indexes for background maintenance.
12/// Maps (table_ref, index_name) -> (Arc<BPlusTreeIndex>, Arc<TableHeap>)
13#[derive(Debug, Default)]
14pub struct IndexRegistry {
15    inner: DashMap<(TableReference, String), (Arc<BPlusTreeIndex>, Arc<TableHeap>)>,
16}
17
18impl IndexRegistry {
19    pub fn new() -> Self {
20        Self {
21            inner: DashMap::new(),
22        }
23    }
24
25    pub fn register(
26        &self,
27        table: TableReference,
28        name: String,
29        index: Arc<BPlusTreeIndex>,
30        table_heap: Arc<TableHeap>,
31    ) {
32        self.inner.insert((table, name), (index, table_heap));
33    }
34
35    pub fn unregister(&self, table: &TableReference, name: &str) {
36        self.inner.remove(&(table.clone(), name.to_string()));
37    }
38
39    pub fn all(&self) -> Vec<(Arc<BPlusTreeIndex>, Arc<TableHeap>)> {
40        self.inner.iter().map(|e| e.value().clone()).collect()
41    }
42
43    /// Non-allocating iterator over registered indexes.
44    pub fn iter(&self) -> impl Iterator<Item = (Arc<BPlusTreeIndex>, Arc<TableHeap>)> + '_ {
45        self.inner.iter().map(|e| e.value().clone())
46    }
47}
48
49/// Global singleton accessor (for now). In a larger system we would plumb this through Database.
50static REGISTRY: OnceLock<IndexRegistry> = OnceLock::new();
51
52pub fn global_index_registry() -> &'static IndexRegistry {
53    REGISTRY.get_or_init(IndexRegistry::new)
54}
55
56/// Global registry of table heaps that may require background maintenance.
57#[derive(Debug, Default)]
58pub struct TableRegistry {
59    inner: DashMap<TableReference, Arc<TableHeap>>,
60}
61
62impl TableRegistry {
63    pub fn new() -> Self {
64        Self {
65            inner: DashMap::new(),
66        }
67    }
68
69    pub fn register(&self, table: TableReference, heap: Arc<TableHeap>) {
70        self.inner.insert(table, heap);
71    }
72
73    pub fn unregister(&self, table: &TableReference) {
74        self.inner.remove(table);
75    }
76
77    pub fn iter_tables(&self) -> impl Iterator<Item = (TableReference, Arc<TableHeap>)> + '_ {
78        self.inner
79            .iter()
80            .map(|entry| (entry.key().clone(), entry.value().clone()))
81    }
82}
83
84static TABLE_REGISTRY: OnceLock<TableRegistry> = OnceLock::new();
85
86pub fn global_table_registry() -> &'static TableRegistry {
87    TABLE_REGISTRY.get_or_init(TableRegistry::new)
88}