mirror of
https://github.com/loro-dev/loro.git
synced 2025-02-02 11:06:14 +00:00
feat: init delta
This commit is contained in:
parent
51a28129a9
commit
1ae9bf2a48
6 changed files with 136 additions and 2 deletions
82
crates/loro-core/src/delta.rs
Normal file
82
crates/loro-core/src/delta.rs
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
use enum_as_inner::EnumAsInner;
|
||||||
|
use rle::{HasLength, Mergable, RleVec};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct Delta<Value, Meta = ()> {
|
||||||
|
vec: RleVec<[DeltaItem<Value, Meta>; 1]>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, EnumAsInner, PartialEq, Eq, Clone)]
|
||||||
|
pub enum DeltaItem<Value, Meta> {
|
||||||
|
Retain { len: usize, meta: Meta },
|
||||||
|
Insert { value: Value, meta: Meta },
|
||||||
|
Delete(usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Value: HasLength, Meta> HasLength for DeltaItem<Value, Meta> {
|
||||||
|
fn content_len(&self) -> usize {
|
||||||
|
match self {
|
||||||
|
DeltaItem::Retain { len, meta: _ } => *len,
|
||||||
|
DeltaItem::Insert { value, meta: _ } => value.atom_len(),
|
||||||
|
DeltaItem::Delete(len) => *len,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Value, Meta> Mergable for DeltaItem<Value, Meta> {}
|
||||||
|
|
||||||
|
impl<Value: HasLength, Meta> Delta<Value, Meta> {
|
||||||
|
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<Item = &DeltaItem<Value, Meta>> {
|
||||||
|
self.vec.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut DeltaItem<Value, Meta>> {
|
||||||
|
self.vec.iter_mut()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn len(&self) -> usize {
|
||||||
|
self.vec.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.len() == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Value: HasLength, Meta> Default for Delta<Value, Meta> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Value: HasLength, Meta: Default> Delta<Value, Meta> {
|
||||||
|
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(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
47
crates/loro-core/src/event.rs
Normal file
47
crates/loro-core/src/event.rs
Normal file
|
@ -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<Diff>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Path = Vec<Index>;
|
||||||
|
|
||||||
|
pub enum Index {
|
||||||
|
Key(InternalString),
|
||||||
|
Index(usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Diff {
|
||||||
|
List(Delta<Vec<LoroValue>>),
|
||||||
|
Text(Delta<String>),
|
||||||
|
Map(MapDiff),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ValuePair {
|
||||||
|
pub old: LoroValue,
|
||||||
|
pub new: LoroValue,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MapDiff {
|
||||||
|
pub added: FxHashMap<InternalString, LoroValue>,
|
||||||
|
pub updated: FxHashMap<InternalString, ValuePair>,
|
||||||
|
pub deleted: FxHashSet<InternalString>,
|
||||||
|
}
|
|
@ -24,6 +24,8 @@ mod span;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod tests;
|
pub mod tests;
|
||||||
|
|
||||||
|
pub mod delta;
|
||||||
|
pub mod event;
|
||||||
mod value;
|
mod value;
|
||||||
|
|
||||||
pub use error::LoroError;
|
pub use error::LoroError;
|
||||||
|
@ -32,6 +34,7 @@ pub(crate) use change::{Lamport, Timestamp};
|
||||||
pub(crate) use id::{ClientID, ID};
|
pub(crate) use id::{ClientID, ID};
|
||||||
pub(crate) use op::{ContentType, InsertContentTrait, Op};
|
pub(crate) use op::{ContentType, InsertContentTrait, Op};
|
||||||
|
|
||||||
|
// TODO: rename as Key?
|
||||||
pub(crate) type InternalString = DefaultAtom;
|
pub(crate) type InternalString = DefaultAtom;
|
||||||
pub(crate) use container::Container;
|
pub(crate) use container::Container;
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ use crate::{
|
||||||
configure::Configure,
|
configure::Configure,
|
||||||
container::{
|
container::{
|
||||||
registry::{ContainerInstance, ContainerRegistry},
|
registry::{ContainerInstance, ContainerRegistry},
|
||||||
Container, ContainerID,
|
ContainerID,
|
||||||
},
|
},
|
||||||
dag::Dag,
|
dag::Dag,
|
||||||
debug_log,
|
debug_log,
|
||||||
|
|
|
@ -30,6 +30,8 @@ use crate::{
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct VersionVector(FxHashMap<ClientID, Counter>);
|
pub struct VersionVector(FxHashMap<ClientID, Counter>);
|
||||||
|
|
||||||
|
pub struct Frontiers(SmallVec<[ID; 1]>);
|
||||||
|
|
||||||
impl PartialEq for VersionVector {
|
impl PartialEq for VersionVector {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.iter()
|
self.iter()
|
||||||
|
|
|
@ -223,7 +223,7 @@ impl<A: Array> Index<usize> for RleVecWithLen<A> {
|
||||||
|
|
||||||
impl<A: Array> PartialEq for RleVec<A>
|
impl<A: Array> PartialEq for RleVec<A>
|
||||||
where
|
where
|
||||||
A::Item: Eq + PartialEq,
|
A::Item: PartialEq,
|
||||||
{
|
{
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.vec == other.vec
|
self.vec == other.vec
|
||||||
|
|
Loading…
Reference in a new issue