Skip to main content

uqa_storage/catalog/
cache_revisions.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Transaction-visible invalidation generations, without loading catalog payloads.
8
9use std::collections::BTreeMap;
10
11/// Lightweight generations read from the same storage snapshot as catalog and
12/// row data. Providers must advance them atomically with the corresponding
13/// mutation, including direct storage writes, and restore them on rollback.
14/// Missing support is distinct from an empty, unchanged database.
15/// Generations are opaque equality tokens, not clocks or counts. A logical
16/// provider may use the domain at or above [`Self::PRIVATE_GENERATION_BASE`]
17/// for transaction-private changes; rollback restores the prior tokens and
18/// commit replaces them with durable generations.
19#[derive(Clone, Debug, Default, PartialEq, Eq)]
20pub struct CatalogCacheRevisions {
21    pub table_catalog: u64,
22    pub registries: u64,
23    /// Per-graph generations, separate from SQL registries. `None` preserves
24    /// conservative restoration for providers without graph-scoped tracking.
25    pub graphs: Option<BTreeMap<String, u64>>,
26    pub table_data: BTreeMap<String, u64>,
27    /// Last committed change of each table's data generation on this snapshot,
28    /// even when its visible generation is private. An absent entry supplies no
29    /// certificate. The database and sequence let a reader recognize data it
30    /// already observed, including its own commit adopted without catalog reads.
31    pub table_data_commits:
32        BTreeMap<String, (crate::mvcc::DatabaseId, crate::mvcc::CommitSequence)>,
33    pub column_statistics: BTreeMap<String, u64>,
34    pub statistics_maintenance: BTreeMap<String, u64>,
35    /// Physical schema changes also invalidate bindings, even when a caller
36    /// changed the storage schema without an ordinary catalog operation.
37    pub storage_schema: u64,
38}
39
40impl CatalogCacheRevisions {
41    /// The first generation of the domain reserved for changes private to the reading transaction. Durable generations stay below it.
42    pub const PRIVATE_GENERATION_BASE: u64 = 1 << 63;
43
44    /// Whether `generation` identifies a change private to the reading transaction instead of a committed generation.
45    pub fn is_private_generation(generation: u64) -> bool {
46        generation >= Self::PRIVATE_GENERATION_BASE
47    }
48}