Skip to content

Commit

Permalink
perf: don't extract changed crdt item when apply update (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
forehalo authored Dec 25, 2023
1 parent dae318a commit 3764b25
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 29 deletions.
4 changes: 2 additions & 2 deletions y-octo-node/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ export class Doc {
createArray(): YArray
createText(): YText
createMap(): YMap
applyUpdate(update: Buffer): Buffer
encodeUpdateV1(): Buffer
applyUpdate(update: Buffer): void
encodeStateAsUpdateV1(state?: Buffer | undefined | null): Buffer
gc(): void
onUpdate(callback: (result: Uint8Array) => void): void
}
Expand Down
27 changes: 16 additions & 11 deletions y-octo-node/src/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use napi::{
bindgen_prelude::{Buffer as JsBuffer, JsFunction},
threadsafe_function::{ErrorStrategy, ThreadsafeFunction, ThreadsafeFunctionCallMode},
};
use y_octo::{Doc as YDoc, History};
use y_octo::{CrdtRead, Doc as YDoc, History, RawDecoder, StateVector};

use super::*;

Expand Down Expand Up @@ -85,19 +85,24 @@ impl Doc {
}

#[napi]
pub fn apply_update(&mut self, update: JsBuffer) -> Result<JsBuffer> {
self.doc
.apply_update_from_binary_v1(update)
.and_then(|u| u.encode_v1().map(|v| v.into()))
.map_err(anyhow::Error::from)
pub fn apply_update(&mut self, update: JsBuffer) -> Result<()> {
self.doc.apply_update_from_binary_v1(update)?;

Ok(())
}

#[napi]
pub fn encode_update_v1(&self) -> Result<JsBuffer> {
self.doc
.encode_update_v1()
.map(|v| v.into())
.map_err(anyhow::Error::from)
pub fn encode_state_as_update_v1(&self, state: Option<JsBuffer>) -> Result<JsBuffer> {
let result = match state {
Some(state) => {
let mut decoder = RawDecoder::new(state.as_ref());
let state = StateVector::read(&mut decoder)?;
self.doc.encode_state_as_update_v1(&state)
}
None => self.doc.encode_update_v1(),
};

result.map(|v| v.into()).map_err(anyhow::Error::from)
}

#[napi]
Expand Down
2 changes: 1 addition & 1 deletion y-octo-node/tests/doc.spec.mts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ test("doc test", { concurrency: false }, async (t) => {
text.insert(2, "c");

let doc2 = new Doc(client_id);
doc2.applyUpdate(doc.encodeUpdateV1());
doc2.applyUpdate(doc.encodeStateAsUpdateV1());

let array2 = doc2.getOrCreateArray("array");
let map2 = doc2.getOrCreateMap("map");
Expand Down
2 changes: 1 addition & 1 deletion y-octo-node/tests/map.spec.mts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ test("map test", { concurrency: false }, async (t) => {
sub_text.insert(2, "c");

let doc2 = new Y.Doc();
Y.applyUpdate(doc2, doc.encodeUpdateV1());
Y.applyUpdate(doc2, doc.encodeStateAsUpdateV1());

let map2 = doc2.getMap<any>("map");
let sub_array2 = map2.get("array") as Y.Array<any>;
Expand Down
7 changes: 3 additions & 4 deletions y-octo/src/doc/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,16 +220,15 @@ impl Doc {
Ok(doc)
}

pub fn apply_update_from_binary_v1<T: AsRef<[u8]>>(&mut self, binary: T) -> JwstCodecResult<Update> {
pub fn apply_update_from_binary_v1<T: AsRef<[u8]>>(&mut self, binary: T) -> JwstCodecResult {
let mut decoder = RawDecoder::new(binary.as_ref());
let update = Update::read(&mut decoder)?;
self.apply_update(update)
}

pub fn apply_update(&mut self, mut update: Update) -> JwstCodecResult<Update> {
pub fn apply_update(&mut self, mut update: Update) -> JwstCodecResult {
let mut store = self.store.write().unwrap();
let mut retry = false;
let before_state = store.get_state_vector();
loop {
for (mut s, offset) in update.iter(store.get_state_vector()) {
if let Node::Item(item) = &mut s {
Expand Down Expand Up @@ -288,7 +287,7 @@ impl Doc {
}
}

store.diff_state_vector(&before_state, false)
Ok(())
}

pub fn keys(&self) -> Vec<String> {
Expand Down
12 changes: 2 additions & 10 deletions y-octo/src/doc/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,6 @@ impl DocStore {
let first_block = items.get(index).unwrap();
let offset = first_block.clock() - clock;
if offset != 0 {
// needs to implement Content split first
vec_struct_info.push_back(first_block.clone().split_at(offset)?.1);
} else {
vec_struct_info.push_back(first_block.clone());
Expand All @@ -800,17 +799,10 @@ impl DocStore {
let mut delete_set = DeleteSet::default();

for (client, nodes) in refs {
let ranges = nodes
nodes
.iter()
.filter(|n| n.deleted())
.map(|n| {
let clock = n.id().clock;
clock..clock + n.len()
})
.collect::<Vec<_>>();
if !ranges.is_empty() {
delete_set.batch_add_ranges(*client, ranges);
}
.for_each(|n| delete_set.add(*client, n.clock(), n.len()));
}

delete_set
Expand Down

0 comments on commit 3764b25

Please sign in to comment.