Skip to content

Commit

Permalink
feat: add history parsing & update pub/sub
Browse files Browse the repository at this point in the history
  • Loading branch information
darkskygit committed Sep 7, 2023
1 parent 0710cda commit bcef699
Show file tree
Hide file tree
Showing 10 changed files with 286 additions and 49 deletions.
40 changes: 20 additions & 20 deletions .github/actions/setup-rust/action.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
name: "Y-Octo Rust setup"
name: "Rust setup"
description: "Rust setup, including cache configuration"
inputs:
components:
description: "Cargo components"
required: false
targets:
description: "Cargo target"
required: false
toolchain:
description: "Rustup toolchain"
required: false
default: "stable"
components:
description: "Cargo components"
required: false
targets:
description: "Cargo target"
required: false
toolchain:
description: "Rustup toolchain"
required: false
default: "stable"

runs:
using: "composite"
steps:
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ inputs.toolchain }}
targets: ${{ inputs.targets }}
components: ${{ inputs.components }}
- uses: Swatinem/rust-cache@v2
using: "composite"
steps:
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ inputs.toolchain }}
targets: ${{ inputs.targets }}
components: ${{ inputs.components }}
- uses: Swatinem/rust-cache@v2
23 changes: 8 additions & 15 deletions y-octo/fuzz/fuzz_targets/apply_update.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
#![no_main]

use libfuzzer_sys::fuzz_target;
use std::collections::HashSet;

use libfuzzer_sys::fuzz_target;
use y_octo_utils::{
gen_nest_type_from_nest_type, gen_nest_type_from_root, CRDTParam, ManipulateSource, OpType,
OpsRegistry, YrsNestType,
gen_nest_type_from_nest_type, gen_nest_type_from_root, CRDTParam, ManipulateSource, OpType, OpsRegistry,
YrsNestType,
};
use yrs::Transact;

