1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// Copyright 2020 Graydon Hoare <graydon@pobox.com>
// Licensed under the MIT and Apache-2.0 licenses.

use crate::{ExtVal, GlobalTime, Lang, ReplicationTag, Sdw};
use serde::{Deserialize, Serialize};

/// An [Entry] is associated with each [KeyVer] (i.e. a [Lang::Key] at some
/// [GlobalTime]) in the [Store], and is either an unevaluated expression of
/// type [Entry::Delayed] (at one of two possible [ReplicationTag] levels), or
/// an [Entry::Aborted] tombstone (if replication fails), or an [Entry::Settled]
/// value carrying a fully-evaluated [ExtVal].
#[serde(bound = "")]
#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Entry<L: Lang> {
    Delayed(L::Expr, Vec<L::Val>, ReplicationTag),
    Settled(ExtVal<L>, ReplicationTag),
    Aborted,
}

/// A `KeyVer` is a [Lang::Key] augmented with a [GlobalTime]. All reads and
/// writes -- both inside the distributed protocol and against the [Store] --
/// happen in terms of `KeyVer`s.
#[derive(Clone, Default, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct KeyVer<L: Lang> {
    pub key: L::Key,
    pub ver: GlobalTime,
}

impl<L: Lang> std::fmt::Debug for KeyVer<L> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_fmt(format_args!("{:?}:{:?}", self.key, self.ver))
    }
}

/// A `Store` is responsible for durable storage. Clients of the library should
/// provide an implementation and pass an instance in to the constructor of
/// [crate::Database].
///
/// Stores are presumed to model something like maps over [KeyVer]s. That is,
/// they are "multi-version" maps, supporting the "multi-version concurrency
/// control" (MVCC) protocols, of which Ocean Vista is a distributed variant.
///
/// When writing, initially an un-evaluated expression-entry of type
/// [Entry::Delayed] is written to the `Store`. Later the same `KeyVer` will be
/// _updated_ with an [Entry::Settled], when watermark time has advanced to
/// the point that it's safe to [Lang::eval_expr] the delayed expression. If at
/// any point the writing phase of the transaction aborts, an [Entry::Aborted]
/// entry will be written instead. All this happens inside the [crate::Database]
/// though; all Store has to do is write to some backing store.
pub trait Store<L: Lang>: Send + Sync + 'static {
    fn get_key_at_or_before_time(&self, kv: &KeyVer<L>) -> Option<(GlobalTime, Entry<L>)>;
    fn put_key_at_time(&mut self, kv: &KeyVer<L>, v: &Entry<L>);
    fn get_delayed_watermark(&self) -> Option<Sdw>;
}