From 1ae9bf2a489f1b00d1632f2867921d295cda0ec7 Mon Sep 17 00:00:00 2001 From: Zixuan Chen Date: Wed, 23 Nov 2022 16:26:38 +0800 Subject: [PATCH] feat: init delta --- crates/loro-core/src/delta.rs | 82 +++++++++++++++++++++++++++++++ crates/loro-core/src/event.rs | 47 ++++++++++++++++++ crates/loro-core/src/lib.rs | 3 ++ crates/loro-core/src/log_store.rs | 2 +- crates/loro-core/src/version.rs | 2 + crates/rle/src/rle_vec.rs | 2 +- 6 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 crates/loro-core/src/delta.rs create mode 100644 crates/loro-core/src/event.rs diff --git a/crates/loro-core/src/delta.rs b/crates/loro-core/src/delta.rs new file mode 100644 index 00000000..3cdf3101 --- /dev/null +++ b/crates/loro-core/src/delta.rs @@ -0,0 +1,82 @@ +use enum_as_inner::EnumAsInner; +use rle::{HasLength, Mergable, RleVec}; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Delta { + vec: RleVec<[DeltaItem; 1]>, +} + +#[derive(Debug, EnumAsInner, PartialEq, Eq, Clone)] +pub enum DeltaItem { + Retain { len: usize, meta: Meta }, + Insert { value: Value, meta: Meta }, + Delete(usize), +} + +impl HasLength for DeltaItem { + fn content_len(&self) -> usize { + match self { + DeltaItem::Retain { len, meta: _ } => *len, + DeltaItem::Insert { value, meta: _ } => value.atom_len(), + DeltaItem::Delete(len) => *len, + } + } +} + +impl Mergable for DeltaItem {} + +impl Delta { + pub fn new() -> Self { + Self { vec: RleVec::new() } + } + + pub fn retain_with_meta(&mut self, len: usize, meta: Meta) { + self.vec.push(DeltaItem::Retain { len, meta }); + } + + pub fn insert_with_meta(&mut self, value: Value, meta: Meta) { + self.vec.push(DeltaItem::Insert { value, meta }); + } + + pub fn delete(&mut self, len: usize) { + self.vec.push(DeltaItem::Delete(len)); + } + + pub fn iter(&self) -> impl Iterator> { + self.vec.iter() + } + + pub fn iter_mut(&mut self) -> impl Iterator> { + self.vec.iter_mut() + } + + pub fn len(&self) -> usize { + self.vec.len() + } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } +} + +impl Default for Delta { + fn default() -> Self { + Self::new() + } +} + +impl Delta { + pub fn retain(&mut self, len: usize) { + self.vec.push(DeltaItem::Retain { + len, + meta: Default::default(), + }); + } + + pub fn insert(&mut self, value: Value) { + self.vec.push(DeltaItem::Insert { + value, + meta: Default::default(), + }); + } +} diff --git a/crates/loro-core/src/event.rs b/crates/loro-core/src/event.rs new file mode 100644 index 00000000..7302cdc1 --- /dev/null +++ b/crates/loro-core/src/event.rs @@ -0,0 +1,47 @@ +use fxhash::{FxHashMap, FxHashSet}; + +use crate::{ + container::ContainerID, delta::Delta, id::ContainerIdx, version::Frontiers, InternalString, + LoroValue, +}; + +pub(crate) struct RawEvent { + container_idx: ContainerIdx, + old_version: Frontiers, + new_version: Frontiers, + diff: Diff, +} + +pub struct Event { + pub old_version: Frontiers, + pub new_version: Frontiers, + pub current_target: ContainerID, + pub target: ContainerID, + /// the relative path from current_target to target + pub relative_path: Path, + pub diff: Vec, +} + +pub type Path = Vec; + +pub enum Index { + Key(InternalString), + Index(usize), +} + +pub enum Diff { + List(Delta>), + Text(Delta), + Map(MapDiff), +} + +pub struct ValuePair { + pub old: LoroValue, + pub new: LoroValue, +} + +pub struct MapDiff { + pub added: FxHashMap, + pub updated: FxHashMap, + pub deleted: FxHashSet, +} diff --git a/crates/loro-core/src/lib.rs b/crates/loro-core/src/lib.rs index 0a51629a..0c20dca6 100644 --- a/crates/loro-core/src/lib.rs +++ b/crates/loro-core/src/lib.rs @@ -24,6 +24,8 @@ mod span; #[cfg(test)] pub mod tests; +pub mod delta; +pub mod event; mod value; pub use error::LoroError; @@ -32,6 +34,7 @@ pub(crate) use change::{Lamport, Timestamp}; pub(crate) use id::{ClientID, ID}; pub(crate) use op::{ContentType, InsertContentTrait, Op}; +// TODO: rename as Key? pub(crate) type InternalString = DefaultAtom; pub(crate) use container::Container; diff --git a/crates/loro-core/src/log_store.rs b/crates/loro-core/src/log_store.rs index 520d703c..ff59044e 100644 --- a/crates/loro-core/src/log_store.rs +++ b/crates/loro-core/src/log_store.rs @@ -20,7 +20,7 @@ use crate::{ configure::Configure, container::{ registry::{ContainerInstance, ContainerRegistry}, - Container, ContainerID, + ContainerID, }, dag::Dag, debug_log, diff --git a/crates/loro-core/src/version.rs b/crates/loro-core/src/version.rs index fc7395a5..0baa4a6c 100644 --- a/crates/loro-core/src/version.rs +++ b/crates/loro-core/src/version.rs @@ -30,6 +30,8 @@ use crate::{ #[derive(Debug, Clone)] pub struct VersionVector(FxHashMap); +pub struct Frontiers(SmallVec<[ID; 1]>); + impl PartialEq for VersionVector { fn eq(&self, other: &Self) -> bool { self.iter() diff --git a/crates/rle/src/rle_vec.rs b/crates/rle/src/rle_vec.rs index 6a6cf168..22f53670 100644 --- a/crates/rle/src/rle_vec.rs +++ b/crates/rle/src/rle_vec.rs @@ -223,7 +223,7 @@ impl Index for RleVecWithLen { impl PartialEq for RleVec where - A::Item: Eq + PartialEq, + A::Item: PartialEq, { fn eq(&self, other: &Self) -> bool { self.vec == other.vec