minerva 0.2.0

Causal ordering for distributed systems
extern crate alloc;

use super::super::support::dot;
use crate::metis::{Dot, DotMap, DotSet, Dotted};

mod boundary;
mod dot_map;
mod flow;

/// The observed-remove document shape the examples exercise: caller keys over
/// bare presence dots.
type Doc = Dotted<DotMap<u8, DotSet>>;

/// A one-dot set, for building write deltas declaratively.
fn dots(pairs: &[(u32, u64)]) -> DotSet {
    let mut set = DotSet::new();
    for &(station, counter) in pairs {
        assert!(set.insert(dot(station, counter)));
    }
    set
}

/// Runs the documented write flow on `doc`: assign the next dot for
/// `station`, wrap it under `key` as a pure write delta, merge it in, and
/// return both the applied delta (for shipping) and the dot.
fn add(doc: &mut Doc, station: u32, key: u8) -> (Doc, Dot) {
    let fresh = doc.next_dot(station);
    let delta = Dotted::from_store(DotMap::singleton(
        key,
        dots(&[(fresh.station(), fresh.counter())]),
    ));
    *doc = doc.merge(&delta);
    (delta, fresh)
}

/// Runs the observed-remove flow on `doc`: supersede exactly the dots it
/// currently holds under `key`, returning the removal delta.
fn remove_observed(doc: &mut Doc, key: u8) -> Doc {
    let observed = doc.store().get(&key).cloned().unwrap_or_default();
    let delta = Dotted::from_context(observed);
    *doc = doc.merge(&delta);
    delta
}