Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: switch to bincode 2, clean up dependencies #288

Merged
merged 7 commits into from
Apr 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions costs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ repository = "https://github.com/dashpay/grovedb"


[dependencies]
thiserror = "1.0.30"
thiserror = "1.0.58"
intmap = "2.0.0"
integer-encoding = "3.0.3"
integer-encoding = "4.0.0"
21 changes: 8 additions & 13 deletions grovedb/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,25 @@ documentation = "https://docs.rs/grovedb"

[dependencies]
grovedb-merk = { version = "1.0.0-rc.2", path = "../merk", optional = true, default-features = false }
thiserror = { version = "1.0.37", optional = true }
tempfile = { version = "3.3.0", optional = true }
bincode = { version = "1.3.3", optional = true }
serde = { version = "1.0.149", optional = true }
thiserror = { version = "1.0.58", optional = true }
tempfile = { version = "3.10.1", optional = true }
bincode = { version = "2.0.0-rc.3" }
grovedb-storage = { version = "1.0.0-rc.2", path = "../storage", optional = true }
grovedb-visualize = { version = "1.0.0-rc.2", path = "../visualize", optional = true }
hex = { version = "0.4.3", optional = true }
itertools = { version = "0.10.5", optional = true }
integer-encoding = { version = "3.0.4", optional = true }
itertools = { version = "0.12.1", optional = true }
integer-encoding = { version = "4.0.0", optional = true }
grovedb-costs = { version = "1.0.0-rc.2", path = "../costs", optional = true }
nohash-hasher = { version = "0.2.0", optional = true }
indexmap = { version = "1.9.2", optional = true }
indexmap = { version = "2.2.6", optional = true }
intmap = { version = "2.0.0", optional = true }
grovedb-path = { version = "1.0.0-rc.2", path = "../path" }

[dev-dependencies]
rand = "0.8.5"
criterion = "0.4.0"
criterion = "0.5.1"
hex = "0.4.3"
pretty_assertions = "1.3.0"
pretty_assertions = "1.4.0"

