Skip to main content

coven_merge/
sequence.rs

1//! Authored causality and first-claim ordering in the store sequence.
2
3use crate::{Slot, WriteId, WritePast};
4
5/// Publication order of a unique value's input setter (§9.2).
6/// Local writes follow every published claim, in their original number order.
7#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
8pub enum ClaimOrder {
9    /// A counted write in the shared sequence.
10    Published {
11        /// Its containing slot.
12        slot: Slot,
13        /// Its author's write number within the slot.
14        number: u64,
15    },
16    /// An original still in this installation's queue.
17    Local {
18        /// Its local write number.
19        number: u64,
20    },
21}
22
23/// The authored prefix plus the author's earlier originals (§7.1).
24/// A later publication never enlarges that prefix.
25pub fn had_read(reader: WriteId, read_through: u64, earlier: WriteId, slot: Option<Slot>) -> bool {
26    (reader.device == earlier.device && earlier.number < reader.number)
27        || slot.is_some_and(|slot| slot.get() <= read_through)
28}
29
30/// A sequence past backed by the consumer's write-to-slot lookup.
31/// `latest` names the greatest timestamp in the authored prefix and own past,
32/// not necessarily the write in its last slot.
33pub struct SlotPast<F> {
34    reader: WriteId,
35    read_through: u64,
36    slot: F,
37    latest: Option<WriteId>,
38}
39
40impl<F: Fn(&WriteId) -> Option<Slot>> SlotPast<F> {
41    /// Construct the past from authored metadata and its timestamp maximum.
42    pub fn new(reader: WriteId, read_through: u64, slot: F, latest: Option<WriteId>) -> Self {
43        Self { reader, read_through, slot, latest }
44    }
45}
46
47impl<F: Fn(&WriteId) -> Option<Slot>> WritePast for SlotPast<F> {
48    fn contains(&self, write: &WriteId) -> bool {
49        had_read(self.reader, self.read_through, *write, (self.slot)(write))
50    }
51
52    fn frontier(&self) -> impl Iterator<Item = &WriteId> {
53        self.latest.iter()
54    }
55}
56
57#[cfg(test)]
58#[path = "sequence_tests.rs"]
59mod tests;