diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 6e99d106..7745f1a5 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -33,9 +33,7 @@ jobs: run: | cargo bench --bench codec_benchmarks --features bench -- --save-baseline master cargo bench --bench array_ops_benchmarks --features bench -- --save-baseline master - # temp disable due to wired memory allocation issue in linux - # i cannot reproduce this issue in mac, but can reproduce in gce and ci - # cargo bench --bench map_ops_benchmarks --features bench -- --save-baseline master + cargo bench --bench map_ops_benchmarks --features bench -- --save-baseline master cargo bench --bench text_ops_benchmarks --features bench -- --save-baseline master cargo bench --bench update_benchmarks --features bench -- --save-baseline master @@ -49,7 +47,7 @@ jobs: run: | cargo bench --bench codec_benchmarks --features bench -- --save-baseline pr cargo bench --bench array_ops_benchmarks --features bench -- --save-baseline pr - # cargo bench --bench map_ops_benchmarks --features bench -- --save-baseline pr + cargo bench --bench map_ops_benchmarks --features bench -- --save-baseline pr cargo bench --bench text_ops_benchmarks --features bench -- --save-baseline pr cargo bench --bench update_benchmarks --features bench -- --save-baseline pr diff --git a/Cargo.lock b/Cargo.lock index 601b9ad0..373383d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2315,7 +2315,6 @@ dependencies = [ "serde", "serde_json", "thiserror", - "y-sync", "yrs", ] @@ -2324,9 +2323,17 @@ name = "jwst-codec-utils" version = "0.1.0" dependencies = [ "arbitrary", + "criterion", "jwst-codec", + "lib0", + "path-ext", "phf", + "proptest", + "proptest-derive", + "rand 0.8.5", + "rand_chacha 0.3.1", "regex", + "y-sync", "yrs", ] @@ -6173,9 +6180,8 @@ dependencies = [ [[package]] name = "y-sync" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e77a143afe4dde83bc987ad3119228d0f107053a3da131a00738cb2d7f496641" +version = "0.3.1" +source = "git+https://github.com/toeverything/y-sync?rev=5626851#5626851603d2961df9bc4cfdd7a16810efc5c3a5" dependencies = [ "lib0", "thiserror", diff --git a/Cargo.toml b/Cargo.toml index d763094e..20fa11f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,4 +47,5 @@ opt-level = 3 [patch.crates-io] lib0 = { git = "https://github.com/toeverything/y-crdt", rev = "a700f09" } +y-sync = { git = "https://github.com/toeverything/y-sync", rev = "5626851" } yrs = { git = "https://github.com/toeverything/y-crdt", rev = "a700f09" } diff --git a/apps/keck/src/server/api/blocks/block.rs b/apps/keck/src/server/api/blocks/block.rs index 977550ae..959d18ff 100644 --- a/apps/keck/src/server/api/blocks/block.rs +++ b/apps/keck/src/server/api/blocks/block.rs @@ -176,11 +176,11 @@ pub async fn delete_block( .await .and_then(|mut ws| Ok(ws.get_blocks()?)) { - if space.remove(&block) { - return StatusCode::NO_CONTENT; - } + space.remove(&block); + StatusCode::NO_CONTENT + } else { + StatusCode::NOT_FOUND } - StatusCode::NOT_FOUND } /// Get children in `Block` diff --git a/apps/keck/src/server/api/mod.rs b/apps/keck/src/server/api/mod.rs index 07281905..3105acef 100644 --- a/apps/keck/src/server/api/mod.rs +++ b/apps/keck/src/server/api/mod.rs @@ -96,7 +96,7 @@ impl Context { .post(webhook) .json( &history - .into_iter() + .iter() .map(|h| (ws_id.as_str(), h).into()) .collect::>(), ) diff --git a/libs/jwst-binding/jwst-jni/build.rs b/libs/jwst-binding/jwst-jni/build.rs index 39c6612e..d1484f96 100644 --- a/libs/jwst-binding/jwst-jni/build.rs +++ b/libs/jwst-binding/jwst-jni/build.rs @@ -82,7 +82,7 @@ foreign_class!( .join("\n"); fs::write(&in_temp, &template).unwrap(); - let template_changed = fs::read_to_string(&in_src).unwrap() != template; + let template_changed = fs::read_to_string(in_src).unwrap() != template; if template_changed || !in_temp.with_extension("").exists() || !jni_dir.exists() { // delete the lib folder then create it again to prevent obsolete files @@ -100,10 +100,10 @@ foreign_class!( swig_gen.expand("android bindings", &in_temp, in_temp.with_extension("out")); if !in_temp.with_extension("").exists() - || fs::read_to_string(&in_temp.with_extension("out")).unwrap() - != fs::read_to_string(&in_temp.with_extension("")).unwrap() + || fs::read_to_string(in_temp.with_extension("out")).unwrap() + != fs::read_to_string(in_temp.with_extension("")).unwrap() { - fs::copy(&in_temp.with_extension("out"), &in_temp.with_extension("")).unwrap(); + fs::copy(in_temp.with_extension("out"), in_temp.with_extension("")).unwrap(); } } } diff --git a/libs/jwst-binding/jwst-jni/src/workspace.rs b/libs/jwst-binding/jwst-jni/src/workspace.rs index f0a1e5ff..33c9468a 100644 --- a/libs/jwst-binding/jwst-jni/src/workspace.rs +++ b/libs/jwst-binding/jwst-jni/src/workspace.rs @@ -64,10 +64,7 @@ impl Workspace { #[generate_interface] pub fn remove(&mut self, block_id: String) -> bool { - self.workspace - .get_blocks() - .map(|mut s| s.remove(&block_id)) - .unwrap_or(false) + self.workspace.get_blocks().map(|mut s| s.remove(&block_id)).is_ok() } #[generate_interface] diff --git a/libs/jwst-codec-utils/Cargo.toml b/libs/jwst-codec-utils/Cargo.toml index 013f3735..675c84ee 100644 --- a/libs/jwst-codec-utils/Cargo.toml +++ b/libs/jwst-codec-utils/Cargo.toml @@ -7,15 +7,55 @@ edition = "2021" [features] bench = ["regex"] -fuzz = ["arbitrary", "jwst-codec", "phf", "yrs"] +fuzz = ["arbitrary", "phf"] [dependencies] arbitrary = { version = "1.3.0", features = ["derive"], optional = true } -jwst-codec = { workspace = true, optional = true } phf = { version = "0.11", features = ["macros"], optional = true } +rand = "0.8" +rand_chacha = "0.3" regex = { version = "1.5", optional = true } -yrs = { version = "=0.16.5", optional = true } + +# ======= bench dependencies ======= +jwst-codec = { workspace = true } + +lib0 = { version = "=0.16.5", features = ["lib0-serde"] } +y-sync = "=0.3.1" +yrs = "=0.16.5" + +[dev-dependencies] +criterion = { version = "0.5", features = ["html_reports"] } +path-ext = "0.1" +proptest = "1.2" +proptest-derive = "0.4" [[bin]] name = "bench_result_render" path = "bin/bench_result_render.rs" + +[[bin]] +name = "memory_leak_test" +path = "bin/memory_leak_test.rs" + +[[bench]] +harness = false +name = "array_ops_benchmarks" + +[[bench]] +harness = false +name = "codec_benchmarks" + +[[bench]] +harness = false +name = "map_ops_benchmarks" + +[[bench]] +harness = false +name = "text_ops_benchmarks" + +[[bench]] +harness = false +name = "update_benchmarks" + +[lib] +bench = true diff --git a/libs/jwst-codec-utils/benches/array_ops_benchmarks.rs b/libs/jwst-codec-utils/benches/array_ops_benchmarks.rs new file mode 100644 index 00000000..841d48b9 --- /dev/null +++ b/libs/jwst-codec-utils/benches/array_ops_benchmarks.rs @@ -0,0 +1,79 @@ +use std::time::Duration; + +use criterion::{criterion_group, criterion_main, Criterion}; +use rand::{Rng, SeedableRng}; + +fn operations(c: &mut Criterion) { + let mut group = c.benchmark_group("ops/array"); + group.measurement_time(Duration::from_secs(15)); + + group.bench_function("yrs/insert", |b| { + let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9"; + let mut rng = rand_chacha::ChaCha20Rng::seed_from_u64(1234); + + let idxs = (0..99) + .map(|_| rng.gen_range(0..base_text.len() as u32)) + .collect::>(); + b.iter(|| { + use yrs::*; + let doc = Doc::new(); + let array = doc.get_or_insert_array("test"); + + let mut trx = doc.transact_mut(); + for c in base_text.chars() { + array.push_back(&mut trx, c.to_string()).unwrap(); + } + for idx in &idxs { + array.insert(&mut trx, *idx, "test").unwrap(); + } + drop(trx); + }); + }); + + group.bench_function("yrs/insert range", |b| { + let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9"; + let mut rng = rand_chacha::ChaCha20Rng::seed_from_u64(1234); + + let idxs = (0..99) + .map(|_| rng.gen_range(0..base_text.len() as u32)) + .collect::>(); + b.iter(|| { + use yrs::*; + let doc = Doc::new(); + let array = doc.get_or_insert_array("test"); + + let mut trx = doc.transact_mut(); + for c in base_text.chars() { + array.push_back(&mut trx, c.to_string()).unwrap(); + } + for idx in &idxs { + array.insert_range(&mut trx, *idx, vec!["test1", "test2"]).unwrap(); + } + drop(trx); + }); + }); + + group.bench_function("yrs/remove", |b| { + let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9"; + + b.iter(|| { + use yrs::*; + let doc = Doc::new(); + let array = doc.get_or_insert_array("test"); + + let mut trx = doc.transact_mut(); + for c in base_text.chars() { + array.push_back(&mut trx, c.to_string()).unwrap(); + } + for idx in (base_text.len() as u32)..0 { + array.remove(&mut trx, idx).unwrap(); + } + drop(trx); + }); + }); + + group.finish(); +} + +criterion_group!(benches, operations); +criterion_main!(benches); diff --git a/libs/jwst-codec-utils/benches/codec_benchmarks.rs b/libs/jwst-codec-utils/benches/codec_benchmarks.rs new file mode 100644 index 00000000..3439d951 --- /dev/null +++ b/libs/jwst-codec-utils/benches/codec_benchmarks.rs @@ -0,0 +1,89 @@ +use criterion::{criterion_group, criterion_main, Criterion, SamplingMode}; +use lib0::{ + decoding::{Cursor, Read}, + encoding::Write, +}; + +const BENCHMARK_SIZE: u32 = 100000; + +fn codec(c: &mut Criterion) { + let mut codec_group = c.benchmark_group("codec"); + codec_group.sampling_mode(SamplingMode::Flat); + { + codec_group.bench_function("lib0 encode var_int (64 bit)", |b| { + b.iter(|| { + let mut encoder = Vec::with_capacity(BENCHMARK_SIZE as usize * 8); + for i in 0..(BENCHMARK_SIZE as i64) { + encoder.write_var(i); + } + }) + }); + codec_group.bench_function("lib0 decode var_int (64 bit)", |b| { + let mut encoder = Vec::with_capacity(BENCHMARK_SIZE as usize * 8); + for i in 0..(BENCHMARK_SIZE as i64) { + encoder.write_var(i); + } + + b.iter(|| { + let mut decoder = Cursor::from(&encoder); + for i in 0..(BENCHMARK_SIZE as i64) { + let num: i64 = decoder.read_var().unwrap(); + assert_eq!(num, i); + } + }) + }); + } + + { + codec_group.bench_function("lib0 encode var_uint (32 bit)", |b| { + b.iter(|| { + let mut encoder = Vec::with_capacity(BENCHMARK_SIZE as usize * 8); + for i in 0..BENCHMARK_SIZE { + encoder.write_var(i); + } + }) + }); + codec_group.bench_function("lib0 decode var_uint (32 bit)", |b| { + let mut encoder = Vec::with_capacity(BENCHMARK_SIZE as usize * 8); + for i in 0..BENCHMARK_SIZE { + encoder.write_var(i); + } + + b.iter(|| { + let mut decoder = Cursor::from(&encoder); + for i in 0..BENCHMARK_SIZE { + let num: u32 = decoder.read_var().unwrap(); + assert_eq!(num, i); + } + }) + }); + } + + { + codec_group.bench_function("lib0 encode var_uint (64 bit)", |b| { + b.iter(|| { + let mut encoder = Vec::with_capacity(BENCHMARK_SIZE as usize * 8); + for i in 0..(BENCHMARK_SIZE as u64) { + encoder.write_var(i); + } + }) + }); + codec_group.bench_function("lib0 decode var_uint (64 bit)", |b| { + let mut encoder = Vec::with_capacity(BENCHMARK_SIZE as usize * 8); + for i in 0..(BENCHMARK_SIZE as u64) { + encoder.write_var(i); + } + + b.iter(|| { + let mut decoder = Cursor::from(&encoder); + for i in 0..(BENCHMARK_SIZE as u64) { + let num: u64 = decoder.read_var().unwrap(); + assert_eq!(num, i); + } + }) + }); + } +} + +criterion_group!(benches, codec); +criterion_main!(benches); diff --git a/libs/jwst-codec-utils/benches/map_ops_benchmarks.rs b/libs/jwst-codec-utils/benches/map_ops_benchmarks.rs new file mode 100644 index 00000000..e4ac31e4 --- /dev/null +++ b/libs/jwst-codec-utils/benches/map_ops_benchmarks.rs @@ -0,0 +1,79 @@ +use std::time::Duration; + +use criterion::{criterion_group, criterion_main, Criterion}; + +fn operations(c: &mut Criterion) { + let mut group = c.benchmark_group("ops/map"); + group.measurement_time(Duration::from_secs(15)); + + group.bench_function("yrs/insert", |b| { + let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9" + .split(' ') + .collect::>(); + + b.iter(|| { + use yrs::*; + let doc = Doc::new(); + let map = doc.get_or_insert_map("test"); + + let mut trx = doc.transact_mut(); + for (idx, key) in base_text.iter().enumerate() { + map.insert(&mut trx, key.to_string(), idx as f64).unwrap(); + } + + drop(trx); + }); + }); + + group.bench_function("yrs/get", |b| { + use yrs::*; + + let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9" + .split(' ') + .collect::>(); + + let doc = Doc::new(); + let map = doc.get_or_insert_map("test"); + + let mut trx = doc.transact_mut(); + for (idx, key) in base_text.iter().enumerate() { + map.insert(&mut trx, key.to_string(), idx as f64).unwrap(); + } + drop(trx); + + b.iter(|| { + let trx = doc.transact(); + for key in &base_text { + map.get(&trx, key).unwrap(); + } + }); + }); + + group.bench_function("yrs/remove", |b| { + let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9" + .split(' ') + .collect::>(); + + b.iter(|| { + use yrs::*; + let doc = Doc::new(); + let map = doc.get_or_insert_map("test"); + + let mut trx = doc.transact_mut(); + for (idx, key) in base_text.iter().enumerate() { + map.insert(&mut trx, key.to_string(), idx as f64).unwrap(); + } + + for key in &base_text { + map.remove(&mut trx, key).unwrap(); + } + + drop(trx); + }); + }); + + group.finish(); +} + +criterion_group!(benches, operations); +criterion_main!(benches); diff --git a/libs/jwst-codec-utils/benches/text_ops_benchmarks.rs b/libs/jwst-codec-utils/benches/text_ops_benchmarks.rs new file mode 100644 index 00000000..d002664e --- /dev/null +++ b/libs/jwst-codec-utils/benches/text_ops_benchmarks.rs @@ -0,0 +1,54 @@ +use std::time::Duration; + +use criterion::{criterion_group, criterion_main, Criterion}; +use rand::{Rng, SeedableRng}; + +fn operations(c: &mut Criterion) { + let mut group = c.benchmark_group("ops/text"); + group.measurement_time(Duration::from_secs(15)); + + group.bench_function("yrs/insert", |b| { + let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9"; + let mut rng = rand_chacha::ChaCha20Rng::seed_from_u64(1234); + + let idxs = (0..99) + .map(|_| rng.gen_range(0..base_text.len() as u32)) + .collect::>(); + b.iter(|| { + use yrs::*; + let doc = Doc::new(); + let text = doc.get_or_insert_text("test"); + let mut trx = doc.transact_mut(); + + text.push(&mut trx, base_text).unwrap(); + for idx in &idxs { + text.insert(&mut trx, *idx, "test").unwrap(); + } + drop(trx); + }); + }); + + group.bench_function("yrs/remove", |b| { + let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9"; + + b.iter(|| { + use yrs::*; + let doc = Doc::new(); + let text = doc.get_or_insert_text("test"); + let mut trx = doc.transact_mut(); + + text.push(&mut trx, base_text).unwrap(); + text.push(&mut trx, base_text).unwrap(); + text.push(&mut trx, base_text).unwrap(); + for idx in (base_text.len() as u32)..0 { + text.remove_range(&mut trx, idx, 1).unwrap(); + } + drop(trx); + }); + }); + + group.finish(); +} + +criterion_group!(benches, operations); +criterion_main!(benches); diff --git a/libs/jwst-codec-utils/benches/update_benchmarks.rs b/libs/jwst-codec-utils/benches/update_benchmarks.rs new file mode 100644 index 00000000..9a9c4c21 --- /dev/null +++ b/libs/jwst-codec-utils/benches/update_benchmarks.rs @@ -0,0 +1,33 @@ +mod utils; + +use std::time::Duration; + +use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; +use path_ext::PathExt; +use utils::Files; + +fn update(c: &mut Criterion) { + let files = Files::load(); + + let mut group = c.benchmark_group("update"); + group.measurement_time(Duration::from_secs(15)); + + for file in &files.files { + group.throughput(Throughput::Bytes(file.content.len() as u64)); + group.bench_with_input( + BenchmarkId::new("parse with yrs", file.path.name_str()), + &file.content, + |b, content| { + b.iter(|| { + use yrs::{updates::decoder::Decode, Update}; + Update::decode_v1(content).unwrap() + }); + }, + ); + } + + group.finish(); +} + +criterion_group!(benches, update); +criterion_main!(benches); diff --git a/libs/jwst-codec-utils/benches/utils/files.rs b/libs/jwst-codec-utils/benches/utils/files.rs new file mode 100644 index 00000000..41f663f7 --- /dev/null +++ b/libs/jwst-codec-utils/benches/utils/files.rs @@ -0,0 +1,42 @@ +use std::{ + fs::{read, read_dir}, + path::{Path, PathBuf}, +}; + +use path_ext::PathExt; + +pub struct File { + pub path: PathBuf, + pub content: Vec, +} + +const BASE: &str = "../jwst-codec/src/fixtures/"; + +impl File { + fn new(path: &Path) -> Self { + let content = read(path).unwrap(); + Self { + path: path.into(), + content, + } + } +} + +pub struct Files { + pub files: Vec, +} + +impl Files { + pub fn load() -> Self { + let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(BASE); + + let files = read_dir(path).unwrap(); + let files = files + .flatten() + .filter(|f| f.path().is_file() && f.path().ext_str() == "bin") + .map(|f| File::new(&f.path())) + .collect::>(); + + Self { files } + } +} diff --git a/libs/jwst-codec-utils/benches/utils/mod.rs b/libs/jwst-codec-utils/benches/utils/mod.rs new file mode 100644 index 00000000..412eb3d0 --- /dev/null +++ b/libs/jwst-codec-utils/benches/utils/mod.rs @@ -0,0 +1,3 @@ +mod files; + +pub use files::Files; diff --git a/libs/jwst-codec-utils/bin/memory_leak_test.rs b/libs/jwst-codec-utils/bin/memory_leak_test.rs new file mode 100644 index 00000000..020a22c3 --- /dev/null +++ b/libs/jwst-codec-utils/bin/memory_leak_test.rs @@ -0,0 +1,79 @@ +use jwst_codec::*; +use rand::{Rng, SeedableRng}; +use rand_chacha::ChaCha20Rng; + +fn run_text_test(seed: u64) { + let doc = Doc::with_client(1); + let mut rand = ChaCha20Rng::seed_from_u64(seed); + let mut text = doc.get_or_create_text("test").unwrap(); + text.insert(0, "This is a string with length 32.").unwrap(); + + let iteration = 20; + let mut len = 32; + + for i in 0..iteration { + let mut text = text.clone(); + let ins = i % 2 == 0; + let pos = rand.gen_range(0..if ins { text.len() } else { len / 2 }); + if ins { + let str = format!("hello {i}"); + text.insert(pos, &str).unwrap(); + len += str.len() as u64; + } else { + text.remove(pos, 6).unwrap(); + len -= 6; + } + } + + assert_eq!(text.to_string().len(), len as usize); + assert_eq!(text.len(), len); +} + +fn run_array_test(seed: u64) { + let doc = Doc::with_client(1); + let mut rand = ChaCha20Rng::seed_from_u64(seed); + let mut array = doc.get_or_create_array("test").unwrap(); + array.push(1).unwrap(); + + let iteration = 20; + let mut len = 1; + + for i in 0..iteration { + let mut array = array.clone(); + let ins = i % 2 == 0; + let pos = rand.gen_range(0..if ins { array.len() } else { len / 2 }); + if ins { + array.insert(pos, 1).unwrap(); + len += 1; + } else { + array.remove(pos, 1).unwrap(); + len -= 1; + } + } + + assert_eq!(array.len(), len); +} + +fn run_map_test() { + let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9" + .split(' ') + .collect::>(); + + for _ in 0..10000 { + let doc = Doc::default(); + let mut map = doc.get_or_create_map("test").unwrap(); + for (idx, key) in base_text.iter().enumerate() { + map.insert(key.to_string(), idx).unwrap(); + } + } +} + +fn main() { + let mut rand = ChaCha20Rng::seed_from_u64(rand::thread_rng().gen()); + for _ in 0..10000 { + let seed = rand.gen(); + run_array_test(seed); + run_text_test(seed); + run_map_test(); + } +} diff --git a/libs/jwst-codec/fuzz/.gitignore b/libs/jwst-codec-utils/fuzz/.gitignore similarity index 100% rename from libs/jwst-codec/fuzz/.gitignore rename to libs/jwst-codec-utils/fuzz/.gitignore diff --git a/libs/jwst-codec/fuzz/Cargo.toml b/libs/jwst-codec-utils/fuzz/Cargo.toml similarity index 76% rename from libs/jwst-codec/fuzz/Cargo.toml rename to libs/jwst-codec-utils/fuzz/Cargo.toml index edd7193f..78cd5775 100644 --- a/libs/jwst-codec/fuzz/Cargo.toml +++ b/libs/jwst-codec-utils/fuzz/Cargo.toml @@ -11,13 +11,13 @@ cargo-fuzz = true rand = "0.8.5" rand_chacha = "0.3.1" libfuzzer-sys = "0.4.6" + +jwst-codec-utils = { path = "..", features = ["fuzz"] } lib0 = "0.16.5" yrs = "0.16.5" -jwst-codec-utils = { path = "../../jwst-codec-utils", features = ["fuzz"] } - [dependencies.jwst-codec] -path = ".." +path = "../../jwst-codec" # Prevent this from interfering with workspaces [workspace] @@ -88,5 +88,12 @@ test = false doc = false [patch.crates-io] +<<<<<<<< HEAD:libs/jwst-codec/fuzz/Cargo.toml + +======== + +>>>>>>>> 07723fc (feat: move compatibility test to utils (#27)):y-octo-utils/fuzz/Cargo.tomllib0 = { git = "https://github.com/toeverything/y-crdt", rev = "a700f09" } +yrs = { git = "https://github.com/toeverything/y-crdt", rev = "a700f09" } lib0 = { git = "https://github.com/toeverything/y-crdt", rev = "a700f09" } +y-sync = { git = "https://github.com/toeverything/y-sync", rev = "5626851" } yrs = { git = "https://github.com/toeverything/y-crdt", rev = "a700f09" } diff --git a/libs/jwst-codec/fuzz/fuzz_targets/apply_update.rs b/libs/jwst-codec-utils/fuzz/fuzz_targets/apply_update.rs similarity index 100% rename from libs/jwst-codec/fuzz/fuzz_targets/apply_update.rs rename to libs/jwst-codec-utils/fuzz/fuzz_targets/apply_update.rs diff --git a/libs/jwst-codec/fuzz/fuzz_targets/codec_doc_any.rs b/libs/jwst-codec-utils/fuzz/fuzz_targets/codec_doc_any.rs similarity index 100% rename from libs/jwst-codec/fuzz/fuzz_targets/codec_doc_any.rs rename to libs/jwst-codec-utils/fuzz/fuzz_targets/codec_doc_any.rs diff --git a/libs/jwst-codec/fuzz/fuzz_targets/codec_doc_any_struct.rs b/libs/jwst-codec-utils/fuzz/fuzz_targets/codec_doc_any_struct.rs similarity index 100% rename from libs/jwst-codec/fuzz/fuzz_targets/codec_doc_any_struct.rs rename to libs/jwst-codec-utils/fuzz/fuzz_targets/codec_doc_any_struct.rs diff --git a/libs/jwst-codec/fuzz/fuzz_targets/decode_bytes.rs b/libs/jwst-codec-utils/fuzz/fuzz_targets/decode_bytes.rs similarity index 100% rename from libs/jwst-codec/fuzz/fuzz_targets/decode_bytes.rs rename to libs/jwst-codec-utils/fuzz/fuzz_targets/decode_bytes.rs diff --git a/libs/jwst-codec/fuzz/fuzz_targets/i32_decode.rs b/libs/jwst-codec-utils/fuzz/fuzz_targets/i32_decode.rs similarity index 100% rename from libs/jwst-codec/fuzz/fuzz_targets/i32_decode.rs rename to libs/jwst-codec-utils/fuzz/fuzz_targets/i32_decode.rs diff --git a/libs/jwst-codec/fuzz/fuzz_targets/i32_encode.rs b/libs/jwst-codec-utils/fuzz/fuzz_targets/i32_encode.rs similarity index 100% rename from libs/jwst-codec/fuzz/fuzz_targets/i32_encode.rs rename to libs/jwst-codec-utils/fuzz/fuzz_targets/i32_encode.rs diff --git a/libs/jwst-codec/fuzz/fuzz_targets/ins_del_text.rs b/libs/jwst-codec-utils/fuzz/fuzz_targets/ins_del_text.rs similarity index 100% rename from libs/jwst-codec/fuzz/fuzz_targets/ins_del_text.rs rename to libs/jwst-codec-utils/fuzz/fuzz_targets/ins_del_text.rs diff --git a/libs/jwst-codec/fuzz/fuzz_targets/sync_message.rs b/libs/jwst-codec-utils/fuzz/fuzz_targets/sync_message.rs similarity index 100% rename from libs/jwst-codec/fuzz/fuzz_targets/sync_message.rs rename to libs/jwst-codec-utils/fuzz/fuzz_targets/sync_message.rs diff --git a/libs/jwst-codec/fuzz/fuzz_targets/u64_decode.rs b/libs/jwst-codec-utils/fuzz/fuzz_targets/u64_decode.rs similarity index 100% rename from libs/jwst-codec/fuzz/fuzz_targets/u64_decode.rs rename to libs/jwst-codec-utils/fuzz/fuzz_targets/u64_decode.rs diff --git a/libs/jwst-codec/fuzz/fuzz_targets/u64_encode.rs b/libs/jwst-codec-utils/fuzz/fuzz_targets/u64_encode.rs similarity index 100% rename from libs/jwst-codec/fuzz/fuzz_targets/u64_encode.rs rename to libs/jwst-codec-utils/fuzz/fuzz_targets/u64_encode.rs diff --git a/libs/jwst-codec-utils/src/codec.rs b/libs/jwst-codec-utils/src/codec.rs new file mode 100644 index 00000000..ea419116 --- /dev/null +++ b/libs/jwst-codec-utils/src/codec.rs @@ -0,0 +1,78 @@ +use super::*; + +#[cfg(test)] +mod tests { + + use super::*; + + use lib0::encoding::Write; + + fn test_var_uint_enc_dec(num: u64) { + let mut buf1 = Vec::new(); + write_var_u64(&mut buf1, num).unwrap(); + + let mut buf2 = Vec::new(); + buf2.write_var(num); + + { + let (rest, decoded_num) = read_var_u64(&buf1).unwrap(); + assert_eq!(num, decoded_num); + assert_eq!(rest.len(), 0); + } + + { + let (rest, decoded_num) = read_var_u64(&buf2).unwrap(); + assert_eq!(num, decoded_num); + assert_eq!(rest.len(), 0); + } + } + + fn test_var_int_enc_dec(num: i32) { + { + let mut buf1: Vec = Vec::new(); + write_var_i32(&mut buf1, num).unwrap(); + + let (rest, decoded_num) = read_var_i32(&buf1).unwrap(); + assert_eq!(num, decoded_num); + assert_eq!(rest.len(), 0); + } + + { + let mut buf2 = Vec::new(); + buf2.write_var(num); + + let (rest, decoded_num) = read_var_i32(&buf2).unwrap(); + assert_eq!(num, decoded_num); + assert_eq!(rest.len(), 0); + } + } + + #[test] + fn test_var_uint_codec() { + test_var_uint_enc_dec(0); + test_var_uint_enc_dec(1); + test_var_uint_enc_dec(127); + test_var_uint_enc_dec(0b1000_0000); + test_var_uint_enc_dec(0b1_0000_0000); + test_var_uint_enc_dec(0b1_1111_1111); + test_var_uint_enc_dec(0b10_0000_0000); + test_var_uint_enc_dec(0b11_1111_1111); + test_var_uint_enc_dec(0x7fff_ffff_ffff_ffff); + test_var_uint_enc_dec(u64::max_value()); + } + + #[test] + fn test_var_int() { + test_var_int_enc_dec(0); + test_var_int_enc_dec(1); + test_var_int_enc_dec(-1); + test_var_int_enc_dec(63); + test_var_int_enc_dec(-63); + test_var_int_enc_dec(64); + test_var_int_enc_dec(-64); + test_var_int_enc_dec(i32::MAX); + test_var_int_enc_dec(i32::MIN); + test_var_int_enc_dec(((1 << 20) - 1) * 8); + test_var_int_enc_dec(-((1 << 20) - 1) * 8); + } +} diff --git a/libs/jwst-codec-utils/src/doc.rs b/libs/jwst-codec-utils/src/doc.rs new file mode 100644 index 00000000..089c22c8 --- /dev/null +++ b/libs/jwst-codec-utils/src/doc.rs @@ -0,0 +1,21 @@ +#[cfg(test)] +mod tests { + use jwst_codec::Doc; + use yrs::{Map, Transact}; + + #[test] + fn test_basic_yrs_binary_compatibility() { + let yrs_doc = yrs::Doc::new(); + + let map = yrs_doc.get_or_insert_map("abc"); + let mut trx = yrs_doc.transact_mut(); + map.insert(&mut trx, "a", 1).unwrap(); + + let binary_from_yrs = trx.encode_update_v1().unwrap(); + + let doc = Doc::new_from_binary(binary_from_yrs.clone()).unwrap(); + let binary = doc.encode_update_v1().unwrap(); + + assert_eq!(binary_from_yrs, binary); + } +} diff --git a/libs/jwst-codec-utils/src/lib.rs b/libs/jwst-codec-utils/src/lib.rs index 54743190..5080c6a0 100644 --- a/libs/jwst-codec-utils/src/lib.rs +++ b/libs/jwst-codec-utils/src/lib.rs @@ -1,5 +1,9 @@ +mod doc; +mod message; + #[cfg(feature = "fuzz")] pub mod doc_operation; #[cfg(feature = "fuzz")] pub use doc_operation::*; +pub use message::{to_sync_message, to_y_message}; diff --git a/libs/jwst-codec-utils/src/message.rs b/libs/jwst-codec-utils/src/message.rs new file mode 100644 index 00000000..93cbce56 --- /dev/null +++ b/libs/jwst-codec-utils/src/message.rs @@ -0,0 +1,154 @@ +use jwst_codec::{AwarenessState, DocMessage, SyncMessage}; +use y_sync::sync::{Message as YMessage, SyncMessage as YSyncMessage}; +use yrs::{ + updates::{decoder::Decode, encoder::Encode}, + StateVector, +}; + +pub fn to_sync_message(msg: YMessage) -> Option { + match msg { + YMessage::Auth(reason) => Some(SyncMessage::Auth(reason)), + YMessage::Awareness(awareness) => Some(SyncMessage::Awareness( + awareness + .clients + .into_iter() + .map(|(client_id, state)| (client_id, AwarenessState::new(state.clock as u64, state.json))) + .collect(), + )), + YMessage::AwarenessQuery => Some(SyncMessage::AwarenessQuery), + YMessage::Sync(doc) => Some(SyncMessage::Doc(match doc { + YSyncMessage::SyncStep1(update) => DocMessage::Step1(update.encode_v1().unwrap()), + YSyncMessage::SyncStep2(update) => DocMessage::Step2(update), + YSyncMessage::Update(update) => DocMessage::Update(update), + })), + YMessage::Custom(_tag, _data) => None, + } +} + +pub fn to_y_message(msg: SyncMessage) -> YMessage { + match msg { + SyncMessage::Auth(reason) => YMessage::Auth(reason), + SyncMessage::Awareness(awareness) => YMessage::Awareness(y_sync::awareness::AwarenessUpdate { + clients: awareness + .into_iter() + .map(|(client_id, state)| { + ( + client_id, + y_sync::awareness::AwarenessUpdateEntry { + clock: state.clock() as u32, + json: state.content().into(), + }, + ) + }) + .collect(), + }), + SyncMessage::AwarenessQuery => YMessage::AwarenessQuery, + SyncMessage::Doc(doc) => YMessage::Sync(match doc { + DocMessage::Step1(update) => YSyncMessage::SyncStep1(StateVector::decode_v1(&update).unwrap()), + DocMessage::Step2(update) => YSyncMessage::SyncStep2(update), + DocMessage::Update(update) => YSyncMessage::Update(update), + }), + } +} + +#[cfg(test)] +mod tests { + use std::collections::HashMap; + + use jwst_codec::{read_sync_message, write_sync_message, SyncMessageScanner}; + use proptest::{collection::vec, prelude::*}; + use yrs::updates::{ + decoder::DecoderV1, + encoder::{Encoder, EncoderV1}, + }; + + use super::*; + + #[test] + fn test_sync_message_compatibility() { + let messages = [ + SyncMessage::Auth(Some("reason".to_string())), + SyncMessage::Awareness(HashMap::from([(1, AwarenessState::new(1, "test".into()))])), + SyncMessage::AwarenessQuery, + SyncMessage::Doc(DocMessage::Step1(vec![1, 2, 3])), + SyncMessage::Doc(DocMessage::Step2(vec![7, 8, 9])), + SyncMessage::Doc(DocMessage::Update(vec![10, 11, 12])), + ]; + + for msg in messages { + let mut buffer = Vec::new(); + write_sync_message(&mut buffer, &msg).unwrap(); + + { + // check messages encode are compatible + let mut decoder = DecoderV1::from(buffer.as_slice()); + let new_msg = YMessage::decode(&mut decoder).unwrap(); + if let Some(new_msg) = to_sync_message(new_msg) { + assert_eq!(new_msg, msg); + } + } + + { + // check messages decode are compatible + let mut encoder = EncoderV1::new(); + to_y_message(msg.clone()).encode(&mut encoder).unwrap(); + + let buffer = encoder.to_vec(); + let (tail, decoded) = read_sync_message(&buffer).unwrap(); + assert_eq!(tail.len(), 0); + assert_eq!(decoded, msg); + } + } + } + + #[derive(Debug, Clone)] + struct WrappedAwarenessState(AwarenessState); + + impl Arbitrary for WrappedAwarenessState { + type Parameters = (); + type Strategy = BoxedStrategy; + + fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { + // clock in yrs only can parse as u32 + any::<(u32, String)>() + .prop_map(|(c, s)| WrappedAwarenessState(AwarenessState::new(c as u64, s))) + .boxed() + } + } + + fn arbitrary_sync_message() -> impl Strategy { + prop_oneof![ + Just(SyncMessage::Auth(None)), + any::().prop_map(|s| SyncMessage::Auth(Some(s))), + any::>() + .prop_map(|s| SyncMessage::Awareness(s.into_iter().map(|(k, v)| (k, v.0)).collect())), + Just(SyncMessage::AwarenessQuery), + // binary in step1 must be a valid state vector in yrs, but in y-octo, you can parse it after parse the + // message any::>().prop_map(|s| SyncMessage::Doc(DocMessage::Step1(s))), + any::>().prop_map(|s| SyncMessage::Doc(DocMessage::Step2(s))), + any::>().prop_map(|s| SyncMessage::Doc(DocMessage::Update(s))), + ] + } + + proptest! { + #[test] + #[cfg_attr(miri, ignore)] + fn test_sync_message_scanner_compatibility(yocto in vec(arbitrary_sync_message(), 0..10)) { + let mut buffer = Vec::new(); + + for message in &yocto { + write_sync_message(&mut buffer, message).unwrap(); + } + + let result: Result, _> = SyncMessageScanner::new(&buffer).collect(); + assert_eq!(result.unwrap(), yocto); + + { + let mut decoder = DecoderV1::from(buffer.as_slice()); + let yrs: Result, _> = y_sync::sync::MessageReader::new(&mut decoder).collect(); + let yrs = yrs.unwrap().into_iter().filter_map(to_sync_message).collect::>(); + assert_eq!(yrs, yocto); + } + } + } +} diff --git a/libs/jwst-codec/Cargo.toml b/libs/jwst-codec/Cargo.toml index d0a3d7de..462ed696 100644 --- a/libs/jwst-codec/Cargo.toml +++ b/libs/jwst-codec/Cargo.toml @@ -1,24 +1,35 @@ [package] -authors = ["DarkSky "] +authors = [ + "DarkSky ", + "forehalo ", + "x1a0t <405028157@qq.com>", + "Brooklyn ", +] +description = "High-performance and thread-safe CRDT implementation compatible with Yjs" edition = "2021" +homepage = "https://github.com/toeverything/OctoBase" +include = ["src/**/*", "benches/**/*", "bin/**/*", "LICENSE", "README.md"] +keywords = ["collaboration", "crdt", "crdts", "yjs", "yata"] license = "AGPL-3.0-only" name = "jwst-codec" +readme = "README.md" +repository = "https://github.com/toeverything/OctoBase" version = "0.1.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bitvec = "1.0.1" -byteorder = "1.4.3" -nanoid = "0.4.0" -nom = "7.1.3" -ordered-float = "3.6.0" -rand = "0.8.5" -rand_chacha = "0.3.1" +bitvec = "1.0" +byteorder = "1.4" +nanoid = "0.4" +nom = "7.1" +ordered-float = "3.9" +rand = "0.8" +rand_chacha = "0.3" rand_distr = "0.4.3" -serde = { version = "1.0.183" } -serde_json = "1.0.105" -thiserror = "1.0.40" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +thiserror = "1.0" # ======= workspace dependencies ======= jwst-logger = { workspace = true } @@ -43,7 +54,6 @@ ordered-float = { version = "3.9", features = ["proptest"] } path-ext = "0.1" proptest = "1.2" proptest-derive = "0.4" -y-sync = "=0.3.0" yrs = "=0.16.5" [[bin]] diff --git a/libs/jwst-codec/benches/array_ops_benchmarks.rs b/libs/jwst-codec/benches/array_ops_benchmarks.rs index bcf15216..e03cbc24 100644 --- a/libs/jwst-codec/benches/array_ops_benchmarks.rs +++ b/libs/jwst-codec/benches/array_ops_benchmarks.rs @@ -28,30 +28,6 @@ fn operations(c: &mut Criterion) { }); }); - group.bench_function("yrs/insert", |b| { - let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9"; - let mut rng = rand_chacha::ChaCha20Rng::seed_from_u64(1234); - - let idxs = (0..99) - .into_iter() - .map(|_| rng.gen_range(0..base_text.len() as u32)) - .collect::>(); - b.iter(|| { - use yrs::*; - let doc = Doc::new(); - let array = doc.get_or_insert_array("test"); - - let mut trx = doc.transact_mut(); - for c in base_text.chars() { - array.push_back(&mut trx, c.to_string()).unwrap(); - } - for idx in &idxs { - array.insert(&mut trx, *idx, "test").unwrap(); - } - drop(trx); - }); - }); - group.bench_function("jwst/insert range", |b| { let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9"; let mut rng = rand_chacha::ChaCha20Rng::seed_from_u64(1234); @@ -74,30 +50,6 @@ fn operations(c: &mut Criterion) { }); }); - group.bench_function("yrs/insert range", |b| { - let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9"; - let mut rng = rand_chacha::ChaCha20Rng::seed_from_u64(1234); - - let idxs = (0..99) - .into_iter() - .map(|_| rng.gen_range(0..base_text.len() as u32)) - .collect::>(); - b.iter(|| { - use yrs::*; - let doc = Doc::new(); - let array = doc.get_or_insert_array("test"); - - let mut trx = doc.transact_mut(); - for c in base_text.chars() { - array.push_back(&mut trx, c.to_string()).unwrap(); - } - for idx in &idxs { - array.insert_range(&mut trx, *idx, vec!["test1", "test2"]).unwrap(); - } - drop(trx); - }); - }); - group.bench_function("jwst/remove", |b| { let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9"; @@ -114,25 +66,6 @@ fn operations(c: &mut Criterion) { }); }); - group.bench_function("yrs/remove", |b| { - let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9"; - - b.iter(|| { - use yrs::*; - let doc = Doc::new(); - let array = doc.get_or_insert_array("test"); - - let mut trx = doc.transact_mut(); - for c in base_text.chars() { - array.push_back(&mut trx, c.to_string()).unwrap(); - } - for idx in (base_text.len() as u32)..0 { - array.remove(&mut trx, idx).unwrap(); - } - drop(trx); - }); - }); - group.finish(); } diff --git a/libs/jwst-codec/benches/codec_benchmarks.rs b/libs/jwst-codec/benches/codec_benchmarks.rs index 0c90fd3f..a172e05c 100644 --- a/libs/jwst-codec/benches/codec_benchmarks.rs +++ b/libs/jwst-codec/benches/codec_benchmarks.rs @@ -1,89 +1,11 @@ use criterion::{criterion_group, criterion_main, Criterion, SamplingMode}; use jwst_codec::{read_var_i32, read_var_u64, write_var_i32, write_var_u64}; -use lib0::{ - decoding::{Cursor, Read}, - encoding::Write, -}; const BENCHMARK_SIZE: u32 = 100000; fn codec(c: &mut Criterion) { let mut codec_group = c.benchmark_group("codec"); codec_group.sampling_mode(SamplingMode::Flat); - { - codec_group.bench_function("lib0 encode var_int (64 bit)", |b| { - b.iter(|| { - let mut encoder = Vec::with_capacity(BENCHMARK_SIZE as usize * 8); - for i in 0..(BENCHMARK_SIZE as i64) { - encoder.write_var(i); - } - }) - }); - codec_group.bench_function("lib0 decode var_int (64 bit)", |b| { - let mut encoder = Vec::with_capacity(BENCHMARK_SIZE as usize * 8); - for i in 0..(BENCHMARK_SIZE as i64) { - encoder.write_var(i); - } - - b.iter(|| { - let mut decoder = Cursor::from(&encoder); - for i in 0..(BENCHMARK_SIZE as i64) { - let num: i64 = decoder.read_var().unwrap(); - assert_eq!(num, i); - } - }) - }); - } - - { - codec_group.bench_function("lib0 encode var_uint (32 bit)", |b| { - b.iter(|| { - let mut encoder = Vec::with_capacity(BENCHMARK_SIZE as usize * 8); - for i in 0..BENCHMARK_SIZE { - encoder.write_var(i); - } - }) - }); - codec_group.bench_function("lib0 decode var_uint (32 bit)", |b| { - let mut encoder = Vec::with_capacity(BENCHMARK_SIZE as usize * 8); - for i in 0..BENCHMARK_SIZE { - encoder.write_var(i); - } - - b.iter(|| { - let mut decoder = Cursor::from(&encoder); - for i in 0..BENCHMARK_SIZE { - let num: u32 = decoder.read_var().unwrap(); - assert_eq!(num, i); - } - }) - }); - } - - { - codec_group.bench_function("lib0 encode var_uint (64 bit)", |b| { - b.iter(|| { - let mut encoder = Vec::with_capacity(BENCHMARK_SIZE as usize * 8); - for i in 0..(BENCHMARK_SIZE as u64) { - encoder.write_var(i); - } - }) - }); - codec_group.bench_function("lib0 decode var_uint (64 bit)", |b| { - let mut encoder = Vec::with_capacity(BENCHMARK_SIZE as usize * 8); - for i in 0..(BENCHMARK_SIZE as u64) { - encoder.write_var(i); - } - - b.iter(|| { - let mut decoder = Cursor::from(&encoder); - for i in 0..(BENCHMARK_SIZE as u64) { - let num: u64 = decoder.read_var().unwrap(); - assert_eq!(num, i); - } - }) - }); - } { codec_group.bench_function("jwst encode var_int (32 bit)", |b| { diff --git a/libs/jwst-codec/benches/map_ops_benchmarks.rs b/libs/jwst-codec/benches/map_ops_benchmarks.rs index 085cfa75..72fdb7f6 100644 --- a/libs/jwst-codec/benches/map_ops_benchmarks.rs +++ b/libs/jwst-codec/benches/map_ops_benchmarks.rs @@ -21,25 +21,6 @@ fn operations(c: &mut Criterion) { }); }); - group.bench_function("yrs/insert", |b| { - let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9" - .split(" ") - .collect::>(); - - b.iter(|| { - use yrs::*; - let doc = Doc::new(); - let map = doc.get_or_insert_map("test"); - - let mut trx = doc.transact_mut(); - for (idx, key) in base_text.iter().enumerate() { - map.insert(&mut trx, key.to_string(), idx as f64).unwrap(); - } - - drop(trx); - }); - }); - group.bench_function("jwst/get", |b| { use jwst_codec::*; @@ -59,30 +40,6 @@ fn operations(c: &mut Criterion) { }); }); - group.bench_function("yrs/get", |b| { - use yrs::*; - - let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9" - .split(" ") - .collect::>(); - - let doc = Doc::new(); - let map = doc.get_or_insert_map("test"); - - let mut trx = doc.transact_mut(); - for (idx, key) in (&base_text).iter().enumerate() { - map.insert(&mut trx, key.to_string(), idx as f64).unwrap(); - } - drop(trx); - - b.iter(|| { - let trx = doc.transact(); - for key in &base_text { - map.get(&trx, key).unwrap(); - } - }); - }); - group.bench_function("jwst/remove", |b| { let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9" .split(" ") @@ -101,29 +58,6 @@ fn operations(c: &mut Criterion) { }); }); - group.bench_function("yrs/remove", |b| { - let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9" - .split(" ") - .collect::>(); - - b.iter(|| { - use yrs::*; - let doc = Doc::new(); - let map = doc.get_or_insert_map("test"); - - let mut trx = doc.transact_mut(); - for (idx, key) in (&base_text).iter().enumerate() { - map.insert(&mut trx, key.to_string(), idx as f64).unwrap(); - } - - for key in &base_text { - map.remove(&mut trx, key).unwrap(); - } - - drop(trx); - }); - }); - group.finish(); } diff --git a/libs/jwst-codec/benches/text_ops_benchmarks.rs b/libs/jwst-codec/benches/text_ops_benchmarks.rs index 9cfab1de..d9ba6339 100644 --- a/libs/jwst-codec/benches/text_ops_benchmarks.rs +++ b/libs/jwst-codec/benches/text_ops_benchmarks.rs @@ -27,28 +27,6 @@ fn operations(c: &mut Criterion) { }); }); - group.bench_function("yrs/insert", |b| { - let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9"; - let mut rng = rand_chacha::ChaCha20Rng::seed_from_u64(1234); - - let idxs = (0..99) - .into_iter() - .map(|_| rng.gen_range(0..base_text.len() as u32)) - .collect::>(); - b.iter(|| { - use yrs::*; - let doc = Doc::new(); - let text = doc.get_or_insert_text("test"); - let mut trx = doc.transact_mut(); - - text.push(&mut trx, &base_text).unwrap(); - for idx in &idxs { - text.insert(&mut trx, *idx, "test").unwrap(); - } - drop(trx); - }); - }); - group.bench_function("jwst/remove", |b| { let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9"; @@ -66,25 +44,6 @@ fn operations(c: &mut Criterion) { }); }); - group.bench_function("yrs/remove", |b| { - let base_text = "test1 test2 test3 test4 test5 test6 test7 test8 test9"; - - b.iter(|| { - use yrs::*; - let doc = Doc::new(); - let text = doc.get_or_insert_text("test"); - let mut trx = doc.transact_mut(); - - text.push(&mut trx, &base_text).unwrap(); - text.push(&mut trx, &base_text).unwrap(); - text.push(&mut trx, &base_text).unwrap(); - for idx in (base_text.len() as u32)..0 { - text.remove_range(&mut trx, idx, 1).unwrap(); - } - drop(trx); - }); - }); - group.finish(); } diff --git a/libs/jwst-codec/benches/update_benchmarks.rs b/libs/jwst-codec/benches/update_benchmarks.rs index 935855b0..fc28808f 100644 --- a/libs/jwst-codec/benches/update_benchmarks.rs +++ b/libs/jwst-codec/benches/update_benchmarks.rs @@ -25,16 +25,6 @@ fn update(c: &mut Criterion) { }); }, ); - group.bench_with_input( - BenchmarkId::new("parse with yrs", file.path.name_str()), - &file.content, - |b, content| { - b.iter(|| { - use yrs::{updates::decoder::Decode, Update}; - Update::decode_v1(&content).unwrap() - }); - }, - ); } group.finish(); diff --git a/libs/jwst-codec/fuzz/Cargo.lock b/libs/jwst-codec/fuzz/Cargo.lock deleted file mode 100644 index 46c04979..00000000 --- a/libs/jwst-codec/fuzz/Cargo.lock +++ /dev/null @@ -1,1050 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "Inflector" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -dependencies = [ - "lazy_static", - "regex", -] - -[[package]] -name = "aho-corasick" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" -dependencies = [ - "memchr", -] - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "arbitrary" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d098ff73c1ca148721f37baad5ea6a465a13f9573aba8641fbbbae8164a54e" -dependencies = [ - "derive_arbitrary", -] - -[[package]] -name = "atomic_refcell" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79d6dc922a2792b006573f60b2648076355daeae5ce9cb59507e5908c9625d31" - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[package]] -name = "bumpalo" -version = "3.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c6ed94e98ecff0c12dd1b04c15ec0d7d9458ca8fe806cea6f12954efe74c63b" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "cc" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" -dependencies = [ - "jobserver", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "time 0.1.45", - "wasm-bindgen", - "winapi", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" - -[[package]] -name = "derive_arbitrary" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cdeb9ec472d588e539a818b2dee436825730da08ad0017c4b1a17676bdc8b7" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "funty" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "generator" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" -dependencies = [ - "cc", - "libc", - "log", - "rustversion", - "windows", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "itoa" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" - -[[package]] -name = "jobserver" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" -dependencies = [ - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "jwst-codec" -version = "0.1.0" -dependencies = [ - "arbitrary", - "bitvec", - "byteorder", - "jwst-logger", - "loom", - "nanoid", - "nom", - "ordered-float", - "rand 0.8.5", - "rand_chacha 0.3.1", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "jwst-codec-fuzz" -version = "0.0.0" -dependencies = [ - "jwst-codec", - "jwst-codec-util", - "lib0", - "libfuzzer-sys", - "rand 0.8.5", - "rand_chacha 0.3.1", - "yrs", -] - -[[package]] -name = "jwst-codec-util" -version = "0.1.0" -dependencies = [ - "arbitrary", - "jwst-codec", - "phf", - "yrs", -] - -[[package]] -name = "jwst-logger" -version = "0.1.0" -dependencies = [ - "chrono", - "nu-ansi-term", - "tracing", - "tracing-log", - "tracing-stackdriver", - "tracing-subscriber", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "lib0" -version = "0.16.5" -source = "git+https://github.com/toeverything/y-crdt?rev=a700f09#a700f0990a993f905531f7acf589c6a736bb7429" -dependencies = [ - "thiserror", -] - -[[package]] -name = "libc" -version = "0.2.144" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" - -[[package]] -name = "libfuzzer-sys" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beb09950ae85a0a94b27676cccf37da5ff13f27076aa1adbc6545dd0d0e1bd4e" -dependencies = [ - "arbitrary", - "cc", - "once_cell", -] - -[[package]] -name = "log" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "loom" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27537a24ea22f4818f17260442099a6ed6e21c445ece117aa1873688c399cb79" -dependencies = [ - "cfg-if", - "generator", - "scoped-tls", - "serde", - "serde_json", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata", -] - -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "nanoid" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8" -dependencies = [ - "rand 0.8.5", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", -] - -[[package]] -name = "once_cell" -version = "1.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" - -[[package]] -name = "ordered-float" -version = "3.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fc2dbde8f8a79f2102cc474ceb0ad68e3b80b85289ea62389b60e66777e4213" -dependencies = [ - "arbitrary", - "num-traits", -] - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "phf" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" -dependencies = [ - "phf_macros", - "phf_shared", -] - -[[package]] -name = "phf_generator" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" -dependencies = [ - "phf_shared", - "rand 0.8.5", -] - -[[package]] -name = "phf_macros" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92aacdc5f16768709a569e913f7451034034178b05bdc8acda226659a3dccc66" -dependencies = [ - "phf_generator", - "phf_shared", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "phf_shared" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" -dependencies = [ - "siphasher", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "proc-macro2" -version = "1.0.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "quote" -version = "1.0.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.9", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] -name = "regex" -version = "1.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax 0.7.2", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", -] - -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" - -[[package]] -name = "rustversion" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f" - -[[package]] -name = "ryu" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" - -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - -[[package]] -name = "serde" -version = "1.0.183" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.183" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.29", -] - -[[package]] -name = "serde_json" -version = "1.0.105" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sharded-slab" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "siphasher" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" - -[[package]] -name = "smallstr" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e922794d168678729ffc7e07182721a14219c65814e66e91b839a272fe5ae4f" -dependencies = [ - "smallvec", -] - -[[package]] -name = "smallvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "thiserror" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.29", -] - -[[package]] -name = "thread_local" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" -dependencies = [ - "cfg-if", - "once_cell", -] - -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "time" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" -dependencies = [ - "itoa", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" - -[[package]] -name = "time-macros" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" -dependencies = [ - "time-core", -] - -[[package]] -name = "tracing" -version = "0.1.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" -dependencies = [ - "cfg-if", - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.29", -] - -[[package]] -name = "tracing-core" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" -dependencies = [ - "lazy_static", - "log", - "tracing-core", -] - -[[package]] -name = "tracing-serde" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" -dependencies = [ - "serde", - "tracing-core", -] - -[[package]] -name = "tracing-stackdriver" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff9dd91761e07727176a3dd3a1d64bbb577ea656b7b82fa4be4021832674c49" -dependencies = [ - "Inflector", - "serde", - "serde_json", - "thiserror", - "time 0.3.21", - "tracing-core", - "tracing-subscriber", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "serde", - "serde_json", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", - "tracing-serde", -] - -[[package]] -name = "unicode-ident" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.29", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.29", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "yrs" -version = "0.16.5" -source = "git+https://github.com/toeverything/y-crdt?rev=a700f09#a700f0990a993f905531f7acf589c6a736bb7429" -dependencies = [ - "atomic_refcell", - "lib0", - "rand 0.7.3", - "smallstr", - "smallvec", - "thiserror", -] diff --git a/libs/jwst-codec/src/codec/integer.rs b/libs/jwst-codec/src/codec/integer.rs index 1a29dbd8..9f54cbe6 100644 --- a/libs/jwst-codec/src/codec/integer.rs +++ b/libs/jwst-codec/src/codec/integer.rs @@ -112,25 +112,24 @@ pub fn write_var_i32(buffer: &mut W, num: i32) -> Result<(), Error> { #[cfg(test)] mod tests { - use lib0::encoding::Write; use super::*; fn test_var_uint_enc_dec(num: u64) { - let mut buf1 = Vec::new(); - write_var_u64(&mut buf1, num).unwrap(); + let mut buf = Vec::new(); + write_var_u64(&mut buf, num).unwrap(); - let mut buf2 = Vec::new(); - buf2.write_var(num); + let (rest, decoded_num) = read_var_u64(&buf).unwrap(); + assert_eq!(num, decoded_num); + assert_eq!(rest.len(), 0); + } + fn test_var_int_enc_dec(num: i32) { { - let (rest, decoded_num) = read_var_u64(&buf1).unwrap(); - assert_eq!(num, decoded_num); - assert_eq!(rest.len(), 0); - } + let mut buf = Vec::new(); + write_var_i32(&mut buf, num).unwrap(); - { - let (rest, decoded_num) = read_var_u64(&buf2).unwrap(); + let (rest, decoded_num) = read_var_i32(&buf).unwrap(); assert_eq!(num, decoded_num); assert_eq!(rest.len(), 0); } @@ -150,26 +149,6 @@ mod tests { test_var_uint_enc_dec(u64::max_value()); } - fn test_var_int_enc_dec(num: i32) { - { - let mut buf1: Vec = Vec::new(); - write_var_i32(&mut buf1, num).unwrap(); - - let (rest, decoded_num) = read_var_i32(&buf1).unwrap(); - assert_eq!(num, decoded_num); - assert_eq!(rest.len(), 0); - } - - { - let mut buf2 = Vec::new(); - buf2.write_var(num); - - let (rest, decoded_num) = read_var_i32(&buf2).unwrap(); - assert_eq!(num, decoded_num); - assert_eq!(rest.len(), 0); - } - } - #[test] fn test_var_int() { test_var_int_enc_dec(0); diff --git a/libs/jwst-codec/src/doc/document.rs b/libs/jwst-codec/src/doc/document.rs index 4fc6b4c8..bfefb410 100644 --- a/libs/jwst-codec/src/doc/document.rs +++ b/libs/jwst-codec/src/doc/document.rs @@ -387,25 +387,6 @@ mod tests { use super::*; use crate::sync::{AtomicU8, Ordering}; - #[test] - #[cfg_attr(miri, ignore)] - fn test_double_run_with_yrs_basic() { - let yrs_doc = yrs::Doc::new(); - - let map = yrs_doc.get_or_insert_map("abc"); - let mut trx = yrs_doc.transact_mut(); - map.insert(&mut trx, "a", 1).unwrap(); - - let binary_from_yrs = trx.encode_update_v1().unwrap(); - - loom_model!({ - let doc = Doc::new_from_binary(binary_from_yrs.clone()).unwrap(); - let binary = doc.encode_update_v1().unwrap(); - - assert_eq!(binary_from_yrs, binary); - }); - } - #[test] fn test_encode_state_as_update() { let yrs_options_left = Options::default(); diff --git a/libs/jwst-codec/src/doc/publisher.rs b/libs/jwst-codec/src/doc/publisher.rs index a58225b3..31b81ff2 100644 --- a/libs/jwst-codec/src/doc/publisher.rs +++ b/libs/jwst-codec/src/doc/publisher.rs @@ -199,22 +199,25 @@ mod tests { } } }); + sleep(Duration::from_millis(500)); let mut map = doc.get_or_create_map("test").unwrap(); map.insert("key1".to_string(), "val1").unwrap(); - sleep(Duration::from_secs(1)); + sleep(Duration::from_millis(500)); map.insert("key2".to_string(), "val2").unwrap(); map.insert("key3".to_string(), "val3").unwrap(); - sleep(Duration::from_secs(1)); + sleep(Duration::from_millis(500)); let mut array = doc.get_or_create_array("array").unwrap(); array.push("val1").unwrap(); array.push("val2").unwrap(); array.push("val3").unwrap(); - sleep(Duration::from_secs(1)); + sleep(Duration::from_millis(500)); + + doc.publisher.stop(); }); } } diff --git a/libs/jwst-codec/src/protocol/awareness.rs b/libs/jwst-codec/src/protocol/awareness.rs index 72201ef4..5cd397ea 100644 --- a/libs/jwst-codec/src/protocol/awareness.rs +++ b/libs/jwst-codec/src/protocol/awareness.rs @@ -18,6 +18,14 @@ impl AwarenessState { AwarenessState { clock, content } } + pub fn clock(&self) -> u64 { + self.clock + } + + pub fn content(&self) -> &str { + &self.content + } + pub fn is_deleted(&self) -> bool { self.content == NULL_STR } diff --git a/libs/jwst-codec/src/protocol/mod.rs b/libs/jwst-codec/src/protocol/mod.rs index e4270fe1..0bfe0e58 100644 --- a/libs/jwst-codec/src/protocol/mod.rs +++ b/libs/jwst-codec/src/protocol/mod.rs @@ -2,8 +2,6 @@ mod awareness; mod doc; mod scanner; mod sync; -#[cfg(test)] -mod utils; use std::{ collections::HashMap, diff --git a/libs/jwst-codec/src/protocol/scanner.rs b/libs/jwst-codec/src/protocol/scanner.rs index cb51e227..1d9bda9c 100644 --- a/libs/jwst-codec/src/protocol/scanner.rs +++ b/libs/jwst-codec/src/protocol/scanner.rs @@ -44,10 +44,8 @@ impl<'a> Iterator for SyncMessageScanner<'a> { #[cfg(test)] mod tests { use proptest::{collection::vec, prelude::*}; - use y_sync::sync::MessageReader; - use yrs::updates::decoder::DecoderV1; - use super::{utils::to_sync_message, *}; + use super::*; proptest! { #[test] @@ -61,14 +59,6 @@ mod tests { let result: Result, _> = SyncMessageScanner::new(&buffer).collect(); assert_eq!(result.unwrap(), messages); - - { - let mut decoder = DecoderV1::from(buffer.as_slice()); - let original = MessageReader::new(&mut decoder) - .flatten() - .collect::>(); - assert_eq!(original.into_iter().filter_map(to_sync_message).collect::>(), messages); - } } } } diff --git a/libs/jwst-codec/src/protocol/sync.rs b/libs/jwst-codec/src/protocol/sync.rs index ec8a0450..1a138c9c 100644 --- a/libs/jwst-codec/src/protocol/sync.rs +++ b/libs/jwst-codec/src/protocol/sync.rs @@ -162,49 +162,4 @@ mod tests { assert_eq!(decoded, msg); } } - - #[test] - fn test_sync_message_compatibility() { - use y_sync::sync::Message as YMessage; - use yrs::updates::{ - decoder::{Decode, DecoderV1}, - encoder::{Encode, Encoder, EncoderV1}, - }; - - use super::utils::{to_sync_message, to_y_message}; - - let messages = [ - SyncMessage::Auth(Some("reason".to_string())), - SyncMessage::Awareness(HashMap::from([(1, AwarenessState::new(1, "test".into()))])), - SyncMessage::AwarenessQuery, - SyncMessage::Doc(DocMessage::Step1(vec![1, 2, 3])), - SyncMessage::Doc(DocMessage::Step2(vec![7, 8, 9])), - SyncMessage::Doc(DocMessage::Update(vec![10, 11, 12])), - ]; - - for msg in messages { - let mut buffer = Vec::new(); - write_sync_message(&mut buffer, &msg).unwrap(); - - { - // check messages encode are compatible - let mut decoder = DecoderV1::from(buffer.as_slice()); - let new_msg = YMessage::decode(&mut decoder).unwrap(); - if let Some(new_msg) = to_sync_message(new_msg) { - assert_eq!(new_msg, msg); - } - } - - { - // check messages decode are compatible - let mut encoder = EncoderV1::new(); - to_y_message(msg.clone()).encode(&mut encoder).unwrap(); - - let buffer = encoder.to_vec(); - let (tail, decoded) = read_sync_message(&buffer).unwrap(); - assert_eq!(tail.len(), 0); - assert_eq!(decoded, msg); - } - } - } } diff --git a/libs/jwst-codec/src/protocol/utils.rs b/libs/jwst-codec/src/protocol/utils.rs deleted file mode 100644 index e1012c1f..00000000 --- a/libs/jwst-codec/src/protocol/utils.rs +++ /dev/null @@ -1,53 +0,0 @@ -use y_sync::sync::Message as YMessage; -use yrs::{ - updates::{decoder::Decode, encoder::Encode}, - StateVector, -}; - -use super::*; - -pub fn to_sync_message(msg: YMessage) -> Option { - match msg { - YMessage::Auth(reason) => Some(SyncMessage::Auth(reason)), - YMessage::Awareness(awareness) => Some(SyncMessage::Awareness( - awareness - .clients - .into_iter() - .map(|(client_id, state)| (client_id, AwarenessState::new(state.clock as u64, state.json))) - .collect(), - )), - YMessage::AwarenessQuery => Some(SyncMessage::AwarenessQuery), - YMessage::Sync(doc) => Some(SyncMessage::Doc(match doc { - y_sync::sync::SyncMessage::SyncStep1(update) => DocMessage::Step1(update.encode_v1().unwrap()), - y_sync::sync::SyncMessage::SyncStep2(update) => DocMessage::Step2(update), - y_sync::sync::SyncMessage::Update(update) => DocMessage::Update(update), - })), - YMessage::Custom(_tag, _data) => None, - } -} - -pub fn to_y_message(msg: SyncMessage) -> YMessage { - match msg { - SyncMessage::Auth(reason) => YMessage::Auth(reason), - SyncMessage::Awareness(awareness) => YMessage::Awareness(y_sync::awareness::AwarenessUpdate { - clients: awareness - .into_iter() - .map(|(client_id, state)| { - ( - client_id, - y_sync::awareness::AwarenessUpdateEntry { - clock: state.clock as u32, - json: state.content, - }, - ) - }) - .collect(), - }), - SyncMessage::AwarenessQuery => YMessage::AwarenessQuery, - SyncMessage::Doc(doc) => YMessage::Sync(match doc { - DocMessage::Step1(update) => y_sync::sync::SyncMessage::SyncStep1(StateVector::decode_v1(&update).unwrap()), - DocMessage::Step2(update) => y_sync::sync::SyncMessage::SyncStep2(update), - DocMessage::Update(update) => y_sync::sync::SyncMessage::Update(update), - }), - } -} diff --git a/libs/jwst-core/src/block/convert.rs b/libs/jwst-core/src/block/convert.rs index efde92f2..9a716276 100644 --- a/libs/jwst-core/src/block/convert.rs +++ b/libs/jwst-core/src/block/convert.rs @@ -133,7 +133,7 @@ impl Block { let created_map = self.doc.create_map()?; new_array.push(created_map.clone())?; for (key, value) in map.iter() { - self.clone_value(stack + 1, &key, value, created_map.clone())?; + self.clone_value(stack + 1, key, value, created_map.clone())?; } } Value::Array(array) => { @@ -158,23 +158,23 @@ impl Block { match value { Value::Any(any) => { - new_map.insert(key, any)?; + new_map.insert(key.into(), any)?; } Value::Text(text) => { let created_text = self.doc.create_text()?; - new_map.insert(key, created_text.clone())?; + new_map.insert(key.into(), created_text.clone())?; self.clone_text(stack + 1, text, created_text)?; } Value::Map(map) => { let created_map = self.doc.create_map()?; - new_map.insert(key, created_map.clone())?; + new_map.insert(key.into(), created_map.clone())?; for (key, value) in map.iter() { - self.clone_value(stack + 1, &key, value, created_map.clone())?; + self.clone_value(stack + 1, key, value, created_map.clone())?; } } Value::Array(array) => { let created_array = self.doc.create_array()?; - new_map.insert(key, created_array.clone())?; + new_map.insert(key.into(), created_array.clone())?; self.clone_array(stack + 1, array, created_array)?; } val => { @@ -188,13 +188,13 @@ impl Block { pub fn clone_block(&self, mut new_blocks: Map) -> JwstResult<()> { // init base struct let mut created_block = self.doc.create_map()?; - new_blocks.insert(&*self.block_id, created_block.clone())?; + new_blocks.insert(self.block_id.to_string(), created_block.clone())?; // init default schema - created_block.insert(sys::ID, self.block_id.clone())?; - created_block.insert(sys::FLAVOUR, self.flavour())?; + created_block.insert(sys::ID.into(), self.block_id.clone())?; + created_block.insert(sys::FLAVOUR.into(), self.flavour())?; let mut created_children = self.doc.create_array()?; - created_block.insert(sys::CHILDREN, created_children.clone())?; + created_block.insert(sys::CHILDREN.into(), created_children.clone())?; // created_block.insert( sys::CREATED, self.created() as f64)?; // clone children @@ -208,7 +208,6 @@ impl Block { for key in self .block .keys() - .iter() .filter(|k| k.starts_with("prop:") || k.starts_with("ext:")) { match self.block.get(key) { @@ -242,8 +241,8 @@ mod tests { let mut ws1 = Workspace::from_doc(doc1, "test").unwrap(); let new_update = { - ws1.metadata.insert("name", Some("test1")).unwrap(); - ws1.metadata.insert("avatar", Some("test2")).unwrap(); + ws1.metadata.insert("name".into(), Some("test1")).unwrap(); + ws1.metadata.insert("avatar".into(), Some("test2")).unwrap(); let space = ws1.get_exists_space("page0").unwrap(); space.to_single_page().unwrap() }; diff --git a/libs/jwst-core/src/block/mod.rs b/libs/jwst-core/src/block/mod.rs index 646b2aed..6e7de718 100644 --- a/libs/jwst-core/src/block/mod.rs +++ b/libs/jwst-core/src/block/mod.rs @@ -67,13 +67,13 @@ impl Block { Ok(block) } else { // init base struct - space.blocks.insert(block_id, space.doc().create_map()?)?; + space.blocks.insert(block_id.into(), space.doc().create_map()?)?; let mut block = space.blocks.get(block_id).and_then(|b| b.to_map()).unwrap(); // init default schema - block.insert(sys::FLAVOUR, flavour.as_ref())?; - block.insert(sys::CHILDREN, space.doc().create_array()?)?; - block.insert(sys::CREATED, chrono::Utc::now().timestamp_millis())?; + block.insert(sys::FLAVOUR.into(), flavour.as_ref())?; + block.insert(sys::CHILDREN.into(), space.doc().create_array()?)?; + block.insert(sys::CREATED.into(), chrono::Utc::now().timestamp_millis())?; let children = block.get(sys::CHILDREN).and_then(|c| c.to_array()).unwrap(); @@ -106,13 +106,13 @@ impl Block { Ok(block) } else { // init base struct - space.blocks.insert(block_id, space.doc().create_map()?)?; + space.blocks.insert(block_id.into(), space.doc().create_map()?)?; let mut block = space.blocks.get(block_id).and_then(|b| b.to_map()).unwrap(); // init default schema - block.insert(sys::FLAVOUR, flavour.as_ref())?; - block.insert(sys::CHILDREN, space.doc().create_array()?)?; - block.insert(sys::CREATED, created)?; + block.insert(sys::FLAVOUR.into(), flavour.as_ref())?; + block.insert(sys::CHILDREN.into(), space.doc().create_array()?)?; + block.insert(sys::CREATED.into(), created)?; let children = block.get(sys::CHILDREN).and_then(|c| c.to_array()).unwrap(); @@ -177,7 +177,7 @@ impl Block { pub(crate) fn log_update(&mut self) -> JwstResult { self.updated.insert( - &self.block_id, + self.block_id.to_string(), Any::Float64((chrono::Utc::now().timestamp_millis() as f64).into()), )?; @@ -303,7 +303,7 @@ impl Block { } fn set_parent(&mut self, block_id: String) -> JwstResult { - self.block.insert(sys::PARENT, block_id)?; + self.block.insert(sys::PARENT.into(), block_id)?; Ok(()) } @@ -322,12 +322,10 @@ impl Block { self.remove_children(block)?; block.set_parent(self.block_id.clone())?; - let children = &mut self.children; - - if children.len() > pos { - children.insert(pos, block.block_id.clone())?; + if self.children.len() > pos { + self.children.insert(pos, block.block_id.clone())?; } else { - children.push(block.block_id.clone())?; + self.children.push(block.block_id.clone())?; } self.log_update()?; @@ -339,12 +337,12 @@ impl Block { self.remove_children(block)?; block.set_parent(self.block_id.clone())?; - let children = &mut self.children; + let pos = self.children.iter().position(|c| c.to_string() == reference); - if let Some(pos) = children.iter().position(|c| c.to_string() == reference) { - children.insert(pos as u64, block.block_id.clone())?; + if let Some(pos) = pos { + self.children.insert(pos as u64, block.block_id.clone())?; } else { - children.push(block.block_id.clone())?; + self.children.push(block.block_id.clone())?; } self.log_update()?; @@ -356,14 +354,13 @@ impl Block { self.remove_children(block)?; block.set_parent(self.block_id.clone())?; - let children = &mut self.children; - - match children.iter().position(|c| c.to_string() == reference) { - Some(pos) if (pos as u64) < children.len() => { - children.insert(pos as u64 + 1, block.block_id.clone())?; + let pos = self.children.iter().position(|c| c.to_string() == reference); + match pos { + Some(pos) if (pos as u64) < self.children.len() => { + self.children.insert(pos as u64 + 1, block.block_id.clone())?; } _ => { - children.push(block.block_id.clone())?; + self.children.push(block.block_id.clone())?; } } @@ -373,11 +370,11 @@ impl Block { } pub fn remove_children(&mut self, block: &mut Block) -> JwstResult { - let children = &mut self.children; block.set_parent(self.block_id.clone())?; - if let Some(current_pos) = children.iter().position(|c| c.to_string() == block.block_id) { - children.remove(current_pos as u64, 1)?; + let pos = self.children.iter().position(|c| c.to_string() == block.block_id); + if let Some(current_pos) = pos { + self.children.remove(current_pos as u64, 1)?; self.log_update()?; } @@ -489,7 +486,7 @@ mod test { } #[test] - fn insert_remove_children() { + fn test_insert_remove_children() { let mut workspace = Workspace::new("text").unwrap(); let mut space = workspace.get_space("space").unwrap(); diff --git a/libs/jwst-core/src/space/convert.rs b/libs/jwst-core/src/space/convert.rs index 9cb9fb62..ba166a01 100644 --- a/libs/jwst-core/src/space/convert.rs +++ b/libs/jwst-core/src/space/convert.rs @@ -32,8 +32,8 @@ impl Space { } fn init_workspace(&mut self, meta: WorkspaceMetadata) -> JwstResult<()> { - self.metadata.insert("name", meta.name)?; - self.metadata.insert("avatar", meta.avatar)?; + self.metadata.insert("name".into(), meta.name)?; + self.metadata.insert("avatar".into(), meta.avatar)?; Ok(()) } @@ -41,7 +41,7 @@ impl Space { fn init_pages(&mut self) -> JwstResult { self.pages().or_else(|_| { let array = self.doc.create_array()?; - self.metadata.insert("pages", array.clone())?; + self.metadata.insert("pages".into(), array.clone())?; Ok(array) }) } @@ -54,17 +54,17 @@ impl Space { .ok_or(JwstError::VersionNotFound(self.id())) .or_else(|_| { let mut map = self.doc.create_map()?; - self.metadata.insert("versions", map.clone())?; - - map.insert("affine:code", 1)?; - map.insert("affine:database", 1)?; - map.insert("affine:divider", 1)?; - map.insert("affine:embed", 1)?; - map.insert("affine:frame", 1)?; - map.insert("affine:list", 1)?; - map.insert("affine:page", 2)?; - map.insert("affine:paragraph", 1)?; - map.insert("affine:surface", 1)?; + self.metadata.insert("versions".into(), map.clone())?; + + map.insert("affine:code".into(), 1)?; + map.insert("affine:database".into(), 1)?; + map.insert("affine:divider".into(), 1)?; + map.insert("affine:embed".into(), 1)?; + map.insert("affine:frame".into(), 1)?; + map.insert("affine:list".into(), 1)?; + map.insert("affine:page".into(), 2)?; + map.insert("affine:paragraph".into(), 1)?; + map.insert("affine:surface".into(), 1)?; Ok(map) }) @@ -123,20 +123,20 @@ impl Space { let mut new_page_item = ws.doc.create_map()?; space.init_pages()?.push(new_page_item.clone())?; - new_page_item.insert("id", self.space_id())?; + new_page_item.insert("id".into(), self.space_id())?; new_page_item.insert( - "createDate", + "createDate".into(), page_item .get("createDate") .unwrap_or_else(|| Utc::now().timestamp_millis().into()), )?; new_page_item.insert( - "subpageIds", + "subpageIds".into(), page_item.get("subpageIds").unwrap_or_else(|| vec![].into()), )?; let mut title_text = ws.doc.create_text()?; - new_page_item.insert("title", title_text.clone())?; + new_page_item.insert("title".into(), title_text.clone())?; title_text.insert(0, title)?; ws.sync_migration() diff --git a/libs/jwst-core/src/space/mod.rs b/libs/jwst-core/src/space/mod.rs index 8e83154f..66919062 100644 --- a/libs/jwst-core/src/space/mod.rs +++ b/libs/jwst-core/src/space/mod.rs @@ -128,9 +128,10 @@ impl Space { Block::new_ffi(self, block_id, flavour, self.client_id(), created) } - pub fn remove>(&mut self, block_id: S) -> bool { + pub fn remove>(&mut self, block_id: S) { info!("remove block: {}", block_id.as_ref()); - self.blocks.remove(block_id.as_ref()) && self.updated.remove(block_id.as_ref()) + self.blocks.remove(block_id.as_ref()); + self.updated.remove(block_id.as_ref()); } pub fn set_metadata(&mut self, key: &str, value: impl Into) -> JwstResult { @@ -196,7 +197,7 @@ mod test { let mut space = { let mut metadata = doc.get_or_create_map(constants::space::META).unwrap(); let pages = doc.create_array().unwrap(); - metadata.insert("pages", pages.clone()).unwrap(); + metadata.insert("pages".into(), pages.clone()).unwrap(); Space::new(doc.clone(), Pages::new(pages), "workspace", space_id).unwrap() }; @@ -235,7 +236,7 @@ mod test { let mut space = { let mut metadata = doc.get_or_create_map(constants::space::META).unwrap(); let pages = doc.create_array().unwrap(); - metadata.insert("pages", pages.clone()).unwrap(); + metadata.insert("pages".into(), pages.clone()).unwrap(); Space::new(doc.clone(), Pages::new(pages), "workspace", "space").unwrap() }; @@ -255,7 +256,7 @@ mod test { assert!(space.exists("block")); - assert!(space.remove("block")); + space.remove("block"); assert_eq!(space.blocks.len(), 0); assert_eq!(space.updated.len(), 0); @@ -270,7 +271,7 @@ mod test { let mut metadata = doc.get_or_create_map(constants::space::META).unwrap(); let pages = doc.create_array().unwrap(); - metadata.insert("pages", pages.clone()).unwrap(); + metadata.insert("pages".into(), pages.clone()).unwrap(); let space = Space::new(doc.clone(), Pages::new(pages), "space", "test").unwrap(); assert_eq!(space.client_id(), 123); } diff --git a/libs/jwst-core/src/workspaces/metadata/meta.rs b/libs/jwst-core/src/workspaces/metadata/meta.rs index 482bfc9e..4d77350c 100644 --- a/libs/jwst-core/src/workspaces/metadata/meta.rs +++ b/libs/jwst-core/src/workspaces/metadata/meta.rs @@ -59,7 +59,7 @@ impl Workspace { pages } else { let array = self.doc.create_array()?; - self.metadata.insert("pages", array.clone())?; + self.metadata.insert("pages".into(), array.clone())?; array }, ) diff --git a/libs/jwst-core/src/workspaces/metadata/pages.rs b/libs/jwst-core/src/workspaces/metadata/pages.rs index b096ed57..8f659cec 100644 --- a/libs/jwst-core/src/workspaces/metadata/pages.rs +++ b/libs/jwst-core/src/workspaces/metadata/pages.rs @@ -157,14 +157,14 @@ mod tests { fn test_page_meta() { let doc = Doc::default(); let mut map = doc.get_or_create_map("test").unwrap(); - map.insert(&mut "id", "test_page").unwrap(); - map.insert(&mut "favorite", true).unwrap(); - map.insert(&mut "isRootPinboard", true).unwrap(); - map.insert(&mut "init", true).unwrap(); - map.insert(&mut "subpageIds", doc.create_array().unwrap()).unwrap(); - map.insert(&mut "title", "test_title").unwrap(); - map.insert(&mut "trash", true).unwrap(); - map.insert(&mut "trashDate", 1234567890).unwrap(); + map.insert("id".into(), "test_page").unwrap(); + map.insert("favorite".into(), true).unwrap(); + map.insert("isRootPinboard".into(), true).unwrap(); + map.insert("init".into(), true).unwrap(); + map.insert("subpageIds".into(), doc.create_array().unwrap()).unwrap(); + map.insert("title".into(), "test_title").unwrap(); + map.insert("trash".into(), true).unwrap(); + map.insert("trashDate".into(), 1234567890).unwrap(); let meta = PageMeta::from(map); assert_eq!(meta.id, "test_page"); diff --git a/libs/jwst-core/src/workspaces/workspace.rs b/libs/jwst-core/src/workspaces/workspace.rs index f388634d..5e834b4f 100644 --- a/libs/jwst-core/src/workspaces/workspace.rs +++ b/libs/jwst-core/src/workspaces/workspace.rs @@ -175,7 +175,7 @@ mod test { assert!(space.exists("block")); - assert!(space.remove("block")); + space.remove("block"); assert_eq!(space.blocks.len(), 0); assert_eq!(workspace.updated.len(), 0); @@ -235,7 +235,7 @@ mod test { fn scan_doc() { let doc = Doc::default(); let mut map = doc.get_or_create_map("test").unwrap(); - map.insert("test", "aaa").unwrap(); + map.insert("test".into(), "aaa").unwrap(); let data = doc.encode_state_as_update_v1(&StateVector::default()).unwrap();