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)]
|
||||
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;
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ use crate::{
|
|||
configure::Configure,
|
||||
container::{
|
||||
registry::{ContainerInstance, ContainerRegistry},
|
||||
Container, ContainerID,
|
||||
ContainerID,
|
||||
},
|
||||
dag::Dag,
|
||||
debug_log,
|
||||
|
|
|
@ -30,6 +30,8 @@ use crate::{
|
|||
#[derive(Debug, Clone)]
|
||||
pub struct VersionVector(FxHashMap<ClientID, Counter>);
|
||||
|
||||
pub struct Frontiers(SmallVec<[ID; 1]>);
|
||||
|
||||
impl PartialEq for VersionVector {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.iter()
|
||||
|
|
|
@ -223,7 +223,7 @@ impl<A: Array> Index<usize> for RleVecWithLen<A> {
|
|||
|
||||
impl<A: Array> PartialEq for RleVec<A>
|
||||
where
|
||||
A::Item: Eq + PartialEq,
|
||||
A::Item: PartialEq,
|
||||
{
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.vec == other.vec
|
||||
|
|
Loading…
Reference in a new issue