mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-05-26 20:49:55 +00:00
refactor(stitched): Move stitcher into its own crate
This commit is contained in:
Generated
+9
-1
@@ -1216,7 +1216,6 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"loole",
|
"loole",
|
||||||
"lru-cache",
|
"lru-cache",
|
||||||
"peg",
|
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"recaptcha-verify",
|
"recaptcha-verify",
|
||||||
"regex",
|
"regex",
|
||||||
@@ -5136,6 +5135,15 @@ version = "1.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stitcher"
|
||||||
|
version = "0.5.3"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"itertools 0.14.0",
|
||||||
|
"peg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strict"
|
name = "strict"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
|||||||
@@ -126,6 +126,3 @@ sd-notify.optional = true
|
|||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
peg = "0.8.5"
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ mod build;
|
|||||||
mod create;
|
mod create;
|
||||||
mod data;
|
mod data;
|
||||||
mod redact;
|
mod redact;
|
||||||
mod stitcher;
|
|
||||||
|
|
||||||
use std::{fmt::Write, sync::Arc};
|
use std::{fmt::Write, sync::Arc};
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
/// Updates to a gap in the stitched order.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) struct GapUpdate<'id, K: OrderKey> {
|
pub struct GapUpdate<'id, K: OrderKey> {
|
||||||
/// The opaque key of the gap to update.
|
/// The opaque key of the gap to update.
|
||||||
pub key: K,
|
pub key: K,
|
||||||
/// The new contents of the gap. If this is empty, the gap should be
|
/// 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.
|
/// Updates to the stitched order.
|
||||||
#[derive(Debug)]
|
#[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
|
/// Updates to individual gaps. The items inserted by these updates _should
|
||||||
/// not_ be synchronized to clients.
|
/// not_ be synchronized to clients.
|
||||||
pub gap_updates: Vec<GapUpdate<'id, K>>,
|
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.
|
/// The stitcher, which implements the stitched ordering algorithm.
|
||||||
/// Its primary method is [`Stitcher::stitch`].
|
/// Its primary method is [`Stitcher::stitch`].
|
||||||
pub(super) struct Stitcher<'backend, B: StitcherBackend> {
|
pub 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`].
|
/// 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
|
/// Given a [`Batch`], compute the [`OrderUpdates`] which should be made to
|
||||||
/// the stitched order to incorporate that batch. It is the responsibility
|
/// the stitched order to incorporate that batch. It is the responsibility
|
||||||
/// of the caller to apply the updates.
|
/// 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 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();
|
||||||
|
|
||||||
@@ -2,16 +2,17 @@ use std::{cmp::Ordering, collections::HashSet};
|
|||||||
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
pub(super) mod algorithm;
|
pub mod algorithm;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test;
|
mod test;
|
||||||
|
pub use algorithm::*;
|
||||||
|
|
||||||
/// A gap in the stitched order.
|
/// A gap in the stitched order.
|
||||||
pub(super) type Gap = HashSet<String>;
|
pub type Gap = HashSet<String>;
|
||||||
|
|
||||||
/// An item in the stitched order.
|
/// An item in the stitched order.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) enum StitchedItem<'id> {
|
pub enum StitchedItem<'id> {
|
||||||
/// A single event.
|
/// A single event.
|
||||||
Event(&'id str),
|
Event(&'id str),
|
||||||
/// A gap representing one or more missing events.
|
/// 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
|
/// An opaque key returned by a [`StitcherBackend`] to identify an item in its
|
||||||
/// order.
|
/// order.
|
||||||
pub(super) trait OrderKey: Eq + Clone {}
|
pub 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.
|
/// A trait providing read-only access to an existing stitched order.
|
||||||
pub(super) trait StitcherBackend {
|
pub trait StitcherBackend {
|
||||||
type Key: OrderKey;
|
type Key: OrderKey;
|
||||||
|
|
||||||
/// Return all gaps containing one or more events listed in `events`.
|
/// 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`.
|
/// 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.
|
/// Information about the `prev_events` of an event.
|
||||||
/// This struct does not store the ID of the event itself.
|
/// 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.
|
/// A batch of events to be inserted into the stitched order.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(super) struct Batch<'id> {
|
pub 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`].
|
/// 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();
|
let mut events = IndexMap::new();
|
||||||
|
|
||||||
for (event, prev_events) in edges {
|
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 {
|
events.insert(*event, EventPredecessors {
|
||||||
prev_events: prev_events.clone(),
|
prev_events: prev_events.clone(),
|
||||||
@@ -3,7 +3,6 @@ use std::sync::atomic::{AtomicU64, Ordering};
|
|||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use super::{algorithm::*, *};
|
use super::{algorithm::*, *};
|
||||||
use crate::rooms::timeline::stitcher::algorithm::Stitcher;
|
|
||||||
|
|
||||||
mod parser;
|
mod parser;
|
||||||
|
|
||||||
@@ -2,7 +2,7 @@ use std::collections::HashSet;
|
|||||||
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
use crate::rooms::timeline::stitcher::StitchedItem;
|
use super::StitchedItem;
|
||||||
|
|
||||||
pub(super) type TestEventId<'id> = &'id str;
|
pub(super) type TestEventId<'id> = &'id str;
|
||||||
|
|
||||||
Reference in New Issue
Block a user