Skip to content

Commit

Permalink
added count sum tree
Browse files Browse the repository at this point in the history
  • Loading branch information
QuantumExplorer committed Jan 8, 2025
1 parent a46c4da commit 3f6705f
Show file tree
Hide file tree
Showing 21 changed files with 703 additions and 80 deletions.
1 change: 0 additions & 1 deletion grovedb/src/batch/estimated_costs/average_case_costs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use grovedb_costs::{
#[cfg(feature = "full")]
use grovedb_merk::{
estimated_costs::average_case_costs::{average_case_merk_propagate, EstimatedLayerInformation},
IsSumTree,
};
use grovedb_merk::{merk::TreeType, tree::AggregateData, RootHashKeyAndAggregateData};
#[cfg(feature = "full")]
Expand Down
21 changes: 15 additions & 6 deletions grovedb/src/batch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ use crate::batch::estimated_costs::EstimatedCostsType;
use crate::{
batch::{batch_structure::BatchStructure, mode::BatchRunMode},
element::{
MaxReferenceHop, BIG_SUM_TREE_COST_SIZE, COUNT_TREE_COST_SIZE, SUM_ITEM_COST_SIZE,
MaxReferenceHop, BIG_SUM_TREE_COST_SIZE, COUNT_TREE_COST_SIZE, COUNT_SUM_TREE_COST_SIZE, SUM_ITEM_COST_SIZE,
SUM_TREE_COST_SIZE, TREE_COST_SIZE,
},
operations::{get::MAX_REFERENCE_HOPS, proof::util::hex_to_ascii},
Expand Down Expand Up @@ -1022,7 +1022,7 @@ where
Element::Tree(..)
| Element::SumTree(..)
| Element::BigSumTree(..)
| Element::CountTree(..) => Err(Error::InvalidBatchOperation(
| Element::CountTree(..) | Element::CountSumTree(..) => Err(Error::InvalidBatchOperation(
"references can not point to trees being updated",
))
.wrap_with_cost(cost),
Expand Down Expand Up @@ -1143,7 +1143,7 @@ where
Element::Tree(..)
| Element::SumTree(..)
| Element::BigSumTree(..)
| Element::CountTree(..) => Err(Error::InvalidBatchOperation(
| Element::CountTree(..) | Element::CountSumTree(..) => Err(Error::InvalidBatchOperation(
"references can not point to trees being updated",
))
.wrap_with_cost(cost),
Expand Down Expand Up @@ -1173,7 +1173,7 @@ where
Element::Tree(..)
| Element::SumTree(..)
| Element::BigSumTree(..)
| Element::CountTree(..) => Err(Error::InvalidBatchOperation(
| Element::CountTree(..) | Element::CountSumTree(..) => Err(Error::InvalidBatchOperation(
"references can not point to trees being updated",
))
.wrap_with_cost(cost),
Expand Down Expand Up @@ -1348,7 +1348,7 @@ where
Element::Tree(..)
| Element::SumTree(..)
| Element::BigSumTree(..)
| Element::CountTree(..) => {
| Element::CountTree(..) | Element::CountSumTree(..) => {
let merk_feature_type = cost_return_on_error!(
&mut cost,
element
Expand Down Expand Up @@ -1562,6 +1562,14 @@ where
flags,
)
}
AggregateData::CountAndSum(count_value, sum_value) => {
Element::new_count_sum_tree_with_flags_and_sum_and_count_value(
root_key,
count_value,
sum_value,
flags,
)
}
};
let merk_feature_type =
cost_return_on_error_no_add!(&cost, element.get_feature_type(in_tree_type));
Expand Down Expand Up @@ -1650,13 +1658,14 @@ where
Element::Tree(..)
| Element::SumTree(..)
| Element::BigSumTree(..)
| Element::CountTree(..) => {
| Element::CountTree(..) | Element::CountSumTree(..) => {
let tree_type = new_element.tree_type().unwrap();
let tree_cost_size = match tree_type {
TreeType::NormalTree => TREE_COST_SIZE,
TreeType::SumTree => SUM_TREE_COST_SIZE,
TreeType::BigSumTree => BIG_SUM_TREE_COST_SIZE,
TreeType::CountTree => COUNT_TREE_COST_SIZE,
TreeType::CountSumTree => COUNT_SUM_TREE_COST_SIZE,
};
let tree_value_cost = tree_cost_size
+ flags_len
Expand Down
26 changes: 26 additions & 0 deletions grovedb/src/element/constructor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,4 +194,30 @@ impl Element {
) -> Self {
Element::CountTree(maybe_root_key, count_value, flags)
}

#[cfg(feature = "full")]
/// Set element to a count sum tree without flags
pub fn new_count_sum_tree(maybe_root_key: Option<Vec<u8>>) -> Self {
Element::CountSumTree(maybe_root_key, 0, 0, None)
}

#[cfg(feature = "full")]
/// Set element to a count sum tree with flags
pub fn new_count_sum_tree_with_flags(
maybe_root_key: Option<Vec<u8>>,
flags: Option<ElementFlags>,
) -> Self {
Element::CountSumTree(maybe_root_key, 0, 0, flags)
}

#[cfg(feature = "full")]
/// Set element to a count sum tree with flags and sum value
pub fn new_count_sum_tree_with_flags_and_sum_and_count_value(
maybe_root_key: Option<Vec<u8>>,
count_value: CountValue,
sum_value: SumValue,
flags: Option<ElementFlags>,
) -> Self {
Element::CountSumTree(maybe_root_key, count_value, sum_value, flags)
}
}
18 changes: 12 additions & 6 deletions grovedb/src/element/delete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ impl Element {
(TreeType::NormalTree, false) => Op::Delete,
(TreeType::SumTree, true)
| (TreeType::BigSumTree, true)
| (TreeType::CountTree, true) => Op::DeleteLayeredMaybeSpecialized,
| (TreeType::CountTree, true)
| (TreeType::CountSumTree, true) => Op::DeleteLayeredMaybeSpecialized,
(TreeType::SumTree, false)
| (TreeType::BigSumTree, false)
| (TreeType::CountTree, false) => Op::DeleteMaybeSpecialized,
| (TreeType::CountTree, false)
| (TreeType::CountSumTree, false) => Op::DeleteMaybeSpecialized,
};
let batch = [(key, op)];
// todo not sure we get it again, we need to see if this is necessary
Expand Down Expand Up @@ -94,10 +96,12 @@ impl Element {
(TreeType::NormalTree, false) => Op::Delete,
(TreeType::SumTree, true)
| (TreeType::BigSumTree, true)
| (TreeType::CountTree, true) => Op::DeleteLayeredMaybeSpecialized,
| (TreeType::CountTree, true)
| (TreeType::CountSumTree, true) => Op::DeleteLayeredMaybeSpecialized,
(TreeType::SumTree, false)
| (TreeType::BigSumTree, false)
| (TreeType::CountTree, false) => Op::DeleteMaybeSpecialized,
| (TreeType::CountTree, false)
| (TreeType::CountSumTree, false) => Op::DeleteMaybeSpecialized,
};
let batch = [(key, op)];
// todo not sure we get it again, we need to see if this is necessary
Expand Down Expand Up @@ -145,10 +149,12 @@ impl Element {
(TreeType::NormalTree, false) => Op::Delete,
(TreeType::SumTree, true)
| (TreeType::BigSumTree, true)
| (TreeType::CountTree, true) => Op::DeleteLayeredMaybeSpecialized,
| (TreeType::CountTree, true)
| (TreeType::CountSumTree, true) => Op::DeleteLayeredMaybeSpecialized,
(TreeType::SumTree, false)
| (TreeType::BigSumTree, false)
| (TreeType::CountTree, false) => Op::DeleteMaybeSpecialized,
| (TreeType::CountTree, false)
| (TreeType::CountSumTree, false) => Op::DeleteMaybeSpecialized,
};
let entry = (key, op);
batch_operations.push(entry);
Expand Down
6 changes: 4 additions & 2 deletions grovedb/src/element/get.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ impl Element {
Some(Element::Tree(_, flags))
| Some(Element::SumTree(_, _, flags))
| Some(Element::BigSumTree(_, _, flags))
| Some(Element::CountTree(_, _, flags)) => {
| Some(Element::CountTree(_, _, flags))
| Some(Element::CountSumTree(.. , flags)) => {
let tree_cost_size = element.as_ref().unwrap().tree_type().unwrap().cost_size();
let flags_len = flags.as_ref().map_or(0, |flags| {
let flags_len = flags.len() as u32;
Expand Down Expand Up @@ -281,7 +282,8 @@ impl Element {
Element::Tree(_, flags)
| Element::SumTree(_, _, flags)
| Element::BigSumTree(_, _, flags)
| Element::CountTree(_, _, flags) => {
| Element::CountTree(_, _, flags)
| Element::CountSumTree(.., flags) => {
let tree_cost_size = element.tree_type().unwrap().cost_size();
let flags_len = flags.as_ref().map_or(0, |flags| {
let flags_len = flags.len() as u32;
Expand Down
32 changes: 26 additions & 6 deletions grovedb/src/element/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ use grovedb_merk::{
use grovedb_version::{check_grovedb_v0, error::GroveVersionError, version::GroveVersion};
#[cfg(feature = "full")]
use integer_encoding::VarInt;

use crate::element::{BIG_SUM_TREE_COST_SIZE, COUNT_TREE_COST_SIZE};
use grovedb_merk::TreeFeatureType::CountedSummedMerkNode;
use crate::element::{BIG_SUM_TREE_COST_SIZE, COUNT_SUM_TREE_COST_SIZE, COUNT_TREE_COST_SIZE};
#[cfg(feature = "full")]
use crate::reference_path::path_from_reference_path_type;
#[cfg(any(feature = "full", feature = "verify"))]
Expand Down Expand Up @@ -183,6 +183,7 @@ impl Element {
Element::SumTree(..) => Some(TreeType::SumTree),
Element::BigSumTree(..) => Some(TreeType::BigSumTree),
Element::CountTree(..) => Some(TreeType::CountTree),
Element::CountSumTree(..) => Some(TreeType::CountSumTree),
_ => None,
}
}
Expand All @@ -208,6 +209,7 @@ impl Element {
| Element::Tree(..)
| Element::BigSumTree(..)
| Element::CountTree(..)
| Element::CountSumTree(..)
)
}

Expand Down Expand Up @@ -243,6 +245,7 @@ impl Element {
TreeType::SumTree => Ok(SummedMerkNode(self.sum_value_or_default())),
TreeType::BigSumTree => Ok(BigSummedMerkNode(self.big_sum_value_or_default())),
TreeType::CountTree => Ok(CountedMerkNode(self.count_value_or_default())),
TreeType::CountSumTree => Ok(CountedSummedMerkNode(self.count_value_or_default(), self.sum_value_or_default())),
}
}

Expand All @@ -256,7 +259,8 @@ impl Element {
| Element::SumTree(.., flags)
| Element::BigSumTree(.., flags)
| Element::CountTree(.., flags)
| Element::SumItem(_, flags) => flags,
| Element::SumItem(_, flags)
| Element::CountSumTree(.., flags) => flags,
}
}

Expand All @@ -270,7 +274,8 @@ impl Element {
| Element::SumTree(.., flags)
| Element::BigSumTree(.., flags)
| Element::CountTree(.., flags)
| Element::SumItem(_, flags) => flags,
| Element::SumItem(_, flags)
| Element::CountSumTree(.., flags) => flags,
}
}

Expand All @@ -284,7 +289,8 @@ impl Element {
| Element::SumTree(.., flags)
| Element::BigSumTree(.., flags)
| Element::CountTree(.., flags)
| Element::SumItem(_, flags) => flags,
| Element::SumItem(_, flags)
| Element::CountSumTree(.., flags) => flags,
}
}

Expand All @@ -298,7 +304,8 @@ impl Element {
| Element::SumTree(.., flags)
| Element::BigSumTree(.., flags)
| Element::CountTree(.., flags)
| Element::SumItem(_, flags) => *flags = new_flags,
| Element::SumItem(_, flags)
| Element::CountSumTree(.., flags) => *flags = new_flags,
}
}

Expand Down Expand Up @@ -409,6 +416,17 @@ impl Element {
key_len, value_len, node_type,
)
}
Element::CountSumTree(.. , flags) => {
let flags_len = flags.map_or(0, |flags| {
let flags_len = flags.len() as u32;
flags_len + flags_len.required_space() as u32
});
let value_len = COUNT_SUM_TREE_COST_SIZE + flags_len;
let key_len = key.len() as u32;
KV::layered_value_byte_cost_size_for_key_and_value_lengths(
key_len, value_len, node_type,
)
}
Element::SumItem(.., flags) => {
let flags_len = flags.map_or(0, |flags| {
let flags_len = flags.len() as u32;
Expand Down Expand Up @@ -436,6 +454,7 @@ impl Element {
Element::BigSumTree(..) => Ok(BIG_SUM_TREE_COST_SIZE),
Element::SumItem(..) => Ok(SUM_ITEM_COST_SIZE),
Element::CountTree(..) => Ok(COUNT_TREE_COST_SIZE),
Element::CountSumTree(..) => Ok(COUNT_SUM_TREE_COST_SIZE),
_ => Err(Error::CorruptedCodeExecution(
"trying to get tree cost from non tree element",
)),
Expand All @@ -459,6 +478,7 @@ impl Element {
Element::SumTree(..) => Some(LayeredValueDefinedCost(cost)),
Element::BigSumTree(..) => Some(LayeredValueDefinedCost(cost)),
Element::CountTree(..) => Some(LayeredValueDefinedCost(cost)),
Element::CountSumTree(..) => Some(LayeredValueDefinedCost(cost)),
Element::SumItem(..) => Some(SpecializedValueDefinedCost(cost)),
_ => None,
}
Expand Down
21 changes: 21 additions & 0 deletions grovedb/src/element/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use grovedb_merk::estimated_costs::SUM_VALUE_EXTRA_COST;
use grovedb_merk::estimated_costs::{
BIG_SUM_LAYER_COST_SIZE, LAYER_COST_SIZE, SUM_LAYER_COST_SIZE,
};
use grovedb_merk::estimated_costs::SUM_AND_COUNT_LAYER_COST_SIZE;
#[cfg(feature = "full")]
use grovedb_merk::merk::TreeType;
#[cfg(feature = "full")]
Expand Down Expand Up @@ -72,6 +73,10 @@ pub const BIG_SUM_TREE_COST_SIZE: u32 = BIG_SUM_LAYER_COST_SIZE; // 19
/// The cost of a count tree
pub const COUNT_TREE_COST_SIZE: u32 = SUM_LAYER_COST_SIZE; // 12

#[cfg(feature = "full")]
/// The cost of a count tree
pub const COUNT_SUM_TREE_COST_SIZE: u32 = SUM_AND_COUNT_LAYER_COST_SIZE; // 21

#[cfg(any(feature = "full", feature = "verify"))]
/// int 64 sum value
pub type SumValue = i64;
Expand All @@ -95,6 +100,7 @@ impl CostSize for TreeType {
TreeType::SumTree => SUM_TREE_COST_SIZE,
TreeType::BigSumTree => BIG_SUM_TREE_COST_SIZE,
TreeType::CountTree => COUNT_TREE_COST_SIZE,
TreeType::CountSumTree => COUNT_SUM_TREE_COST_SIZE,
}
}
}
Expand Down Expand Up @@ -127,6 +133,8 @@ pub enum Element {
/// Same as Element::Tree but underlying Merk counts value of its countable
/// nodes
CountTree(Option<Vec<u8>>, CountValue, Option<ElementFlags>),
/// Combines Element::SumTree and Element::CountTree
CountSumTree(Option<Vec<u8>>, CountValue, SumValue, Option<ElementFlags>),
}

impl fmt::Display for Element {
Expand Down Expand Up @@ -206,6 +214,18 @@ impl fmt::Display for Element {
.map_or(String::new(), |f| format!(", flags: {:?}", f))
)
}
Element::CountSumTree(root_key, count_value, sum_value, flags) => {
write!(
f,
"CountSumTree({}, {}, {}{})",
root_key.as_ref().map_or("None".to_string(), hex::encode),
count_value,
sum_value,
flags
.as_ref()
.map_or(String::new(), |f| format!(", flags: {:?}", f))
)
}
}
}
}
Expand All @@ -220,6 +240,7 @@ impl Element {
Element::SumTree(..) => "sum tree",
Element::BigSumTree(..) => "big sum tree",
Element::CountTree(..) => "count tree",
Element::CountSumTree(..) => "count sum tree",
}
}

Expand Down
Loading

0 comments on commit 3f6705f

Please sign in to comment.