[[bench]]
name = "insertion_benchmark"
Expand All @@ -44,8 +43,6 @@ full = [
"grovedb-merk/full",
"thiserror",
"tempfile",
"bincode",
"serde/derive",
"grovedb-storage/rocksdb_storage",
"visualize",
"hex",
Expand All @@ -63,8 +60,6 @@ verify = [
"grovedb-merk/verify",
"grovedb-costs",
"thiserror",
"serde/derive",
"bincode",
"integer-encoding",
]
estimated_costs = ["full"]
5 changes: 2 additions & 3 deletions grovedb/src/element/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,13 @@ mod serialize;
#[cfg(feature = "full")]
use core::fmt;

use bincode::{Decode, Encode};
#[cfg(any(feature = "full", feature = "verify"))]
use grovedb_merk::estimated_costs::SUM_VALUE_EXTRA_COST;
#[cfg(feature = "full")]
use grovedb_merk::estimated_costs::{LAYER_COST_SIZE, SUM_LAYER_COST_SIZE};
#[cfg(feature = "full")]
use grovedb_visualize::visualize_to_vec;
#[cfg(any(feature = "full", feature = "verify"))]
use serde::{Deserialize, Serialize};

#[cfg(any(feature = "full", feature = "verify"))]
use crate::reference_path::ReferencePathType;
Expand Down Expand Up @@ -93,7 +92,7 @@ pub type SumValue = i64;
///
/// ONLY APPEND TO THIS LIST!!! Because
/// of how serialization works.
#[derive(Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[derive(Clone, Encode, Decode, PartialEq, Eq, Hash)]
#[cfg_attr(not(any(feature = "full", feature = "visualize")), derive(Debug))]
pub enum Element {
/// An ordinary value
Expand Down
44 changes: 19 additions & 25 deletions grovedb/src/element/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@
//! Serialize
//! Implements serialization functions in Element

#[cfg(any(feature = "full", feature = "verify"))]
use bincode::Options;
use bincode::config;

#[cfg(any(feature = "full", feature = "verify"))]
use crate::{Element, Error};
Expand All @@ -39,31 +38,26 @@ impl Element {
#[cfg(feature = "full")]
/// Serializes self. Returns vector of u8s.
pub fn serialize(&self) -> Result<Vec<u8>, Error> {
bincode::DefaultOptions::default()
.with_varint_encoding()
.reject_trailing_bytes()
.serialize(self)
.map_err(|_| Error::CorruptedData(String::from("unable to serialize element")))
let config = bincode::config::standard()
.with_big_endian()
.with_no_limit();
bincode::encode_to_vec(self, config)
.map_err(|e| Error::CorruptedData(format!("unable to serialize element {}", e)))
}

#[cfg(feature = "full")]
/// Serializes self. Returns usize.
pub fn serialized_size(&self) -> usize {
bincode::DefaultOptions::default()
.with_varint_encoding()
.reject_trailing_bytes()
.serialized_size(self)
.unwrap() as usize // this should not be able to error
pub fn serialized_size(&self) -> Result<usize, Error> {
self.serialize().map(|serialized| serialized.len())
}

#[cfg(any(feature = "full", feature = "verify"))]
/// Deserializes given bytes and sets as self
pub fn deserialize(bytes: &[u8]) -> Result<Self, Error> {
bincode::DefaultOptions::default()
.with_varint_encoding()
.reject_trailing_bytes()
.deserialize(bytes)
.map_err(|_| Error::CorruptedData(String::from("unable to deserialize element")))
let config = config::standard().with_big_endian().with_no_limit();
Ok(bincode::decode_from_slice(bytes, config)
.map_err(|e| Error::CorruptedData(format!("unable to deserialize element {}", e)))?
.0)
}
}

Expand All @@ -80,20 +74,20 @@ mod tests {
let empty_tree = Element::empty_tree();
let serialized = empty_tree.serialize().expect("expected to serialize");
assert_eq!(serialized.len(), 3);
assert_eq!(serialized.len(), empty_tree.serialized_size());
assert_eq!(serialized.len(), empty_tree.serialized_size().unwrap());
// The tree is fixed length 32 bytes, so it's enum 2 then 32 bytes of zeroes
assert_eq!(hex::encode(serialized), "020000");

let empty_tree = Element::new_tree_with_flags(None, Some(vec![5]));
let serialized = empty_tree.serialize().expect("expected to serialize");
assert_eq!(serialized.len(), 5);
assert_eq!(serialized.len(), empty_tree.serialized_size());
assert_eq!(serialized.len(), empty_tree.serialized_size().unwrap());
assert_eq!(hex::encode(serialized), "0200010105");

let item = Element::new_item(hex::decode("abcdef").expect("expected to decode"));
let serialized = item.serialize().expect("expected to serialize");
assert_eq!(serialized.len(), 6);
assert_eq!(serialized.len(), item.serialized_size());
assert_eq!(serialized.len(), item.serialized_size().unwrap());
// The item is variable length 3 bytes, so it's enum 2 then 32 bytes of zeroes
assert_eq!(hex::encode(serialized), "0003abcdef00");

Expand All @@ -102,7 +96,7 @@ mod tests {
let item = Element::new_sum_item(5);
let serialized = item.serialize().expect("expected to serialize");
assert_eq!(serialized.len(), 3);
assert_eq!(serialized.len(), item.serialized_size());
assert_eq!(serialized.len(), item.serialized_size().unwrap());
// The item is variable length 3 bytes, so it's enum 2 then 32 bytes of zeroes
assert_eq!(hex::encode(serialized), "030a00");

Expand All @@ -112,7 +106,7 @@ mod tests {
);
let serialized = item.serialize().expect("expected to serialize");
assert_eq!(serialized.len(), 8);
assert_eq!(serialized.len(), item.serialized_size());
assert_eq!(serialized.len(), item.serialized_size().unwrap());
assert_eq!(hex::encode(serialized), "0003abcdef010101");

let reference = Element::new_reference(ReferencePathType::AbsolutePathReference(vec![
Expand All @@ -122,7 +116,7 @@ mod tests {
]));
let serialized = reference.serialize().expect("expected to serialize");
assert_eq!(serialized.len(), 12);
assert_eq!(serialized.len(), reference.serialized_size());
assert_eq!(serialized.len(), reference.serialized_size().unwrap());
// The item is variable length 2 bytes, so it's enum 1 then 1 byte for length,
// then 1 byte for 0, then 1 byte 02 for abcd, then 1 byte '1' for 05
assert_eq!(hex::encode(serialized), "010003010002abcd01050000");
Expand All @@ -137,7 +131,7 @@ mod tests {
);
let serialized = reference.serialize().expect("expected to serialize");
assert_eq!(serialized.len(), 16);
assert_eq!(serialized.len(), reference.serialized_size());
assert_eq!(serialized.len(), reference.serialized_size().unwrap());
assert_eq!(hex::encode(serialized), "010003010002abcd0105000103010203");
}
}
11 changes: 6 additions & 5 deletions grovedb/src/estimated_costs/average_case_costs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ impl GroveDb {
_ => add_cost_case_merk_insert(
&mut cost,
key_len,
value.serialized_size() as u32,
cost_return_on_error_no_add!(&cost, value.serialized_size()) as u32,
in_tree_using_sums,
),
};
Expand Down Expand Up @@ -259,7 +259,7 @@ impl GroveDb {
let sum_item_cost_size = if value.is_sum_item() {
SUM_ITEM_COST_SIZE
} else {
value.serialized_size() as u32
cost_return_on_error_no_add!(&cost, value.serialized_size()) as u32
};
let value_len = sum_item_cost_size + flags_len;
add_cost_case_merk_replace_same_size(
Expand All @@ -272,7 +272,7 @@ impl GroveDb {
_ => add_cost_case_merk_replace_same_size(
&mut cost,
key_len,
value.serialized_size() as u32,
cost_return_on_error_no_add!(&cost, value.serialized_size()) as u32,
in_tree_using_sums,
),
};
Expand Down Expand Up @@ -303,7 +303,8 @@ impl GroveDb {
flags_len + flags_len.required_space() as u32
});
// Items need to be always the same serialized size for this to work
let item_cost_size = value.serialized_size() as u32;
let item_cost_size =
cost_return_on_error_no_add!(&cost, value.serialized_size()) as u32;
let value_len = item_cost_size + flags_len;
add_cost_case_merk_patch(
&mut cost,
Expand Down Expand Up @@ -562,7 +563,7 @@ mod test {
&mut average_case_has_raw_cost,
&path,
&key,
elem.serialized_size() as u32,
elem.serialized_size().expect("expected size") as u32,
false,
);

Expand Down
11 changes: 6 additions & 5 deletions grovedb/src/estimated_costs/worst_case_costs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
//! Worst case costs
//! Implements worst case cost functions in GroveDb

use grovedb_costs::{CostResult, CostsExt, OperationCost};
use grovedb_costs::{cost_return_on_error_no_add, CostResult, CostsExt, OperationCost};
use grovedb_merk::{
estimated_costs::{
add_cost_case_merk_insert, add_cost_case_merk_insert_layered, add_cost_case_merk_patch,
Expand Down Expand Up @@ -195,7 +195,7 @@ impl GroveDb {
_ => add_cost_case_merk_insert(
&mut cost,
key_len,
value.serialized_size() as u32,
cost_return_on_error_no_add!(&cost, value.serialized_size()) as u32,
in_parent_tree_using_sums,
),
};
Expand Down Expand Up @@ -253,7 +253,7 @@ impl GroveDb {
_ => add_cost_case_merk_replace(
&mut cost,
key_len,
value.serialized_size() as u32,
cost_return_on_error_no_add!(&cost, value.serialized_size()) as u32,
in_parent_tree_using_sums,
),
};
Expand Down Expand Up @@ -284,7 +284,8 @@ impl GroveDb {
flags_len + flags_len.required_space() as u32
});
// Items need to be always the same serialized size for this to work
let sum_item_cost_size = value.serialized_size() as u32;
let sum_item_cost_size =
cost_return_on_error_no_add!(&cost, value.serialized_size()) as u32;
let value_len = sum_item_cost_size + flags_len;
add_cost_case_merk_patch(
&mut cost,
Expand Down Expand Up @@ -498,7 +499,7 @@ mod test {
&mut worst_case_has_raw_cost,
&path,
&key,
elem.serialized_size() as u32,
elem.serialized_size().expect("expected size") as u32,
false,
);

Expand Down
5 changes: 2 additions & 3 deletions grovedb/src/reference_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,19 @@
#[cfg(feature = "full")]
use std::fmt;

use bincode::{Decode, Encode};
#[cfg(feature = "full")]
use grovedb_visualize::visualize_to_vec;
#[cfg(feature = "full")]
use integer_encoding::VarInt;
#[cfg(any(feature = "full", feature = "verify"))]
use serde::{Deserialize, Serialize};

#[cfg(feature = "full")]
use crate::Error;

#[cfg(any(feature = "full", feature = "verify"))]
#[cfg_attr(not(any(feature = "full", feature = "visualize")), derive(Debug))]
/// Reference path variants
#[derive(Hash, Eq, PartialEq, Serialize, Deserialize, Clone)]
#[derive(Hash, Eq, PartialEq, Encode, Decode, Clone)]
pub enum ReferencePathType {
/// Holds the absolute path to the element the reference points to
AbsolutePathReference(Vec<Vec<u8>>),
Expand Down
12 changes: 7 additions & 5 deletions grovedb/src/visualize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@

use std::io::{Result, Write};

use bincode::Options;
use bincode::{
config,
config::{BigEndian, Configuration},
};
use grovedb_merk::{Merk, VisualizeableMerk};
use grovedb_path::SubtreePathBuilder;
use grovedb_storage::StorageContext;
Expand Down Expand Up @@ -239,11 +242,10 @@ impl Visualize for GroveDb {
#[allow(dead_code)]
pub fn visualize_merk_stdout<'db, S: StorageContext<'db>>(merk: &Merk<S>) {
visualize_stdout(&VisualizeableMerk::new(merk, |bytes: &[u8]| {
bincode::DefaultOptions::default()
.with_varint_encoding()
.reject_trailing_bytes()
.deserialize::<Element>(bytes)
let config = config::standard().with_big_endian().with_no_limit();
bincode::decode_from_slice::<Element, Configuration<BigEndian>>(bytes, config)
.expect("unable to deserialize Element")
.0
}));
}

Expand Down
Loading
Loading