clepsydra/storage.rs
1// Copyright 2020 Graydon Hoare <graydon@pobox.com>
2// Licensed under the MIT and Apache-2.0 licenses.
3
4use crate::{ExtVal, GlobalTime, Lang, ReplicationTag, Sdw};
5use serde::{Deserialize, Serialize};
6
7/// An [Entry] is associated with each [KeyVer] (i.e. a [Lang::Key] at some
8/// [GlobalTime]) in the [Store], and is either an unevaluated expression of
9/// type [Entry::Delayed] (at one of two possible [ReplicationTag] levels), or
10/// an [Entry::Aborted] tombstone (if replication fails), or an [Entry::Settled]
11/// value carrying a fully-evaluated [ExtVal].
12#[serde(bound = "")]
13#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize)]
14pub enum Entry<L: Lang> {
15 Delayed(L::Expr, Vec<L::Val>, ReplicationTag),
16 Settled(ExtVal<L>, ReplicationTag),
17 Aborted,
18}
19
20/// A `KeyVer` is a [Lang::Key] augmented with a [GlobalTime]. All reads and
21/// writes -- both inside the distributed protocol and against the [Store] --
22/// happen in terms of `KeyVer`s.
23#[derive(Clone, Default, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize)]
24pub struct KeyVer<L: Lang> {
25 pub key: L::Key,
26 pub ver: GlobalTime,
27}
28
29impl<L: Lang> std::fmt::Debug for KeyVer<L> {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 f.write_fmt(format_args!("{:?}:{:?}", self.key, self.ver))
32 }
33}
34
35/// A `Store` is responsible for durable storage. Clients of the library should
36/// provide an implementation and pass an instance in to the constructor of
37/// [crate::Database].
38///
39/// Stores are presumed to model something like maps over [KeyVer]s. That is,
40/// they are "multi-version" maps, supporting the "multi-version concurrency
41/// control" (MVCC) protocols, of which Ocean Vista is a distributed variant.
42///
43/// When writing, initially an un-evaluated expression-entry of type
44/// [Entry::Delayed] is written to the `Store`. Later the same `KeyVer` will be
45/// _updated_ with an [Entry::Settled], when watermark time has advanced to
46/// the point that it's safe to [Lang::eval_expr] the delayed expression. If at
47/// any point the writing phase of the transaction aborts, an [Entry::Aborted]
48/// entry will be written instead. All this happens inside the [crate::Database]
49/// though; all Store has to do is write to some backing store.
50pub trait Store<L: Lang>: Send + Sync + 'static {
51 fn get_key_at_or_before_time(&self, kv: &KeyVer<L>) -> Option<(GlobalTime, Entry<L>)>;
52 fn put_key_at_time(&mut self, kv: &KeyVer<L>, v: &Entry<L>);
53 fn get_delayed_watermark(&self) -> Option<Sdw>;
54}