1use alloc::{boxed::Box, string::String, vec::Vec};
9use core::{fmt, ops::Deref};
10
11use buggy::{Bug, BugExt as _};
12use serde::{Deserialize, Serialize};
13
14use crate::{Address, CmdId, Command, PolicyId, Prior};
15
16pub mod linear;
17pub mod memory;
18
19#[cfg(feature = "low-mem-usage")]
20pub const MAX_COMMAND_LENGTH: usize = 400;
21#[cfg(not(feature = "low-mem-usage"))]
22pub const MAX_COMMAND_LENGTH: usize = 2048;
23
24aranya_crypto::custom_id! {
25 pub struct GraphId;
27}
28
29#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
30#[repr(transparent)]
31pub struct SegmentIndex(pub usize);
32
33impl fmt::Display for SegmentIndex {
34 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35 fmt::Display::fmt(&self.0, f)
36 }
37}
38
39#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
40#[repr(transparent)]
41pub struct MaxCut(pub usize);
42
43impl fmt::Display for MaxCut {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 fmt::Display::fmt(&self.0, f)
46 }
47}
48
49impl MaxCut {
50 #[must_use]
52 pub fn checked_add(self, other: usize) -> Option<Self> {
53 self.0.checked_add(other).map(Self)
54 }
55
56 #[must_use]
58 pub fn decremented(self) -> Option<Self> {
59 self.0.checked_sub(1).map(Self)
60 }
61
62 #[must_use]
64 pub fn distance_from(self, other: Self) -> Option<usize> {
65 self.0.checked_sub(other.0)
66 }
67}
68
69#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
70pub struct Location {
71 pub segment: SegmentIndex,
72 pub max_cut: MaxCut,
73}
74
75impl From<(SegmentIndex, MaxCut)> for Location {
76 fn from((segment, max_cut): (SegmentIndex, MaxCut)) -> Self {
77 Self::new(segment, max_cut)
78 }
79}
80
81impl AsRef<Self> for Location {
82 fn as_ref(&self) -> &Self {
83 self
84 }
85}
86
87impl Location {
88 pub fn new(segment: SegmentIndex, max_cut: MaxCut) -> Self {
89 Self { segment, max_cut }
90 }
91
92 pub fn same_segment(self, other: Self) -> bool {
94 self.segment == other.segment
95 }
96}
97
98impl fmt::Display for Location {
99 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
100 write!(f, "{}:{}", self.segment, self.max_cut)
101 }
102}
103
104#[derive(Debug, PartialEq, Eq, thiserror::Error)]
106pub enum StorageError {
107 #[error("storage already exists")]
108 StorageExists,
109 #[error("no such storage")]
110 NoSuchStorage,
111 #[error("segment index {} is out of bounds", .0.segment)]
112 SegmentOutOfBounds(Location),
113 #[error("max cut {} is out of bounds in segment {}", .0.max_cut, .0.segment)]
114 CommandOutOfBounds(Location),
115 #[error("IO error")]
116 IoError,
117 #[error("not a merge command")]
118 NotMerge,
119 #[error("command with id {0} not found")]
120 NoSuchId(CmdId),
121 #[error("policy mismatch")]
122 PolicyMismatch,
123 #[error("cannot write an empty perspective")]
124 EmptyPerspective,
125 #[error("segment must be a descendant of the head for commit")]
126 HeadNotAncestor,
127 #[error("command's parents do not match the perspective head")]
128 PerspectiveHeadMismatch,
129 #[error(transparent)]
130 Bug(#[from] Bug),
131}
132
133pub trait StorageProvider {
135 type Perspective: Perspective + Revertable;
136 type Segment: Segment;
137 type Storage: Storage<
138 Segment = Self::Segment,
139 Perspective = Self::Perspective,
140 FactIndex = <Self::Segment as Segment>::FactIndex,
141 >;
142
143 fn new_perspective(&mut self, policy_id: PolicyId) -> Self::Perspective;
149
150 fn new_storage(
157 &mut self,
158 init: Self::Perspective,
159 ) -> Result<(GraphId, &mut Self::Storage), StorageError>;
160
161 fn get_storage(&mut self, graph: GraphId) -> Result<&mut Self::Storage, StorageError>;
167
168 fn remove_storage(&mut self, graph: GraphId) -> Result<(), StorageError>;
174
175 fn list_graph_ids(
178 &mut self,
179 ) -> Result<impl Iterator<Item = Result<GraphId, StorageError>>, StorageError>;
180}
181
182pub trait Storage {
185 type Perspective: Perspective + Revertable;
186 type FactPerspective: FactPerspective;
187 type Segment: Segment<FactIndex = Self::FactIndex>;
188 type FactIndex: FactIndex;
189
190 fn get_location(&self, address: Address) -> Result<Option<Location>, StorageError> {
193 self.get_location_from(self.get_head()?, address)
194 }
195
196 fn get_location_from(
198 &self,
199 start: Location,
200 address: Address,
201 ) -> Result<Option<Location>, StorageError> {
202 let mut queue = Vec::new();
203 queue.push(start);
204 'outer: while let Some(loc) = queue.pop() {
205 let head = self.get_segment(loc)?;
206 if address.max_cut > head.longest_max_cut()? {
207 continue;
208 }
209 if let Some(loc) = head.get_by_address(address) {
210 return Ok(Some(loc));
211 }
212 for skip in head.skip_list() {
215 if skip.max_cut >= address.max_cut {
216 queue.push(*skip);
217 continue 'outer;
218 }
219 }
220 queue.extend(head.prior());
221 }
222 Ok(None)
223 }
224
225 fn get_command_address(&self, location: Location) -> Result<Address, StorageError> {
229 let segment = self.get_segment(location)?;
230 let command = segment
231 .get_command(location)
232 .ok_or(StorageError::CommandOutOfBounds(location))?;
233 let address = command.address()?;
234 Ok(address)
235 }
236
237 fn get_linear_perspective(&self, parent: Location) -> Result<Self::Perspective, StorageError>;
239
240 fn get_fact_perspective(&self, first: Location) -> Result<Self::FactPerspective, StorageError>;
243
244 fn new_merge_perspective(
246 &self,
247 left: Location,
248 right: Location,
249 last_common_ancestor: Location,
250 policy_id: PolicyId,
251 braid: Self::FactIndex,
252 ) -> Result<Self::Perspective, StorageError>;
253
254 fn get_segment(&self, location: Location) -> Result<Self::Segment, StorageError>;
256
257 fn get_head(&self) -> Result<Location, StorageError>;
259
260 fn get_head_address(&self) -> Result<Address, StorageError> {
262 self.get_command_address(self.get_head()?)
263 }
264
265 fn commit(&mut self, segment: Self::Segment) -> Result<(), StorageError>;
268
269 fn write(&mut self, perspective: Self::Perspective) -> Result<Self::Segment, StorageError>;
271
272 fn write_facts(
274 &mut self,
275 fact_perspective: Self::FactPerspective,
276 ) -> Result<Self::FactIndex, StorageError>;
277
278 fn is_ancestor(
280 &self,
281 search_location: Location,
282 segment: &Self::Segment,
283 ) -> Result<bool, StorageError> {
284 self.get_segment(search_location)?
287 .get_command(search_location)
288 .assume("location must exist")?;
289 let mut queue = Vec::new();
290 queue.extend(segment.prior());
291 'outer: while let Some(location) = queue.pop() {
292 if location.segment == search_location.segment
293 && location.max_cut >= search_location.max_cut
294 {
295 return Ok(true);
296 }
297 let segment = self.get_segment(location)?;
298 if search_location.max_cut > segment.longest_max_cut()? {
299 continue;
300 }
301 for skip in segment.skip_list() {
302 if skip.max_cut >= search_location.max_cut {
303 queue.push(*skip);
304 continue 'outer;
305 }
306 }
307 queue.extend(segment.prior());
308 }
309 Ok(false)
310 }
311}
312
313pub trait Segment {
323 type FactIndex: FactIndex;
324 type Command<'a>: Command
325 where
326 Self: 'a;
327
328 fn index(&self) -> SegmentIndex;
330
331 fn head_id(&self) -> CmdId;
333
334 fn policy(&self) -> PolicyId;
336
337 fn prior(&self) -> Prior<Location>;
339
340 fn get_command(&self, location: Location) -> Option<Self::Command<'_>>;
342
343 fn facts(&self) -> Result<Self::FactIndex, StorageError>;
345
346 fn shortest_max_cut(&self) -> MaxCut;
350
351 fn longest_max_cut(&self) -> Result<MaxCut, StorageError>;
355
356 fn skip_list(&self) -> &[Location];
365
366 fn get_from(&self, location: Location) -> Vec<Self::Command<'_>> {
368 let segment = location.segment;
369 core::iter::successors(Some(location.max_cut), |max_cut| max_cut.checked_add(1))
370 .map_while(|max_cut| self.get_command(Location { segment, max_cut }))
371 .collect()
372 }
373
374 fn get_by_address(&self, address: Address) -> Option<Location> {
376 let loc = Location::new(self.index(), address.max_cut);
377 let cmd = self.get_command(loc)?;
378 if cmd.id() != address.id {
379 return None;
380 }
381 Some(loc)
382 }
383
384 fn first_location(&self) -> Location {
386 Location {
387 segment: self.index(),
388 max_cut: self.shortest_max_cut(),
389 }
390 }
391
392 fn head_location(&self) -> Result<Location, StorageError> {
394 Ok(Location {
395 segment: self.index(),
396 max_cut: self.longest_max_cut()?,
397 })
398 }
399
400 fn head_address(&self) -> Result<Address, StorageError> {
402 Ok(Address {
403 id: self.head_id(),
404 max_cut: self.longest_max_cut()?,
405 })
406 }
407
408 #[must_use]
410 fn previous(&self, mut location: Location) -> Option<Location> {
411 debug_assert_eq!(location.segment, self.index());
412 if location.max_cut <= self.shortest_max_cut() {
413 return None;
414 }
415 location.max_cut = location.max_cut.decremented()?;
416 Some(location)
417 }
418}
419
420pub trait FactIndex: Query {}
422
423pub trait Perspective: FactPerspective {
426 fn policy(&self) -> PolicyId;
428
429 fn add_command(&mut self, command: &impl Command) -> Result<usize, StorageError>;
432
433 fn includes(&self, id: CmdId) -> bool;
435
436 fn head_address(&self) -> Result<Prior<Address>, Bug>;
438}
439
440pub trait FactPerspective: QueryMut {}
442
443pub trait Revertable {
446 fn checkpoint(&self) -> Checkpoint;
448
449 fn revert(&mut self, checkpoint: Checkpoint) -> Result<(), Bug>;
451}
452
453pub struct Checkpoint {
455 pub index: usize,
457}
458
459pub trait Query {
466 fn query(&self, name: &str, keys: &[Box<[u8]>]) -> Result<Option<Box<[u8]>>, StorageError>;
468
469 type QueryIterator: Iterator<Item = Result<Fact, StorageError>>;
471
472 fn query_prefix(
477 &self,
478 name: &str,
479 prefix: &[Box<[u8]>],
480 ) -> Result<Self::QueryIterator, StorageError>;
481}
482
483#[derive(Debug, PartialEq, Eq)]
485pub struct Fact {
486 pub key: Keys,
488 pub value: Box<[u8]>,
490}
491
492pub trait QueryMut: Query {
496 fn insert(&mut self, name: String, keys: Keys, value: Box<[u8]>);
500
501 fn delete(&mut self, name: String, keys: Keys);
503}
504
505#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
507pub struct Keys(Box<[Box<[u8]>]>);
508
509impl Deref for Keys {
510 type Target = [Box<[u8]>];
511 fn deref(&self) -> &[Box<[u8]>] {
512 self.0.as_ref()
513 }
514}
515
516impl AsRef<[Box<[u8]>]> for Keys {
517 fn as_ref(&self) -> &[Box<[u8]>] {
518 self.0.as_ref()
519 }
520}
521
522impl core::borrow::Borrow<[Box<[u8]>]> for Keys {
523 fn borrow(&self) -> &[Box<[u8]>] {
524 self.0.as_ref()
525 }
526}
527
528impl From<&[&[u8]]> for Keys {
529 fn from(value: &[&[u8]]) -> Self {
530 value.iter().copied().collect()
531 }
532}
533
534impl Keys {
535 fn starts_with(&self, prefix: &[Box<[u8]>]) -> bool {
536 self.as_ref().starts_with(prefix)
537 }
538}
539
540impl<B: Into<Box<[u8]>>> FromIterator<B> for Keys {
541 fn from_iter<T: IntoIterator<Item = B>>(iter: T) -> Self {
542 Self(iter.into_iter().map(Into::into).collect())
543 }
544}
545
546