1mod resolve;
10
11use std::sync::Arc;
12
13use uqa_core::memory::BudgetedVec;
14
15use crate::{read_control::StorageReadControl, GraphEntityKind};
16
17use super::{CommitSequence, DatabaseId, MergedRecordSnapshot, VersionResult};
18
19#[derive(Clone, Copy)]
21pub enum GraphMutation<'a> {
22 InvalidateGraph(&'a str),
23 InvalidatePath(&'a str),
24 InvalidateEntity(GraphEntityKind, u64),
25 PublishPath {
26 index: &'a str,
27 graph: &'a str,
28 definition: &'a str,
29 },
30}
31
32#[derive(Clone, Copy)]
34pub enum GraphRecordKey<'a> {
35 Entity(GraphEntityKind, u64),
36 EntityMemberships(GraphEntityKind, u64),
37 GraphMemberships(&'a str),
38 GraphPaths(&'a str),
39 GraphName(&'a str),
40 LabelRegistry(&'a str),
41 PathDefinition(&'a str),
42 PathValidity(&'a str),
43}
44
45pub trait GraphRecordLayout: Send + Sync {
47 fn key(
48 &self,
49 database: DatabaseId,
50 key: GraphRecordKey<'_>,
51 control: &StorageReadControl,
52 ) -> VersionResult<BudgetedVec<u8>>;
53
54 fn is_validity_key(&self, key: &[u8]) -> VersionResult<bool>;
55
56 fn membership_graph(
57 &self,
58 key: &[u8],
59 control: &StorageReadControl,
60 ) -> VersionResult<BudgetedVec<u8>>;
61
62 fn membership_entity(
63 &self,
64 key: &[u8],
65 control: &StorageReadControl,
66 ) -> VersionResult<(GraphEntityKind, u64)>;
67
68 fn path_validity_key(
70 &self,
71 view: &MergedRecordSnapshot,
72 database: DatabaseId,
73 graph: &str,
74 key: &[u8],
75 value: &[u8],
76 control: &StorageReadControl,
77 ) -> VersionResult<Option<BudgetedVec<u8>>>;
78
79 fn invalidate(
80 &self,
81 key: &[u8],
82 value: &[u8],
83 control: &StorageReadControl,
84 ) -> VersionResult<Option<BudgetedVec<u8>>>;
85
86 fn is_published(
88 &self,
89 view: &MergedRecordSnapshot,
90 key: &[u8],
91 value: &[u8],
92 graph: &str,
93 definition: &str,
94 control: &StorageReadControl,
95 ) -> VersionResult<bool>;
96
97 fn definition_matches(
98 &self,
99 key: &[u8],
100 value: &[u8],
101 definition: &str,
102 control: &StorageReadControl,
103 ) -> VersionResult<bool>;
104}
105
106type Text = Arc<BudgetedVec<u8>>;
107
108#[derive(Clone)]
109pub(super) enum OwnedGraphMutation {
110 InvalidateGraph(Text),
111 InvalidatePath(Text),
112 InvalidateEntity(GraphEntityKind, u64),
113 PublishPath {
114 index: Text,
115 graph: Text,
116 definition: Text,
117 },
118}
119
120impl OwnedGraphMutation {
121 pub(super) fn retain(
122 value: GraphMutation<'_>,
123 control: &StorageReadControl,
124 ) -> VersionResult<Self> {
125 let text = |value: &str| {
126 let mut bytes = BudgetedVec::new(control.memory());
127 bytes.extend_from_slice(value.as_bytes())?;
128 Ok::<_, super::VersionError>(Arc::new(bytes))
129 };
130 Ok(match value {
131 GraphMutation::InvalidateGraph(graph) => Self::InvalidateGraph(text(graph)?),
132 GraphMutation::InvalidatePath(index) => Self::InvalidatePath(text(index)?),
133 GraphMutation::InvalidateEntity(kind, id) => Self::InvalidateEntity(kind, id),
134 GraphMutation::PublishPath {
135 index,
136 graph,
137 definition,
138 } => Self::PublishPath {
139 index: text(index)?,
140 graph: text(graph)?,
141 definition: text(definition)?,
142 },
143 })
144 }
145
146 pub(super) fn borrowed(&self) -> GraphMutation<'_> {
147 fn text(bytes: &Text) -> &str {
148 std::str::from_utf8(bytes).expect("retained graph text")
149 }
150 match self {
151 Self::InvalidateGraph(graph) => GraphMutation::InvalidateGraph(text(graph)),
152 Self::InvalidatePath(index) => GraphMutation::InvalidatePath(text(index)),
153 Self::InvalidateEntity(kind, id) => GraphMutation::InvalidateEntity(*kind, *id),
154 Self::PublishPath {
155 index,
156 graph,
157 definition,
158 } => GraphMutation::PublishPath {
159 index: text(index),
160 graph: text(graph),
161 definition: text(definition),
162 },
163 }
164 }
165}
166
167pub(super) struct GraphEffects {
168 pub(super) base: CommitSequence,
169 pub(super) operations: BudgetedVec<OwnedGraphMutation>,
170}
171
172pub(super) use resolve::resolve;