diff --git a/grovedb-element/Cargo.toml b/grovedb-element/Cargo.toml index 1030bcd01..4d3a5bc7b 100644 --- a/grovedb-element/Cargo.toml +++ b/grovedb-element/Cargo.toml @@ -11,8 +11,8 @@ readme = "../README.md" documentation = "https://docs.rs/grovedb" [dependencies] -bincode = { version = "=2.0.0-rc.3" } -bincode_derive = { version = "=2.0.0-rc.3" } +bincode = { version = "=2.0.1" } +bincode_derive = { version = "=2.0.1" } serde = { version = "1.0.228", features = ["derive"], optional = true } hex = "0.4.3" integer-encoding = "4.1.0" @@ -26,4 +26,4 @@ default = ["verify", "constructor"] verify = [] constructor = [] serde = ["dep:serde"] -visualize = ["dep:grovedb-visualize"] \ No newline at end of file +visualize = ["dep:grovedb-visualize"] diff --git a/grovedb/Cargo.toml b/grovedb/Cargo.toml index 35cfd2245..183093359 100644 --- a/grovedb/Cargo.toml +++ b/grovedb/Cargo.toml @@ -2,7 +2,11 @@ name = "grovedb" description = "Fully featured database using balanced hierarchical authenticated data structures" version = "4.0.0" -authors = ["Samuel Westrich ", "Wisdom Ogwu "] +authors = [ + "Samuel Westrich ", + "Wisdom Ogwu ", +] edition = "2021" license = "MIT" homepage = "https://www.grovedb.org" @@ -11,7 +15,7 @@ readme = "../README.md" documentation = "https://docs.rs/grovedb" [dependencies] -grovedb-costs = { version = "4.0.0", path = "../costs" , optional = true } +grovedb-costs = { version = "4.0.0", path = "../costs", optional = true } grovedbg-types = { version = "4.0.0", path = "../grovedbg-types", optional = true } grovedb-merk = { version = "4.0.0", path = "../merk", optional = true, default-features = false } grovedb-path = { version = "4.0.0", path = "../path" } @@ -21,8 +25,8 @@ grovedb-visualize = { version = "4.0.0", path = "../visualize", optional = true grovedb-element = { version = "4.0.0", path = "../grovedb-element" } axum = { version = "0.8", features = ["macros"], optional = true } -bincode = { version = "=2.0.0-rc.3" } -bincode_derive = { version = "=2.0.0-rc.3" } +bincode = { version = "=2.0.1" } +bincode_derive = { version = "=2.0.1" } blake3 = "1.8.1" hex = "0.4.3" indexmap = "2.7.0" @@ -32,7 +36,10 @@ itertools = { version = "0.14.0", optional = true } tempfile = { version = "3.23.0", optional = true } thiserror = { version = "2.0.17", optional = true } tokio-util = { version = "0.7.17", optional = true } -tokio = { version = "1.48.0", features = ["rt-multi-thread", "net"], optional = true } +tokio = { version = "1.48.0", features = [ + "rt-multi-thread", + "net", +], optional = true } tower-http = { version = "0.6.8", features = ["fs"], optional = true } zip-extensions = { version = "0.13.0", optional = true } serde = { version = "1.0.219", features = ["derive"], optional = true } @@ -60,10 +67,7 @@ harness = false default = ["full", "estimated_costs"] proof_debug = ["grovedb-merk/proof_debug"] serde = ["dep:serde", "grovedb-merk/serde", "indexmap/serde"] -full = [ - "grovedb-merk/full", - "minimal", -] +full = ["grovedb-merk/full", "minimal"] minimal = [ "grovedb-merk/minimal", "thiserror", @@ -75,9 +79,7 @@ minimal = [ "grovedb-costs", "intmap", ] -visualize = [ - "grovedb-visualize", -] +visualize = ["grovedb-visualize"] verify = [ "grovedb-merk/verify", "grovedb-costs", @@ -94,7 +96,7 @@ grovedbg = [ "axum", "tower-http", "zip-extensions", - "tempfile" + "tempfile", ] [build-dependencies] diff --git a/grovedb/benches/insertion_benchmark.rs b/grovedb/benches/insertion_benchmark.rs index 6e7370150..c1e93fc45 100644 --- a/grovedb/benches/insertion_benchmark.rs +++ b/grovedb/benches/insertion_benchmark.rs @@ -34,6 +34,8 @@ use criterion::{criterion_group, criterion_main, Criterion}; use grovedb::{Element, GroveDb}; use grovedb_path::SubtreePath; #[cfg(feature = "minimal")] +use grovedb_version::version::GroveVersion; +#[cfg(feature = "minimal")] use rand::Rng; #[cfg(feature = "minimal")] use tempfile::TempDir; @@ -47,6 +49,7 @@ const EMPTY_PATH: SubtreePath<'static, [u8; 0]> = SubtreePath::empty(); /// without a transaction #[cfg(feature = "minimal")] pub fn insertion_benchmark_without_transaction(c: &mut Criterion) { + let grove_version = GroveVersion::latest(); let dir = TempDir::new().unwrap(); let db = GroveDb::open(dir.path()).unwrap(); let test_leaf: &[u8] = b"leaf1"; @@ -84,6 +87,7 @@ pub fn insertion_benchmark_without_transaction(c: &mut Criterion) { /// with a transaction #[cfg(feature = "minimal")] pub fn insertion_benchmark_with_transaction(c: &mut Criterion) { + let grove_version = GroveVersion::latest(); let dir = TempDir::new().unwrap(); let db = GroveDb::open(dir.path()).unwrap(); let test_leaf: &[u8] = b"leaf1"; @@ -122,6 +126,7 @@ pub fn insertion_benchmark_with_transaction(c: &mut Criterion) { /// Benchmark function to insert 10 root leaves without a transaction #[cfg(feature = "minimal")] pub fn root_leaf_insertion_benchmark_without_transaction(c: &mut Criterion) { + let grove_version = GroveVersion::latest(); let dir = TempDir::new().unwrap(); let db = GroveDb::open(dir.path()).unwrap(); let keys = std::iter::repeat_with(|| rand::thread_rng().gen::<[u8; 32]>()).take(10); @@ -147,6 +152,7 @@ pub fn root_leaf_insertion_benchmark_without_transaction(c: &mut Criterion) { /// Benchmark function to insert 10 root leaves with a transaction #[cfg(feature = "minimal")] pub fn root_leaf_insertion_benchmark_with_transaction(c: &mut Criterion) { + let grove_version = GroveVersion::latest(); let dir = TempDir::new().unwrap(); let db = GroveDb::open(dir.path()).unwrap(); let keys = std::iter::repeat_with(|| rand::thread_rng().gen::<[u8; 32]>()).take(10); @@ -175,6 +181,7 @@ pub fn root_leaf_insertion_benchmark_with_transaction(c: &mut Criterion) { /// and insert key-values into it without a transaction #[cfg(feature = "minimal")] pub fn deeply_nested_insertion_benchmark_without_transaction(c: &mut Criterion) { + let grove_version = GroveVersion::latest(); let dir = TempDir::new().unwrap(); let db = GroveDb::open(dir.path()).unwrap(); let mut nested_subtrees: Vec<[u8; 32]> = Vec::new(); @@ -216,6 +223,7 @@ pub fn deeply_nested_insertion_benchmark_without_transaction(c: &mut Criterion) /// and insert key-values into it with a transaction #[cfg(feature = "minimal")] pub fn deeply_nested_insertion_benchmark_with_transaction(c: &mut Criterion) { + let grove_version = GroveVersion::latest(); let dir = TempDir::new().unwrap(); let db = GroveDb::open(dir.path()).unwrap(); let mut nested_subtrees: Vec<[u8; 32]> = Vec::new(); diff --git a/merk/Cargo.toml b/merk/Cargo.toml index d8ee51e60..d15e16983 100644 --- a/merk/Cargo.toml +++ b/merk/Cargo.toml @@ -2,7 +2,12 @@ name = "grovedb-merk" description = "Merkle key/value store adapted for GroveDB" version = "4.0.0" -authors = ["Samuel Westrich ", "Wisdom Ogwu ", "Matt Bell "] +authors = [ + "Samuel Westrich ", + "Wisdom Ogwu ", + "Evgeny Fomin ", + "Matt Bell ", +] edition = "2021" license = "MIT" homepage = "https://www.grovedb.org" @@ -18,8 +23,8 @@ grovedb-version = { version = "4.0.0", path = "../grovedb-version" } grovedb-visualize = { version = "4.0.0", path = "../visualize" } grovedb-element = { version = "4.0.0", path = "../grovedb-element" } -bincode = { version = "=2.0.0-rc.3" } -bincode_derive = { version = "=2.0.0-rc.3" } +bincode = { version = "=2.0.1" } +bincode_derive = { version = "=2.0.1" } hex = "0.4.3" indexmap = "2.2.6" integer-encoding = "4.1.0" @@ -36,23 +41,18 @@ colored = { version = "3.0.0", optional = true } default = ["full"] proof_debug = [] serde = ["dep:serde", "indexmap/serde"] -minimal = ["num_cpus", - "ed", - "blake3", - "grovedb-storage", - "grovedb-storage/rocksdb_storage", - "grovedb-element/visualize" -] -full = ["minimal", - "test_utils", - "colored_debug", +minimal = [ + "num_cpus", + "ed", + "blake3", + "grovedb-storage", + "grovedb-storage/rocksdb_storage", + "grovedb-element/visualize", ] +full = ["minimal", "test_utils", "colored_debug"] test_utils = ["rand"] colored_debug = ["colored"] -verify = [ - "ed", - "blake3" -] +verify = ["ed", "blake3"] grovedbg = ["full"] [dev-dependencies] diff --git a/merk/benches/branch_queries.rs b/merk/benches/branch_queries.rs index 3e4652037..09f97d092 100644 --- a/merk/benches/branch_queries.rs +++ b/merk/benches/branch_queries.rs @@ -70,7 +70,7 @@ use std::{ time::{Duration, Instant}, }; -use grovedb_costs::{CostsExt, OperationCost}; +use grovedb_costs::OperationCost; use grovedb_element::Element; use grovedb_merk::{ proofs::{Node, Op}, @@ -228,6 +228,7 @@ fn get_key_from_node(node: &Node) -> Option> { Node::KVValueHash(key, ..) => Some(key.clone()), Node::KVValueHashFeatureType(key, ..) => Some(key.clone()), Node::KVDigest(key, _) => Some(key.clone()), + Node::KVDigestCount(key, ..) => Some(key.clone()), Node::KVRefValueHash(key, ..) => Some(key.clone()), Node::KVCount(key, ..) => Some(key.clone()), Node::KVRefValueHashCount(key, ..) => Some(key.clone()), diff --git a/merk/benches/merk.rs b/merk/benches/merk.rs index 62bc6ebba..4e4d80307 100644 --- a/merk/benches/merk.rs +++ b/merk/benches/merk.rs @@ -29,18 +29,46 @@ //! Merk benches use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; -use grovedb_costs::storage_cost::removal::StorageRemovedBytes::BasicStorageRemoval; +use grovedb_costs::storage_cost::{removal::StorageRemovedBytes::BasicStorageRemoval, StorageCost}; use grovedb_merk::{ proofs, test_utils::{make_batch_rand, make_batch_seq, make_del_batch_rand, TempMerk}, - tree::kv::ValueDefinedCostType, - Merk, + tree::{kv::ValueDefinedCostType, MerkBatch}, + tree_type::TreeType, + Merk, Restorer, }; use grovedb_path::SubtreePath; use grovedb_storage::{rocksdb_storage::test_utils::TempStorage, Storage}; use grovedb_version::version::GroveVersion; use rand::prelude::*; +fn apply_batch_default>( + merk: &mut TempMerk, + batch: &MerkBatch, + grove_version: &GroveVersion, +) { + merk.apply_unchecked::, _, _, _, _, _>( + batch, + &[], + None, + &|_k, _v| Ok(0), + None::<&fn(&[u8], &GroveVersion) -> Option>, + &|_old_value, _new_value| Ok(None), + &mut |_costs: &StorageCost, _old_value: &Vec, _new_value: &mut Vec| { + Ok((false, None)) + }, + &mut |_key: &Vec, key_bytes_to_remove: u32, value_bytes_to_remove: u32| { + Ok(( + BasicStorageRemoval(key_bytes_to_remove), + BasicStorageRemoval(value_bytes_to_remove), + )) + }, + grove_version, + ) + .unwrap() + .expect("apply failed"); +} + /// 1 million gets in 2k batches pub fn get(c: &mut Criterion) { let grove_version = GroveVersion::latest(); @@ -53,23 +81,7 @@ pub fn get(c: &mut Criterion) { let mut batches = vec![]; for i in 0..num_batches { let batch = make_batch_rand(batch_size, i); - merk.apply_unchecked::<_, Vec, _, _, _, _>( - &batch, - &[], - None, - &|_k, _v| Ok(0), - None::<&fn(&[u8], &GroveVersion) -> Option>, - &mut |_costs, _old_value, _value| Ok((false, None)), - &mut |_a, key_bytes_to_remove, value_bytes_to_remove| { - Ok(( - BasicStorageRemoval(key_bytes_to_remove), - BasicStorageRemoval(value_bytes_to_remove), - )) - }, - grove_version, - ) - .unwrap() - .expect("apply failed"); + apply_batch_default(&mut merk, &batch, grove_version); batches.push(batch); } @@ -115,23 +127,7 @@ pub fn insert_1m_2k_seq(c: &mut Criterion) { b.iter_with_large_drop(|| { let batch = &batches[i % n_batches]; - merk.apply_unchecked::<_, Vec, _, _, _, _>( - batch, - &[], - None, - &|_k, _v| Ok(0), - None::<&fn(&[u8], &GroveVersion) -> Option>, - &mut |_costs, _old_value, _value| Ok((false, None)), - &mut |_a, key_bytes_to_remove, value_bytes_to_remove| { - Ok(( - BasicStorageRemoval(key_bytes_to_remove), - BasicStorageRemoval(value_bytes_to_remove), - )) - }, - grove_version, - ) - .unwrap() - .expect("apply failed"); + apply_batch_default(&mut merk, batch, grove_version); i += 1; }); }); @@ -157,23 +153,7 @@ pub fn insert_1m_2k_rand(c: &mut Criterion) { b.iter_with_large_drop(|| { let batch = &batches[i % n_batches]; - merk.apply_unchecked::<_, Vec, _, _, _, _>( - batch, - &[], - None, - &|_k, _v| Ok(0), - None::<&fn(&[u8], &GroveVersion) -> Option>, - &mut |_costs, _old_value, _value| Ok((false, None)), - &mut |_a, key_bytes_to_remove, value_bytes_to_remove| { - Ok(( - BasicStorageRemoval(key_bytes_to_remove), - BasicStorageRemoval(value_bytes_to_remove), - )) - }, - grove_version, - ) - .unwrap() - .expect("apply failed"); + apply_batch_default(&mut merk, batch, grove_version); i += 1; }); }); @@ -192,23 +172,7 @@ pub fn update_1m_2k_seq(c: &mut Criterion) { for i in 0..n_batches { let batch = make_batch_seq(((i * batch_size) as u64)..((i + 1) * batch_size) as u64); - merk.apply_unchecked::<_, Vec, _, _, _, _>( - &batch, - &[], - None, - &|_k, _v| Ok(0), - None::<&fn(&[u8], &GroveVersion) -> Option>, - &mut |_costs, _old_value, _value| Ok((false, None)), - &mut |_a, key_bytes_to_remove, value_bytes_to_remove| { - Ok(( - BasicStorageRemoval(key_bytes_to_remove), - BasicStorageRemoval(value_bytes_to_remove), - )) - }, - grove_version, - ) - .unwrap() - .expect("apply failed"); + apply_batch_default(&mut merk, &batch, grove_version); batches.push(batch); } @@ -218,23 +182,7 @@ pub fn update_1m_2k_seq(c: &mut Criterion) { b.iter_with_large_drop(|| { let batch = &batches[i % n_batches]; - merk.apply_unchecked::<_, Vec, _, _, _, _>( - batch, - &[], - None, - &|_k, _v| Ok(0), - None::<&fn(&[u8], &GroveVersion) -> Option>, - &mut |_costs, _old_value, _value| Ok((false, None)), - &mut |_a, key_bytes_to_remove, value_bytes_to_remove| { - Ok(( - BasicStorageRemoval(key_bytes_to_remove), - BasicStorageRemoval(value_bytes_to_remove), - )) - }, - grove_version, - ) - .unwrap() - .expect("apply failed"); + apply_batch_default(&mut merk, batch, grove_version); i += 1; }); }); @@ -253,23 +201,7 @@ pub fn update_1m_2k_rand(c: &mut Criterion) { for i in 0..n_batches { let batch = make_batch_rand(batch_size as u64, i as u64); - merk.apply_unchecked::<_, Vec, _, _, _, _>( - &batch, - &[], - None, - &|_k, _v| Ok(0), - None::<&fn(&[u8], &GroveVersion) -> Option>, - &mut |_costs, _old_value, _value| Ok((false, None)), - &mut |_a, key_bytes_to_remove, value_bytes_to_remove| { - Ok(( - BasicStorageRemoval(key_bytes_to_remove), - BasicStorageRemoval(value_bytes_to_remove), - )) - }, - grove_version, - ) - .unwrap() - .expect("apply failed"); + apply_batch_default(&mut merk, &batch, grove_version); batches.push(batch); } @@ -279,23 +211,7 @@ pub fn update_1m_2k_rand(c: &mut Criterion) { b.iter_with_large_drop(|| { let batch = &batches[i % n_batches]; - merk.apply_unchecked::<_, Vec, _, _, _, _>( - batch, - &[], - None, - &|_k, _v| Ok(0), - None::<&fn(&[u8], &GroveVersion) -> Option>, - &mut |_costs, _old_value, _value| Ok((false, None)), - &mut |_a, key_bytes_to_remove, value_bytes_to_remove| { - Ok(( - BasicStorageRemoval(key_bytes_to_remove), - BasicStorageRemoval(value_bytes_to_remove), - )) - }, - grove_version, - ) - .unwrap() - .expect("apply failed"); + apply_batch_default(&mut merk, batch, grove_version); i += 1; }); }); @@ -316,23 +232,7 @@ pub fn delete_1m_2k_rand(c: &mut Criterion) { for i in 0..n_batches { let batch = make_batch_rand(batch_size as u64, i as u64); let delete_batch = make_del_batch_rand(batch_size as u64, i as u64); - merk.apply_unchecked::<_, Vec, _, _, _, _>( - &batch, - &[], - None, - &|_k, _v| Ok(0), - None::<&fn(&[u8], &GroveVersion) -> Option>, - &mut |_costs, _old_value, _value| Ok((false, None)), - &mut |_a, key_bytes_to_remove, value_bytes_to_remove| { - Ok(( - BasicStorageRemoval(key_bytes_to_remove), - BasicStorageRemoval(value_bytes_to_remove), - )) - }, - grove_version, - ) - .unwrap() - .expect("apply failed"); + apply_batch_default(&mut merk, &batch, grove_version); batches.push(batch); delete_batches.push(delete_batch); @@ -346,42 +246,10 @@ pub fn delete_1m_2k_rand(c: &mut Criterion) { // Merk tree is kept with 1m elements before each bench iteration for more or // less same inputs. - merk.apply_unchecked::<_, Vec, _, _, _, _>( - insert_batch, - &[], - None, - &|_k, _v| Ok(0), - None::<&fn(&[u8], &GroveVersion) -> Option>, - &mut |_costs, _old_value, _value| Ok((false, None)), - &mut |_a, key_bytes_to_remove, value_bytes_to_remove| { - Ok(( - BasicStorageRemoval(key_bytes_to_remove), - BasicStorageRemoval(value_bytes_to_remove), - )) - }, - grove_version, - ) - .unwrap() - .expect("apply failed"); + apply_batch_default(&mut merk, insert_batch, grove_version); b.iter_with_large_drop(|| { - merk.apply_unchecked::<_, Vec, _, _, _, _>( - delete_batch, - &[], - None, - &|_k, _v| Ok(0), - None::<&fn(&[u8], &GroveVersion) -> Option>, - &mut |_costs, _old_value, _value| Ok((false, None)), - &mut |_a, key_bytes_to_remove, value_bytes_to_remove| { - Ok(( - BasicStorageRemoval(key_bytes_to_remove), - BasicStorageRemoval(value_bytes_to_remove), - )) - }, - grove_version, - ) - .unwrap() - .expect("apply failed"); + apply_batch_default(&mut merk, delete_batch, grove_version); i += 1; }); }); @@ -401,23 +269,7 @@ pub fn prove_1m_2k_rand(c: &mut Criterion) { for i in 0..n_batches { let batch = make_batch_rand(batch_size as u64, i as u64); - merk.apply_unchecked::<_, Vec, _, _, _, _>( - &batch, - &[], - None, - &|_k, _v| Ok(0), - None::<&fn(&[u8], &GroveVersion) -> Option>, - &mut |_costs, _old_value, _value| Ok((false, None)), - &mut |_a, key_bytes_to_remove, value_bytes_to_remove| { - Ok(( - BasicStorageRemoval(key_bytes_to_remove), - BasicStorageRemoval(value_bytes_to_remove), - )) - }, - grove_version, - ) - .unwrap() - .expect("apply failed"); + apply_batch_default(&mut merk, &batch, grove_version); let mut prove_keys = Vec::with_capacity(batch_size); for (key, _) in batch.iter() { prove_keys.push(proofs::query::query_item::QueryItem::Key(key.clone())); @@ -452,23 +304,7 @@ pub fn build_trunk_chunk_1m_2k_rand(c: &mut Criterion) { for i in 0..n_batches { let batch = make_batch_rand(batch_size as u64, i as u64); - merk.apply_unchecked::<_, Vec, _, _, _, _>( - &batch, - &[], - None, - &|_k, _v| Ok(0), - None::<&fn(&[u8], &GroveVersion) -> Option>, - &mut |_costs, _old_value, _value| Ok((false, None)), - &mut |_a, key_bytes_to_remove, value_bytes_to_remove| { - Ok(( - BasicStorageRemoval(key_bytes_to_remove), - BasicStorageRemoval(value_bytes_to_remove), - )) - }, - grove_version, - ) - .unwrap() - .expect("apply failed") + apply_batch_default(&mut merk, &batch, grove_version); } c.bench_function("build_trunk_chunk_1m_2k_rand", |b| { @@ -477,9 +313,12 @@ pub fn build_trunk_chunk_1m_2k_rand(c: &mut Criterion) { b.iter(|| { bytes.clear(); - let (ops, _) = - merk.walk(|walker| walker.unwrap().create_trunk_proof().unwrap().unwrap()); - proofs::encode_into(ops.iter(), &mut bytes); + let (chunk, _) = merk + .chunks() + .unwrap() + .chunk_with_index(1, grove_version) + .unwrap(); + proofs::encode_into(chunk.iter(), &mut bytes); }); }); } @@ -496,32 +335,20 @@ pub fn chunkproducer_rand_1m_1_rand(c: &mut Criterion) { for i in 0..n_batches { let batch = make_batch_rand(batch_size as u64, i as u64); - merk.apply_unchecked::<_, Vec, _, _, _, _>( - &batch, - &[], - None, - &|_k, _v| Ok(0), - None::<&fn(&[u8], &GroveVersion) -> Option>, - &mut |_costs, _old_value, _value| Ok((false, None)), - &mut |_a, key_bytes_to_remove, value_bytes_to_remove| { - Ok(( - BasicStorageRemoval(key_bytes_to_remove), - BasicStorageRemoval(value_bytes_to_remove), - )) - }, - grove_version, - ) - .unwrap() - .expect("apply failed") + apply_batch_default(&mut merk, &batch, grove_version); } let mut rng = rand::thread_rng(); - let mut chunks = merk.chunks().unwrap(); + let chunk_count = merk.chunks().unwrap().len(); c.bench_function("chunkproducer_rand_1m_1_rand", |b| { b.iter_with_large_drop(|| { - let i = rng.gen::() % chunks.len(); - let _chunk = chunks.chunk(i, grove_version).unwrap(); + let index = rng.gen_range(1..=chunk_count); + let _chunk = merk + .chunks() + .unwrap() + .chunk_with_index(index, grove_version) + .unwrap(); }); }); } @@ -538,38 +365,20 @@ pub fn chunk_iter_1m_1(c: &mut Criterion) { for i in 0..n_batches { let batch = make_batch_rand(batch_size as u64, i as u64); - merk.apply_unchecked::<_, Vec, _, _, _, _>( - &batch, - &[], - None, - &|_k, _v| Ok(0), - None::<&fn(&[u8], &GroveVersion) -> Option>, - &mut |_costs, _old_value, _value| Ok((false, None)), - &mut |_a, key_bytes_to_remove, value_bytes_to_remove| { - Ok(( - BasicStorageRemoval(key_bytes_to_remove), - BasicStorageRemoval(value_bytes_to_remove), - )) - }, - grove_version, - ) - .unwrap() - .expect("apply failed") + apply_batch_default(&mut merk, &batch, grove_version); } - let mut chunks = merk.chunks().unwrap().into_iter(); - - let mut next = || match chunks.next(grove_version) { - Some(chunk) => chunk, - None => { - chunks = merk.chunks().unwrap().into_iter(); - chunks.next(grove_version).unwrap() - } - }; + let mut chunk_producer = merk.chunks().unwrap(); c.bench_function("chunk_iter_1m_1", |b| { - b.iter_with_large_drop(|| { - let _chunk = next(); + b.iter_with_large_drop(|| match chunk_producer.next(grove_version) { + Some(chunk) => { + let _ = chunk.unwrap(); + } + None => { + chunk_producer = merk.chunks().unwrap(); + let _ = chunk_producer.next(grove_version).unwrap().unwrap(); + } }); }); } @@ -582,52 +391,40 @@ pub fn restore_500_1(c: &mut Criterion) { let mut merk = TempMerk::new(grove_version); let batch = make_batch_rand(merk_size as u64, 0_u64); - merk.apply_unchecked::<_, Vec, _, _, _, _>( - &batch, - &[], - None, - &|_k, _v| Ok(0), - None::<&fn(&[u8], &GroveVersion) -> Option>, - &mut |_costs, _old_value, _value| Ok((false, None)), - &mut |_a, key_bytes_to_remove, value_bytes_to_remove| { - Ok(( - BasicStorageRemoval(key_bytes_to_remove), - BasicStorageRemoval(value_bytes_to_remove), - )) - }, - grove_version, - ) - .unwrap() - .expect("apply failed"); + apply_batch_default(&mut merk, &batch, grove_version); let root_hash = merk.root_hash().unwrap(); c.bench_function("restore_500_1", |b| { b.iter_batched( - || { - let storage = TempStorage::new(); - (storage, merk.chunks().unwrap().into_iter()) - }, - |data| { - let tx = data.0.start_transaction(); - let ctx = data - .0 + || TempStorage::new(), + |storage| { + let tx = storage.start_transaction(); + let ctx = storage .get_immediate_storage_context(SubtreePath::empty(), &tx) .unwrap(); let m = Merk::open_standalone( ctx, - false, + TreeType::NormalTree, None::<&fn(&[u8], &GroveVersion) -> Option>, grove_version, ) .unwrap() .unwrap(); - let mut restorer = Merk::restore(m, root_hash); - - for chunk in data.1 { - restorer.process_chunk(chunk.unwrap()).unwrap(); + let mut restorer = Restorer::new(m, root_hash, None); + let mut chunk_producer = merk.chunks().unwrap(); + let mut chunk_id: Option> = Some(Vec::new()); + + while let Some(current_id) = chunk_id.take() { + let (chunk, next_id) = chunk_producer + .chunk(current_id.as_slice(), grove_version) + .unwrap(); + restorer + .process_chunk(current_id.as_slice(), chunk, grove_version) + .unwrap(); + chunk_id = next_id; } - data.0.commit_transaction(tx).unwrap().unwrap(); + storage.commit_transaction(tx).unwrap().unwrap(); }, BatchSize::SmallInput, ); diff --git a/merk/benches/ops.rs b/merk/benches/ops.rs index d194e6fff..36a134393 100644 --- a/merk/benches/ops.rs +++ b/merk/benches/ops.rs @@ -35,9 +35,11 @@ use grovedb_merk::{ apply_memonly_unchecked, make_batch_rand, make_batch_seq, make_tree_rand, make_tree_seq, }, }; +use grovedb_version::version::GroveVersion; /// 1m sequential inserts in 10k batches, memonly fn insert_1m_10k_seq_memonly(c: &mut Criterion) { + let grove_version = GroveVersion::latest(); let initial_size = 1_000_000; let batch_size = 10_000; let n_batches = initial_size / batch_size; @@ -62,6 +64,7 @@ fn insert_1m_10k_seq_memonly(c: &mut Criterion) { /// 1m random inserts in 10k batches, memonly fn insert_1m_10k_rand_memonly(c: &mut Criterion) { + let grove_version = GroveVersion::latest(); let initial_size = 1_000_000; let batch_size = 10_000; let n_batches = initial_size / batch_size; @@ -92,6 +95,7 @@ fn insert_1m_10k_rand_memonly(c: &mut Criterion) { /// 1m sequential updates in 10k batches, memonly fn update_1m_10k_seq_memonly(c: &mut Criterion) { + let grove_version = GroveVersion::latest(); let initial_size = 1_000_000; let batch_size = 10_000; let n_batches = initial_size / batch_size; @@ -118,6 +122,7 @@ fn update_1m_10k_seq_memonly(c: &mut Criterion) { /// 1m random updates in 10k batches, memonly fn update_1m_10k_rand_memonly(c: &mut Criterion) { + let grove_version = GroveVersion::latest(); let initial_size = 1_000_000; let batch_size = 10_000; let n_batches = initial_size / batch_size; diff --git a/merk/src/proofs/query/mod.rs b/merk/src/proofs/query/mod.rs index 5bb75ba2e..3856e08ed 100644 --- a/merk/src/proofs/query/mod.rs +++ b/merk/src/proofs/query/mod.rs @@ -178,8 +178,10 @@ impl Encode for Query { } #[cfg(any(feature = "minimal", feature = "verify"))] -impl Decode for Query { - fn decode(decoder: &mut D) -> Result { +impl Decode for Query { + fn decode>( + decoder: &mut D, + ) -> Result { let _version = u8::decode(decoder)?; // Decode the items vector let items = Vec::::decode(decoder)?; @@ -218,8 +220,8 @@ impl Decode for Query { } #[cfg(any(feature = "minimal", feature = "verify"))] -impl<'de> BorrowDecode<'de> for Query { - fn borrow_decode>( +impl<'de, Context> BorrowDecode<'de, Context> for Query { + fn borrow_decode>( decoder: &mut D, ) -> Result { let _version = u8::borrow_decode(decoder)?; diff --git a/merk/src/proofs/query/query_item/mod.rs b/merk/src/proofs/query/query_item/mod.rs index 933426910..c4f9ed2cc 100644 --- a/merk/src/proofs/query/query_item/mod.rs +++ b/merk/src/proofs/query/query_item/mod.rs @@ -279,8 +279,10 @@ impl Encode for QueryItem { } #[cfg(any(feature = "minimal", feature = "verify"))] -impl Decode for QueryItem { - fn decode(decoder: &mut D) -> Result { +impl Decode for QueryItem { + fn decode>( + decoder: &mut D, + ) -> Result { let variant_id = u8::decode(decoder)?; match variant_id { @@ -335,8 +337,8 @@ impl Decode for QueryItem { } #[cfg(any(feature = "minimal", feature = "verify"))] -impl<'de> BorrowDecode<'de> for QueryItem { - fn borrow_decode>( +impl<'de, Context> BorrowDecode<'de, Context> for QueryItem { + fn borrow_decode>( decoder: &mut D, ) -> Result { let variant_id = u8::decode(decoder)?;