Skip to main content

uqa_storage/catalog/
graph_access.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Indexed graph reads. Entity payloads are fetched separately from bounded
8//! identity scans so traversal never requires a resident graph replica.
9
10use crate::{StorageBackendError, StorageBackendResult};
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum GraphEntityKind {
14    Vertex,
15    Edge,
16}
17
18impl GraphEntityKind {
19    pub fn as_str(self) -> &'static str {
20        match self {
21            Self::Vertex => "vertex",
22            Self::Edge => "edge",
23        }
24    }
25}
26
27/// Conjunctive, storage-side filters over graph entity identities. `None`
28/// means no restriction; an empty label is an ordinary exact label value.
29#[derive(Debug, Clone, Copy)]
30pub struct GraphEntityFilter<'a> {
31    pub kind: GraphEntityKind,
32    pub graph: Option<&'a str>,
33    pub label: Option<&'a str>,
34    pub source: Option<u64>,
35    pub target: Option<u64>,
36}
37
38impl<'a> GraphEntityFilter<'a> {
39    pub fn new(kind: GraphEntityKind, graph: Option<&'a str>) -> Self {
40        Self {
41            kind,
42            graph,
43            label: None,
44            source: None,
45            target: None,
46        }
47    }
48
49    pub fn validate(self) -> StorageBackendResult<()> {
50        if self.kind == GraphEntityKind::Vertex && (self.source.is_some() || self.target.is_some())
51        {
52            return Err(StorageBackendError::Other(
53                "vertex scans cannot have edge endpoint filters".into(),
54            ));
55        }
56        Ok(())
57    }
58}
59
60/// Upper bound on one graph identity page; callers advance with the last id.
61pub const MAX_GRAPH_ID_PAGE: usize = 4096;
62
63pub fn validate_graph_page(limit: usize) -> StorageBackendResult<()> {
64    if !(1..=MAX_GRAPH_ID_PAGE).contains(&limit) {
65        return Err(StorageBackendError::Other(format!(
66            "graph identity page size must be in 1..={MAX_GRAPH_ID_PAGE}"
67        )));
68    }
69    Ok(())
70}