Expand All @@ -22,26 +23,18 @@ fuzz_target!(|crdt_params: Vec<CRDTParam>| {
match crdt_param.op_type {
OpType::HandleCurrent => {
if cur_crdt_nest_type.is_some() {
ops_registry.operate_yrs_nest_type(
&doc,
cur_crdt_nest_type.clone().unwrap(),
crdt_param,
);
ops_registry.operate_yrs_nest_type(&doc, cur_crdt_nest_type.clone().unwrap(), crdt_param);
}
}
OpType::CreateCRDTNestType => {
cur_crdt_nest_type = match cur_crdt_nest_type {
None => gen_nest_type_from_root(&mut doc, &crdt_param),
Some(mut nest_type) => match crdt_param.manipulate_source {
ManipulateSource::CurrentNestType => Some(nest_type),
ManipulateSource::NewNestTypeFromYDocRoot => {
gen_nest_type_from_root(&mut doc, &crdt_param)
ManipulateSource::NewNestTypeFromYDocRoot => gen_nest_type_from_root(&mut doc, &crdt_param),
ManipulateSource::NewNestTypeFromCurrent => {
gen_nest_type_from_nest_type(&mut doc, crdt_param.clone(), &mut nest_type)
}
ManipulateSource::NewNestTypeFromCurrent => gen_nest_type_from_nest_type(
&mut doc,
crdt_param.clone(),
&mut nest_type,
),
},
};
}
Expand Down
6 changes: 1 addition & 5 deletions y-octo/fuzz/fuzz_targets/codec_doc_any_struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,7 @@ fn get_random_string() -> String {

fuzz_target!(|data: Vec<Any>| {
{
let any = Any::Object(
data.iter()
.map(|a| (get_random_string(), a.clone()))
.collect(),
);
let any = Any::Object(data.iter().map(|a| (get_random_string(), a.clone())).collect());

let mut buffer = RawEncoder::default();
if let Err(e) = any.write(&mut buffer) {
Expand Down
1 change: 1 addition & 0 deletions y-octo/src/doc/codec/id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ impl Add<Clock> for Id {
}
}

#[allow(clippy::incorrect_partial_ord_impl_on_ord_type)]
impl PartialOrd for Id {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
match self.client.cmp(&other.client) {
Expand Down
15 changes: 15 additions & 0 deletions y-octo/src/doc/codec/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,21 @@ impl Item {
}
}

pub fn resolve_parent(&self) -> Option<(Option<Parent>, Option<String>)> {
if let Some(item) = self.left.as_ref().map(|n| n.as_item()).and_then(|i| i.get().cloned()) {
if item.parent.is_none() {
if let Some(item) = item.right.map(|n| n.as_item()).and_then(|i| i.get().cloned()) {
return Some((item.parent.clone(), item.parent_sub.clone()));
}
} else {
return Some((item.parent.clone(), item.parent_sub.clone()));
}
} else if let Some(item) = self.right.as_ref().map(|n| n.as_item()).and_then(|i| i.get().cloned()) {
return Some((item.parent.clone(), item.parent_sub.clone()));
}
None
}

pub fn len(&self) -> u64 {
self.content.clock_len()
}
Expand Down
4 changes: 4 additions & 0 deletions y-octo/src/doc/codec/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ impl Update {
}
}

pub fn is_content_empty(&self) -> bool {
self.structs.is_empty()
}

pub fn is_empty(&self) -> bool {
self.structs.is_empty() && self.delete_set.is_empty()
}
Expand Down
30 changes: 23 additions & 7 deletions y-octo/src/doc/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ pub struct Doc {
opts: DocOptions,

pub(crate) store: StoreRef,
pub(crate) publisher: Arc<DocPublisher>,
pub publisher: Arc<DocPublisher>,
}

unsafe impl Send for Doc {}
Expand Down Expand Up @@ -150,6 +150,14 @@ impl Doc {
self.client_id
}

pub fn clients(&self) -> Vec<u64> {
self.store.read().unwrap().clients()
}

pub fn history(&self, client: u64) -> Option<Vec<RawHistory>> {
self.store.read().unwrap().history(client)
}

pub fn options(&self) -> &DocOptions {
&self.opts
}
Expand All @@ -170,16 +178,16 @@ impl Doc {
Ok(doc)
}

pub fn apply_update_from_binary(&mut self, update: Vec<u8>) -> JwstCodecResult {
pub fn apply_update_from_binary(&mut self, update: Vec<u8>) -> JwstCodecResult<Update> {
let mut decoder = RawDecoder::new(update);
let update = Update::read(&mut decoder)?;
self.apply_update(update)?;
Ok(())
self.apply_update(update)
}

pub fn apply_update(&mut self, mut update: Update) -> JwstCodecResult {
pub fn apply_update(&mut self, mut update: Update) -> JwstCodecResult<Update> {
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 @@ -238,7 +246,7 @@ impl Doc {
}
}

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

pub fn keys(&self) -> Vec<String> {
Expand Down Expand Up @@ -293,13 +301,21 @@ impl Doc {
}

pub fn encode_state_as_update_v1(&self, sv: &StateVector) -> JwstCodecResult<Vec<u8>> {
let update = self.store.read().unwrap().diff_state_vector(sv)?;
let update = self.encode_state_as_update(sv)?;

let mut encoder = RawEncoder::default();
update.write(&mut encoder)?;
Ok(encoder.into_inner())
}

pub fn encode_update(&self) -> JwstCodecResult<Update> {
self.encode_state_as_update(&StateVector::default())
}

pub fn encode_state_as_update(&self, sv: &StateVector) -> JwstCodecResult<Update> {
self.store.read().unwrap().diff_state_vector(sv)
}

pub fn get_state_vector(&self) -> StateVector {
self.store.read().unwrap().get_state_vector()
}
Expand Down
Loading

0 comments on commit bcef699

Please sign in to comment.