chore(stitched): Add doc comments

This commit is contained in:
Ginger
2026-01-22 13:08:17 -05:00
parent b60af7c282
commit 9210ee2b42
3 changed files with 30 additions and 7 deletions
@@ -32,13 +32,19 @@ pub(super) struct OrderUpdates<'id, K: OrderKey> {
pub events_added_to_gaps: HashSet<&'id str>, pub events_added_to_gaps: HashSet<&'id str>,
} }
/// The stitcher, which implements the stitched ordering algorithm.
/// Its primary method is [`Stitcher::stitch`].
pub(super) struct Stitcher<'backend, B: StitcherBackend> { pub(super) struct Stitcher<'backend, B: StitcherBackend> {
backend: &'backend B, backend: &'backend B,
} }
impl<B: StitcherBackend> Stitcher<'_, B> { impl<B: StitcherBackend> Stitcher<'_, B> {
/// Create a new [`Stitcher`] given a [`StitcherBackend`].
pub(super) fn new(backend: &B) -> Stitcher<'_, B> { Stitcher { backend } } pub(super) fn new(backend: &B) -> Stitcher<'_, B> { Stitcher { backend } }
/// Given a [`Batch`], compute the [`OrderUpdates`] which should be made to
/// the stitched order to incorporate that batch. It is the responsibility
/// of the caller to apply the updates.
pub(super) fn stitch<'id>(&self, batch: &Batch<'id>) -> OrderUpdates<'id, B::Key> { pub(super) fn stitch<'id>(&self, batch: &Batch<'id>) -> OrderUpdates<'id, B::Key> {
let mut gap_updates = Vec::new(); let mut gap_updates = Vec::new();
let mut events_added_to_gaps: HashSet<&'id str> = HashSet::new(); let mut events_added_to_gaps: HashSet<&'id str> = HashSet::new();
+23 -7
View File
@@ -9,9 +9,12 @@ mod test;
/// A gap in the stitched order. /// A gap in the stitched order.
pub(super) type Gap = HashSet<String>; pub(super) type Gap = HashSet<String>;
/// An item in the stitched order.
#[derive(Debug)] #[derive(Debug)]
pub(super) enum StitchedItem<'id> { pub(super) enum StitchedItem<'id> {
/// A single event.
Event(&'id str), Event(&'id str),
/// A gap representing one or more missing events.
Gap(Gap), Gap(Gap),
} }
@@ -21,16 +24,17 @@ pub(super) trait OrderKey: Eq + Clone {}
impl<T: Eq + Clone> OrderKey for T {} impl<T: Eq + Clone> OrderKey for T {}
/// A trait providing read-only access to an existing stitched order.
pub(super) trait StitcherBackend { pub(super) trait StitcherBackend {
type Key: OrderKey; type Key: OrderKey;
/// Returns all gaps containing an event listed in `events`. /// Return all gaps containing one or more events listed in `events`.
fn find_matching_gaps<'a>( fn find_matching_gaps<'a>(
&'a self, &'a self,
events: impl Iterator<Item = &'a str>, events: impl Iterator<Item = &'a str>,
) -> impl Iterator<Item = (Self::Key, Gap)>; ) -> impl Iterator<Item = (Self::Key, Gap)>;
/// Returns whether an event exists in the stitched order. /// Return whether an event exists in the stitched order.
fn event_exists<'a>(&'a self, event: &'a str) -> bool; fn event_exists<'a>(&'a self, event: &'a str) -> bool;
} }
@@ -43,18 +47,21 @@ pub(super) type EventEdges<'id> = IndexMap<&'id str, HashSet<&'id str>>;
struct EventPredecessors<'id> { struct EventPredecessors<'id> {
/// The `prev_events` of the event. /// The `prev_events` of the event.
pub prev_events: HashSet<&'id str>, pub prev_events: HashSet<&'id str>,
/// The predecessor set of the event. This is a superset of /// The predecessor set of the event. This is derived from, and a superset
/// [`EventPredecessors::prev_events`]. See [`Batch::find_predecessor_set`] /// of, [`EventPredecessors::prev_events`]. See
/// for details. /// [`Batch::find_predecessor_set`] for details. It is cached in this
/// struct for performance.
pub predecessor_set: HashSet<&'id str>, pub predecessor_set: HashSet<&'id str>,
} }
/// A batch of events to be inserted into the stitched order.
#[derive(Debug)] #[derive(Debug)]
pub(super) struct Batch<'id> { pub(super) struct Batch<'id> {
events: IndexMap<&'id str, EventPredecessors<'id>>, events: IndexMap<&'id str, EventPredecessors<'id>>,
} }
impl<'id> Batch<'id> { impl<'id> Batch<'id> {
/// Create a new [`Batch`] from an [`EventEdges`].
pub(super) fn from_edges<'edges>(edges: &EventEdges<'edges>) -> Batch<'edges> { pub(super) fn from_edges<'edges>(edges: &EventEdges<'edges>) -> Batch<'edges> {
let mut events = IndexMap::new(); let mut events = IndexMap::new();
@@ -106,10 +113,13 @@ impl<'id> Batch<'id> {
predecessor_set predecessor_set
} }
/// Iterate over all the events contained in this batch.
fn events(&self) -> impl Iterator<Item = &'id str> { self.events.keys().copied() } fn events(&self) -> impl Iterator<Item = &'id str> { self.events.keys().copied() }
/// Check whether an event exists in this batch.
fn contains(&self, event: &'id str) -> bool { self.events.contains_key(event) } fn contains(&self, event: &'id str) -> bool { self.events.contains_key(event) }
/// Return the predecessors of an event, if it exists in this batch.
fn predecessors(&self, event: &str) -> Option<&EventPredecessors<'id>> { fn predecessors(&self, event: &str) -> Option<&EventPredecessors<'id>> {
self.events.get(event) self.events.get(event)
} }
@@ -131,8 +141,14 @@ impl<'id> Batch<'id> {
{ {
Ordering::Less Ordering::Less
} else { } else {
let a_index = self.events.get_index_of(a).expect("a should be in events"); let a_index = self
let b_index = self.events.get_index_of(b).expect("b should be in events"); .events
.get_index_of(a)
.expect("a should be in this batch");
let b_index = self
.events
.get_index_of(b)
.expect("b should be in this batch");
a_index.cmp(&b_index) a_index.cmp(&b_index)
} }
@@ -7,6 +7,7 @@ use crate::rooms::timeline::stitcher::algorithm::Stitcher;
mod parser; mod parser;
/// A stitcher backend which holds a stitched ordering in RAM.
#[derive(Default)] #[derive(Default)]
struct TestStitcherBackend<'id> { struct TestStitcherBackend<'id> {
items: Vec<(u64, StitchedItem<'id>)>, items: Vec<(u64, StitchedItem<'id>)>,