Skip to main content

uqa_storage/catalog/graph_observations/
definitions.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Catalog presence and definition addresses are independent of graph entity generations.
8
9use std::ops::Bound;
10
11use sha2::{Digest, Sha256};
12
13use super::GraphIdentifierNamespace;
14use crate::mvcc::{SerializableKeySpace, SerializablePredicate};
15
16#[derive(Clone, Copy)]
17pub enum GraphDefinitionKind {
18    NamedGraph,
19    PathIndex,
20    LabelRegistry,
21}
22
23/// A point for one canonical catalog name, or a range for the complete name listing. Fixed size hashes bound retained observations without retaining arbitrary catalog strings.
24pub struct GraphDefinitionKey {
25    object: [u8; 16],
26    lower: [u8; 33],
27    upper: [u8; 33],
28}
29
30impl GraphDefinitionKey {
31    pub fn new(
32        namespace: GraphIdentifierNamespace,
33        kind: GraphDefinitionKind,
34        name: Option<&str>,
35    ) -> Self {
36        let tag = match kind {
37            GraphDefinitionKind::NamedGraph => b'n',
38            GraphDefinitionKind::PathIndex => b'i',
39            GraphDefinitionKind::LabelRegistry => b'r',
40        };
41        let mut lower = [0; 33];
42        let mut upper = [u8::MAX; 33];
43        lower[0] = tag;
44        upper[0] = tag;
45        if let Some(name) = name {
46            lower[1..].copy_from_slice(&Sha256::digest(name.as_bytes()));
47            upper = lower;
48        }
49        Self {
50            object: namespace.serializable_scope_object(),
51            lower,
52            upper,
53        }
54    }
55
56    pub fn predicate(&self) -> SerializablePredicate<'_> {
57        if self.lower == self.upper {
58            return SerializablePredicate::point(
59                self.object,
60                SerializableKeySpace::Graph,
61                &self.lower,
62            );
63        }
64        SerializablePredicate::range(
65            self.object,
66            SerializableKeySpace::Graph,
67            Bound::Included(&self.lower),
68            Bound::Included(&self.upper),
69        )
70    }
71}