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:
35 files changed
+43
-21
No files matched your search
Generated
+9
-1
@@ -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};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Reference in new issue
Block a user