refactor(stitched): Move stitcher into its own crate
This commit is contained in:
parent
9210ee2b42
commit
4da955438e
35 changed files with 43 additions and 21 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
|
@ -1216,7 +1216,6 @@ dependencies = [
|
|||
"log",
|
||||
"loole",
|
||||
"lru-cache",
|
||||
"peg",
|
||||
"rand 0.8.5",
|
||||
"recaptcha-verify",
|
||||
"regex",
|
||||
|
|
@ -5136,6 +5135,15 @@ version = "1.2.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||
|
||||
[[package]]
|
||||
name = "stitcher"
|
||||
version = "0.5.3"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itertools 0.14.0",
|
||||
"peg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strict"
|
||||
version = "0.2.0"
|
||||
|
|
|
|||
|
|
@ -126,6 +126,3 @@ sd-notify.optional = true
|
|||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
peg = "0.8.5"
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ mod build;
|
|||
mod create;
|
||||
mod data;
|
||||
mod redact;
|
||||
mod stitcher;
|
||||
|
||||
use std::{fmt::Write, sync::Arc};
|
||||
|
||||
|
|
|
|||
18
src/stitcher/Cargo.toml
Normal file
18
src/stitcher/Cargo.toml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
[package]
|
||||
name = "stitcher"
|
||||
description = "An implementation of stitched ordering (https://codeberg.org/andybalaam/stitched-order)"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
readme.workspace = true
|
||||
repository.workspace = true
|
||||
version.workspace = true
|
||||
|
||||
[lib]
|
||||
path = "mod.rs"
|
||||
|
||||
[dependencies]
|
||||
indexmap.workspace = true
|
||||
itertools.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
peg = "0.8.5"
|
||||
|
|
@ -7,7 +7,7 @@ use super::{Batch, Gap, OrderKey, StitchedItem, StitcherBackend};
|
|||
|
||||
/// Updates to a gap in the stitched order.
|
||||
#[derive(Debug)]
|
||||
pub(super) struct GapUpdate<'id, K: OrderKey> {
|
||||
pub struct GapUpdate<'id, K: OrderKey> {
|
||||
/// The opaque key of the gap to update.
|
||||
pub key: K,
|
||||
/// The new contents of the gap. If this is empty, the gap should be
|
||||
|
|
@ -20,7 +20,7 @@ pub(super) struct GapUpdate<'id, K: OrderKey> {
|
|||
|
||||
/// Updates to the stitched order.
|
||||
#[derive(Debug)]
|
||||
pub(super) struct OrderUpdates<'id, K: OrderKey> {
|
||||
pub struct OrderUpdates<'id, K: OrderKey> {
|
||||
/// Updates to individual gaps. The items inserted by these updates _should
|
||||
/// not_ be synchronized to clients.
|
||||
pub gap_updates: Vec<GapUpdate<'id, K>>,
|
||||
|
|
@ -34,18 +34,18 @@ pub(super) struct OrderUpdates<'id, K: OrderKey> {
|
|||
|
||||
/// The stitcher, which implements the stitched ordering algorithm.
|
||||
/// Its primary method is [`Stitcher::stitch`].
|
||||
pub(super) struct Stitcher<'backend, B: StitcherBackend> {
|
||||
pub struct Stitcher<'backend, B: StitcherBackend> {
|
||||
backend: &'backend B,
|
||||
}
|
||||
|
||||
impl<B: StitcherBackend> Stitcher<'_, B> {
|
||||
/// Create a new [`Stitcher`] given a [`StitcherBackend`].
|
||||
pub(super) fn new(backend: &B) -> Stitcher<'_, B> { Stitcher { backend } }
|
||||
pub 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 fn stitch<'id>(&self, batch: &Batch<'id>) -> OrderUpdates<'id, B::Key> {
|
||||
let mut gap_updates = Vec::new();
|
||||
let mut events_added_to_gaps: HashSet<&'id str> = HashSet::new();
|
||||
|
||||
|
|
@ -2,16 +2,17 @@ use std::{cmp::Ordering, collections::HashSet};
|
|||
|
||||
use indexmap::IndexMap;
|
||||
|
||||
pub(super) mod algorithm;
|
||||
pub mod algorithm;
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
pub use algorithm::*;
|
||||
|
||||
/// A gap in the stitched order.
|
||||
pub(super) type Gap = HashSet<String>;
|
||||
pub type Gap = HashSet<String>;
|
||||
|
||||
/// An item in the stitched order.
|
||||
#[derive(Debug)]
|
||||
pub(super) enum StitchedItem<'id> {
|
||||
pub enum StitchedItem<'id> {
|
||||
/// A single event.
|
||||
Event(&'id str),
|
||||
/// A gap representing one or more missing events.
|
||||
|
|
@ -20,12 +21,12 @@ pub(super) enum StitchedItem<'id> {
|
|||
|
||||
/// An opaque key returned by a [`StitcherBackend`] to identify an item in its
|
||||
/// order.
|
||||
pub(super) trait OrderKey: Eq + Clone {}
|
||||
pub trait OrderKey: Eq + Clone {}
|
||||
|
||||
impl<T: Eq + Clone> OrderKey for T {}
|
||||
|
||||
/// A trait providing read-only access to an existing stitched order.
|
||||
pub(super) trait StitcherBackend {
|
||||
pub trait StitcherBackend {
|
||||
type Key: OrderKey;
|
||||
|
||||
/// Return all gaps containing one or more events listed in `events`.
|
||||
|
|
@ -39,7 +40,7 @@ pub(super) trait StitcherBackend {
|
|||
}
|
||||
|
||||
/// An ordered map from an event ID to its `prev_events`.
|
||||
pub(super) type EventEdges<'id> = IndexMap<&'id str, HashSet<&'id str>>;
|
||||
pub type EventEdges<'id> = IndexMap<&'id str, HashSet<&'id str>>;
|
||||
|
||||
/// Information about the `prev_events` of an event.
|
||||
/// This struct does not store the ID of the event itself.
|
||||
|
|
@ -56,17 +57,17 @@ struct EventPredecessors<'id> {
|
|||
|
||||
/// A batch of events to be inserted into the stitched order.
|
||||
#[derive(Debug)]
|
||||
pub(super) struct Batch<'id> {
|
||||
pub struct Batch<'id> {
|
||||
events: IndexMap<&'id str, EventPredecessors<'id>>,
|
||||
}
|
||||
|
||||
impl<'id> Batch<'id> {
|
||||
/// Create a new [`Batch`] from an [`EventEdges`].
|
||||
pub(super) fn from_edges<'edges>(edges: &EventEdges<'edges>) -> Batch<'edges> {
|
||||
pub fn from_edges<'edges>(edges: &EventEdges<'edges>) -> Batch<'edges> {
|
||||
let mut events = IndexMap::new();
|
||||
|
||||
for (event, prev_events) in edges {
|
||||
let predecessor_set = Self::find_predecessor_set(event, &edges);
|
||||
let predecessor_set = Self::find_predecessor_set(event, edges);
|
||||
|
||||
events.insert(*event, EventPredecessors {
|
||||
prev_events: prev_events.clone(),
|
||||
|
|
@ -3,7 +3,6 @@ use std::sync::atomic::{AtomicU64, Ordering};
|
|||
use itertools::Itertools;
|
||||
|
||||
use super::{algorithm::*, *};
|
||||
use crate::rooms::timeline::stitcher::algorithm::Stitcher;
|
||||
|
||||
mod parser;
|
||||
|
||||
|
|
@ -2,7 +2,7 @@ use std::collections::HashSet;
|
|||
|
||||
use indexmap::IndexMap;
|
||||
|
||||
use crate::rooms::timeline::stitcher::StitchedItem;
|
||||
use super::StitchedItem;
|
||||
|
||||
pub(super) type TestEventId<'id> = &'id str;
|
||||
|
||||
Loading…
Add table
Reference in a new issue