feat: add list notify

Co-authored-by: Zixuan Chen <me@zxch3n.com>
This commit is contained in:
leeeon233 2022-11-24 15:34:23 +08:00
parent e153f113b8
commit 4ed1eaee32
2 changed files with 58 additions and 3 deletions

View file

@ -19,7 +19,8 @@ use crate::{
Container, ContainerID, ContainerType, Container, ContainerID, ContainerType,
}, },
context::Context, context::Context,
event::Index, delta::Delta,
event::{Diff, Index, RawEvent},
hierarchy::Hierarchy, hierarchy::Hierarchy,
id::{ClientID, Counter, ID}, id::{ClientID, Counter, ID},
log_store::ImportContext, log_store::ImportContext,
@ -165,6 +166,27 @@ impl ListContainer {
Some(id) Some(id)
} }
fn notify(
&mut self,
store: &mut LogStore,
diff: Vec<Diff>,
old_version: SmallVec<[ID; 2]>,
new_version: SmallVec<[ID; 2]>,
local: bool,
) {
store.with_hierarchy(|store, hierarchy| {
let event = RawEvent {
diff,
local,
old_version,
new_version,
container_id: self.id.clone(),
};
hierarchy.notify(event, &store.reg);
});
}
fn update_hierarchy_on_delete(&mut self, hierarchy: &mut Hierarchy, pos: usize, len: usize) { fn update_hierarchy_on_delete(&mut self, hierarchy: &mut Hierarchy, pos: usize, len: usize) {
if !hierarchy.has_children(&self.id) { if !hierarchy.has_children(&self.id) {
return; return;
@ -326,13 +348,21 @@ impl Container for ListContainer {
} }
fn apply_tracked_effects_from(&mut self, store: &mut LogStore, import_context: &ImportContext) { fn apply_tracked_effects_from(&mut self, store: &mut LogStore, import_context: &ImportContext) {
let should_notify = store.hierarchy.should_notify(&self.id);
let mut diff = vec![];
for effect in self for effect in self
.tracker .tracker
.iter_effects(&import_context.old_vv, &import_context.spans) .iter_effects(&import_context.old_vv, &import_context.spans)
{ {
match effect { match effect {
Effect::Del { pos, len } => { Effect::Del { pos, len } => {
// Update hierarchy info if should_notify {
let mut delta = Delta::new();
delta.retain(pos);
delta.delete(len);
diff.push(Diff::List(delta));
}
if store.hierarchy.has_children(&self.id) { if store.hierarchy.has_children(&self.id) {
for state in self.state.iter_range(pos, Some(pos + len)) { for state in self.state.iter_range(pos, Some(pos + len)) {
let range = &state.as_ref().0; let range = &state.as_ref().0;
@ -347,7 +377,16 @@ impl Container for ListContainer {
self.state.delete_range(Some(pos), Some(pos + len)); self.state.delete_range(Some(pos), Some(pos + len));
} }
Effect::Ins { pos, content } => { Effect::Ins { pos, content } => {
// Update hierarchy info if should_notify {
let mut delta_vec = vec![];
for value in self.raw_data.slice(&content.0) {
delta_vec.push(value.clone());
}
let mut delta = Delta::new();
delta.retain(pos);
delta.insert(delta_vec);
diff.push(Diff::List(delta));
}
{ {
let content = &content; let content = &content;
for value in self.raw_data.slice(&content.0).iter() { for value in self.raw_data.slice(&content.0).iter() {
@ -361,6 +400,16 @@ impl Container for ListContainer {
} }
} }
} }
if should_notify {
self.notify(
store,
diff,
import_context.old_frontiers.clone(),
import_context.new_frontiers.clone(),
false,
);
}
} }
} }

View file

@ -90,3 +90,9 @@ impl HasLength for String {
self.len() self.len()
} }
} }
impl<T> HasLength for Vec<T> {
fn content_len(&self) -> usize {
self.len()
}
}