diff --git a/costs/src/lib.rs b/costs/src/lib.rs index c3d85530..7e576dc1 100644 --- a/costs/src/lib.rs +++ b/costs/src/lib.rs @@ -72,9 +72,29 @@ pub type ChildrenSizesWithValue = Option<( Option<(ChildKeyLength, ChildSumLength)>, )>; +/// The tree cost type +pub enum TreeCostType { + /// This is for sum trees and count trees + TreeFeatureUsesVarIntCostAs8Bytes, + /// This is for count sum trees + TreeFeatureUsesTwoVarIntsCostAs16Bytes, + /// This is for big sum trees + TreeFeatureUses16Bytes, +} + +impl TreeCostType { + fn cost_size(&self) -> u32 { + match self { + TreeCostType::TreeFeatureUsesVarIntCostAs8Bytes => 8, + TreeCostType::TreeFeatureUsesTwoVarIntsCostAs16Bytes => 16, + TreeCostType::TreeFeatureUses16Bytes => 16, + } + } +} + /// Children sizes starting with if we are in a sum tree pub type ChildrenSizesWithIsSumTree = Option<( - Option, + Option<(TreeCostType, FeatureSumLength)>, Option<(ChildKeyLength, ChildSumLength)>, Option<(ChildKeyLength, ChildSumLength)>, )>; @@ -199,10 +219,14 @@ impl OperationCost { paid_value_len -= right_child_sum_len; } - if let Some(sum_tree_len) = in_sum_tree { + let sum_tree_node_size = if let Some((tree_cost_type, sum_tree_len)) = in_sum_tree { + let cost_size = tree_cost_type.cost_size(); paid_value_len -= sum_tree_len; - paid_value_len += 8; - } + paid_value_len += cost_size; + cost_size + } else { + 0 + }; // This is the moment we need to add the required space (after removing // children) but before adding the parent to child hook @@ -210,9 +234,6 @@ impl OperationCost { // Now we are the parent to child hook - // we need to add the sum tree node size - let sum_tree_node_size = if in_sum_tree.is_some() { 8 } else { 0 }; - // We need to add the cost of a parent // key_len has a hash length already in it from the key prefix // So we need to remove it and then add a hash length diff --git a/grovedb/src/batch/estimated_costs/average_case_costs.rs b/grovedb/src/batch/estimated_costs/average_case_costs.rs index 112aac04..cc7cd452 100644 --- a/grovedb/src/batch/estimated_costs/average_case_costs.rs +++ b/grovedb/src/batch/estimated_costs/average_case_costs.rs @@ -11,8 +11,8 @@ use grovedb_costs::{ cost_return_on_error, cost_return_on_error_no_add, CostResult, CostsExt, OperationCost, }; #[cfg(feature = "full")] -use grovedb_merk::{ - estimated_costs::average_case_costs::{average_case_merk_propagate, EstimatedLayerInformation}, +use grovedb_merk::estimated_costs::average_case_costs::{ + average_case_merk_propagate, EstimatedLayerInformation, }; use grovedb_merk::{merk::TreeType, tree::AggregateData, RootHashKeyAndAggregateData}; #[cfg(feature = "full")] diff --git a/grovedb/src/batch/mod.rs b/grovedb/src/batch/mod.rs index 1d431624..e1f8991c 100644 --- a/grovedb/src/batch/mod.rs +++ b/grovedb/src/batch/mod.rs @@ -75,8 +75,8 @@ 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, COUNT_SUM_TREE_COST_SIZE, SUM_ITEM_COST_SIZE, - SUM_TREE_COST_SIZE, TREE_COST_SIZE, + MaxReferenceHop, BIG_SUM_TREE_COST_SIZE, COUNT_SUM_TREE_COST_SIZE, COUNT_TREE_COST_SIZE, + SUM_ITEM_COST_SIZE, SUM_TREE_COST_SIZE, TREE_COST_SIZE, }, operations::{get::MAX_REFERENCE_HOPS, proof::util::hex_to_ascii}, reference_path::{ @@ -1022,7 +1022,8 @@ where Element::Tree(..) | Element::SumTree(..) | Element::BigSumTree(..) - | Element::CountTree(..) | Element::CountSumTree(..) => Err(Error::InvalidBatchOperation( + | Element::CountTree(..) + | Element::CountSumTree(..) => Err(Error::InvalidBatchOperation( "references can not point to trees being updated", )) .wrap_with_cost(cost), @@ -1143,7 +1144,8 @@ where Element::Tree(..) | Element::SumTree(..) | Element::BigSumTree(..) - | Element::CountTree(..) | Element::CountSumTree(..) => Err(Error::InvalidBatchOperation( + | Element::CountTree(..) + | Element::CountSumTree(..) => Err(Error::InvalidBatchOperation( "references can not point to trees being updated", )) .wrap_with_cost(cost), @@ -1173,7 +1175,8 @@ where Element::Tree(..) | Element::SumTree(..) | Element::BigSumTree(..) - | Element::CountTree(..) | Element::CountSumTree(..) => Err(Error::InvalidBatchOperation( + | Element::CountTree(..) + | Element::CountSumTree(..) => Err(Error::InvalidBatchOperation( "references can not point to trees being updated", )) .wrap_with_cost(cost), @@ -1348,7 +1351,8 @@ where Element::Tree(..) | Element::SumTree(..) | Element::BigSumTree(..) - | Element::CountTree(..) | Element::CountSumTree(..) => { + | Element::CountTree(..) + | Element::CountSumTree(..) => { let merk_feature_type = cost_return_on_error!( &mut cost, element @@ -1658,7 +1662,8 @@ where Element::Tree(..) | Element::SumTree(..) | Element::BigSumTree(..) - | Element::CountTree(..) | Element::CountSumTree(..) => { + | Element::CountTree(..) + | Element::CountSumTree(..) => { let tree_type = new_element.tree_type().unwrap(); let tree_cost_size = match tree_type { TreeType::NormalTree => TREE_COST_SIZE, diff --git a/grovedb/src/element/get.rs b/grovedb/src/element/get.rs index 9ff281da..f9a8dc6e 100644 --- a/grovedb/src/element/get.rs +++ b/grovedb/src/element/get.rs @@ -201,7 +201,7 @@ impl Element { | Some(Element::SumTree(_, _, flags)) | Some(Element::BigSumTree(_, _, flags)) | Some(Element::CountTree(_, _, flags)) - | Some(Element::CountSumTree(.. , 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; diff --git a/grovedb/src/element/helpers.rs b/grovedb/src/element/helpers.rs index 0acb9d3f..0ecac752 100644 --- a/grovedb/src/element/helpers.rs +++ b/grovedb/src/element/helpers.rs @@ -8,7 +8,7 @@ use grovedb_merk::tree::kv::{ }; use grovedb_merk::{ merk::{NodeType, TreeType}, - TreeFeatureType::{BigSummedMerkNode, CountedMerkNode}, + TreeFeatureType::{BigSummedMerkNode, CountedMerkNode, CountedSummedMerkNode}, }; #[cfg(feature = "full")] use grovedb_merk::{ @@ -20,7 +20,7 @@ use grovedb_merk::{ use grovedb_version::{check_grovedb_v0, error::GroveVersionError, version::GroveVersion}; #[cfg(feature = "full")] use integer_encoding::VarInt; -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; @@ -245,7 +245,10 @@ 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())), + TreeType::CountSumTree => Ok(CountedSummedMerkNode( + self.count_value_or_default(), + self.sum_value_or_default(), + )), } } @@ -416,7 +419,7 @@ impl Element { key_len, value_len, node_type, ) } - Element::CountSumTree(.. , flags) => { + 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 diff --git a/grovedb/src/element/mod.rs b/grovedb/src/element/mod.rs index 5b831a11..bc3b8baf 100644 --- a/grovedb/src/element/mod.rs +++ b/grovedb/src/element/mod.rs @@ -24,13 +24,13 @@ mod serialize; use std::fmt; use bincode::{Decode, Encode}; +use grovedb_merk::estimated_costs::SUM_AND_COUNT_LAYER_COST_SIZE; #[cfg(any(feature = "full", feature = "verify"))] use grovedb_merk::estimated_costs::SUM_VALUE_EXTRA_COST; #[cfg(feature = "full")] 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")] diff --git a/grovedb/src/operations/get/mod.rs b/grovedb/src/operations/get/mod.rs index c035147f..88022d66 100644 --- a/grovedb/src/operations/get/mod.rs +++ b/grovedb/src/operations/get/mod.rs @@ -458,7 +458,8 @@ impl GroveDb { Ok(Element::Tree(..)) | Ok(Element::SumTree(..)) | Ok(Element::BigSumTree(..)) - | Ok(Element::CountTree(..)) | Ok(Element::CountSumTree(..)) => Ok(()).wrap_with_cost(cost), + | Ok(Element::CountTree(..)) + | Ok(Element::CountSumTree(..)) => Ok(()).wrap_with_cost(cost), Ok(_) | Err(Error::PathKeyNotFound(_)) => Err(error_fn()).wrap_with_cost(cost), Err(e) => Err(e).wrap_with_cost(cost), } diff --git a/grovedb/src/operations/get/query.rs b/grovedb/src/operations/get/query.rs index 584e6ce7..618680dc 100644 --- a/grovedb/src/operations/get/query.rs +++ b/grovedb/src/operations/get/query.rs @@ -445,7 +445,10 @@ where { Ok(QueryItemOrSumReturnType::CountValue(count_value)) } Element::CountSumTree(_, count_value, sum_value, _) => { - Ok(QueryItemOrSumReturnType::CountSumValue(count_value, sum_value)) + Ok(QueryItemOrSumReturnType::CountSumValue( + count_value, + sum_value, + )) } _ => Err(Error::InvalidQuery( "the reference must result in an item", @@ -470,9 +473,9 @@ where { Element::CountTree(_, count_value, _) => { Ok(QueryItemOrSumReturnType::CountValue(count_value)) } - Element::CountSumTree(_, count_value, sum_value, _) => { - Ok(QueryItemOrSumReturnType::CountSumValue(count_value, sum_value)) - } + Element::CountSumTree(_, count_value, sum_value, _) => Ok( + QueryItemOrSumReturnType::CountSumValue(count_value, sum_value), + ), Element::Tree(..) => Err(Error::InvalidQuery( "path_queries can only refer to items, sum items, references and sum \ trees", diff --git a/grovedb/src/tests/sum_tree_tests.rs b/grovedb/src/tests/sum_tree_tests.rs index 0c9c19db..777fcb45 100644 --- a/grovedb/src/tests/sum_tree_tests.rs +++ b/grovedb/src/tests/sum_tree_tests.rs @@ -5,9 +5,8 @@ mod tests { use grovedb_merk::{ proofs::Query, tree::{kv::ValueDefinedCostType, AggregateData}, - TreeFeatureType::{BasicMerkNode, SummedMerkNode}, + TreeFeatureType::{BasicMerkNode, BigSummedMerkNode, SummedMerkNode}, }; - use grovedb_merk::TreeFeatureType::BigSummedMerkNode; use grovedb_storage::StorageBatch; use grovedb_version::version::GroveVersion; @@ -324,7 +323,9 @@ mod tests { Some(SummedMerkNode(0)) )); assert_eq!( - merk.aggregate_data().expect("expected to get sum").as_sum_i64(), + merk.aggregate_data() + .expect("expected to get sum") + .as_sum_i64(), 40 ); @@ -1063,8 +1064,8 @@ mod tests { None, grove_version, ) - .unwrap() - .expect("should insert tree"); + .unwrap() + .expect("should insert tree"); db.insert( [TEST_LEAF, b"big_sum_tree"].as_ref(), b"sum_tree_1", @@ -1073,8 +1074,8 @@ mod tests { None, grove_version, ) - .unwrap() - .expect("should insert tree"); + .unwrap() + .expect("should insert tree"); db.insert( [TEST_LEAF, b"big_sum_tree"].as_ref(), b"sum_tree_2", @@ -1083,8 +1084,8 @@ mod tests { None, grove_version, ) - .unwrap() - .expect("should insert tree"); + .unwrap() + .expect("should insert tree"); db.insert( [TEST_LEAF, b"big_sum_tree", b"sum_tree_1"].as_ref(), b"item1", @@ -1093,8 +1094,8 @@ mod tests { None, grove_version, ) - .unwrap() - .expect("should insert item"); + .unwrap() + .expect("should insert item"); db.insert( [TEST_LEAF, b"big_sum_tree", b"sum_tree_1"].as_ref(), b"sum_item_1", @@ -1103,8 +1104,8 @@ mod tests { None, grove_version, ) - .unwrap() - .expect("should insert item"); + .unwrap() + .expect("should insert item"); db.insert( [TEST_LEAF, b"big_sum_tree", b"sum_tree_1"].as_ref(), b"sum_item_2", @@ -1113,8 +1114,8 @@ mod tests { None, grove_version, ) - .unwrap() - .expect("should insert item"); + .unwrap() + .expect("should insert item"); db.insert( [TEST_LEAF, b"big_sum_tree", b"sum_tree_1"].as_ref(), b"ref_1", @@ -1128,8 +1129,8 @@ mod tests { None, grove_version, ) - .unwrap() - .expect("should insert item"); + .unwrap() + .expect("should insert item"); db.insert( [TEST_LEAF, b"big_sum_tree", b"sum_tree_2"].as_ref(), @@ -1139,14 +1140,17 @@ mod tests { None, grove_version, ) - .unwrap() - .expect("should insert item"); + .unwrap() + .expect("should insert item"); let sum_tree = db .get([TEST_LEAF].as_ref(), b"big_sum_tree", None, grove_version) .unwrap() .expect("should fetch tree"); - assert_eq!(sum_tree.big_sum_value_or_default(), (SumValue::MAX - 10) as i128 + (SumValue::MAX - 50) as i128); + assert_eq!( + sum_tree.big_sum_value_or_default(), + (SumValue::MAX - 10) as i128 + (SumValue::MAX - 50) as i128 + ); db.insert( [TEST_LEAF, b"big_sum_tree"].as_ref(), @@ -1156,14 +1160,19 @@ mod tests { None, grove_version, ) - .unwrap() - .expect("should insert item"); + .unwrap() + .expect("should insert item"); let sum_tree = db .get([TEST_LEAF].as_ref(), b"big_sum_tree", None, grove_version) .unwrap() .expect("should fetch tree"); - assert_eq!(sum_tree.big_sum_value_or_default(), (SumValue::MAX - 10) as i128 + (SumValue::MAX - 50) as i128 + (SumValue::MAX - 70) as i128 ); + assert_eq!( + sum_tree.big_sum_value_or_default(), + (SumValue::MAX - 10) as i128 + + (SumValue::MAX - 50) as i128 + + (SumValue::MAX - 70) as i128 + ); let batch = StorageBatch::new(); @@ -1202,10 +1211,11 @@ mod tests { b"sum_tree_1", true, Some(&Element::value_defined_cost_for_serialized_value), - grove_version + grove_version, ) .unwrap() - .expect("node should exist").expect("expected feature type"); + .expect("node should exist") + .expect("expected feature type"); assert_eq!( feature_type, BigSummedMerkNode((SumValue::MAX - 10) as i128) @@ -1216,10 +1226,11 @@ mod tests { b"sum_item_4", true, Some(&Element::value_defined_cost_for_serialized_value), - grove_version + grove_version, ) .unwrap() - .expect("node should exist").expect("expected feature type"); + .expect("node should exist") + .expect("expected feature type"); assert_eq!( feature_type, BigSummedMerkNode((SumValue::MAX - 70) as i128) @@ -1570,11 +1581,11 @@ mod tests { ) .unwrap() .expect("node should exist"), - Some(SummedMerkNode(10)) + Some(BigSummedMerkNode(10)) ); assert_eq!( sum_tree.aggregate_data().expect("expected to get sum"), - AggregateData::Sum(20) + AggregateData::BigSum(20) ); // Test propagation @@ -1652,7 +1663,7 @@ mod tests { .expect("should open tree"); assert_eq!( sum_tree.aggregate_data().expect("expected to get sum"), - AggregateData::Sum(41) + AggregateData::BigSum(41) ); } } diff --git a/merk/src/estimated_costs/mod.rs b/merk/src/estimated_costs/mod.rs index eb2eaa40..5ad58c0a 100644 --- a/merk/src/estimated_costs/mod.rs +++ b/merk/src/estimated_costs/mod.rs @@ -43,7 +43,8 @@ pub const SUM_LAYER_COST_SIZE: u32 = LAYER_COST_SIZE + SUM_VALUE_EXTRA_COST; #[cfg(feature = "full")] /// The cost of a summed subtree layer /// This is the layer size + 9 for the encoded value -pub const SUM_AND_COUNT_LAYER_COST_SIZE: u32 = LAYER_COST_SIZE + SUM_VALUE_EXTRA_COST + COUNT_VALUE_EXTRA_COST; +pub const SUM_AND_COUNT_LAYER_COST_SIZE: u32 = + LAYER_COST_SIZE + SUM_VALUE_EXTRA_COST + COUNT_VALUE_EXTRA_COST; #[cfg(feature = "full")] /// The cost of a summed subtree layer diff --git a/merk/src/merk/committer.rs b/merk/src/merk/committer.rs index c260c355..49e4fbdc 100644 --- a/merk/src/merk/committer.rs +++ b/merk/src/merk/committer.rs @@ -44,7 +44,8 @@ impl Commit for MerkCommitter { let right_child_sizes = tree.child_ref_and_sum_size(false); self.batch.push(( tree.key().to_vec(), - tree.feature_type().tree_feature_length(), + tree.feature_type() + .tree_feature_specialized_type_and_length(), Some((buf, left_child_sizes, right_child_sizes)), storage_costs, )); diff --git a/merk/src/merk/mod.rs b/merk/src/merk/mod.rs index e4abe750..bcf53780 100644 --- a/merk/src/merk/mod.rs +++ b/merk/src/merk/mod.rs @@ -52,7 +52,7 @@ use committer::MerkCommitter; use grovedb_costs::{ cost_return_on_error, cost_return_on_error_default, cost_return_on_error_no_add, storage_cost::key_value_cost::KeyValueStorageCost, ChildrenSizesWithValue, CostContext, - CostResult, CostsExt, FeatureSumLength, OperationCost, + CostResult, CostsExt, FeatureSumLength, OperationCost, TreeCostType, }; use grovedb_storage::{self, Batch, RawIterator, StorageContext}; use grovedb_version::version::GroveVersion; @@ -107,7 +107,7 @@ impl KeyUpdates { /// Type alias for simple function signature pub type BatchValue = ( Vec, - Option, + Option<(TreeCostType, FeatureSumLength)>, ChildrenSizesWithValue, KeyValueStorageCost, ); @@ -367,7 +367,7 @@ impl fmt::Debug for Merk { pub type UseTreeMutResult = CostResult< Vec<( Vec, - Option, + Option<(TreeCostType, FeatureSumLength)>, ChildrenSizesWithValue, KeyValueStorageCost, )>, diff --git a/merk/src/tree/link.rs b/merk/src/tree/link.rs index 5bffb025..3e826e38 100644 --- a/merk/src/tree/link.rs +++ b/merk/src/tree/link.rs @@ -289,7 +289,7 @@ impl Link { // sum_len for sum vale key.len() + 44 // 1 + 32 + 2 + 1 + 8 } - AggregateData::BigSum(_) | AggregateData::CountAndSum(_, _) => { + AggregateData::BigSum(_) | AggregateData::CountAndSum(..) => { // 1 for key len // key_len for keys // 32 for hash @@ -316,7 +316,7 @@ impl Link { AggregateData::Count(_) | AggregateData::Sum(_) => { tree.key().len() + 44 // 1 + 32 + 2 + 1 + 8 } - AggregateData::BigSum(_) | AggregateData::CountAndSum(_, _) => { + AggregateData::BigSum(_) | AggregateData::CountAndSum(..) => { tree.key().len() + 52 // 1 + 32 + 2 + 1 + 16 } }, diff --git a/merk/src/tree/mod.rs b/merk/src/tree/mod.rs index 8abb7e8c..8a10f82b 100644 --- a/merk/src/tree/mod.rs +++ b/merk/src/tree/mod.rs @@ -460,7 +460,9 @@ impl TreeNode { AggregateData::Sum(s) => s.encode_var_vec().len() as u32, AggregateData::BigSum(_) => 16 as u32, AggregateData::Count(c) => c.encode_var_vec().len() as u32, - AggregateData::CountAndSum(c, s) => s.encode_var_vec().len() as u32 + c.encode_var_vec().len() as u32, + AggregateData::CountAndSum(c, s) => { + s.encode_var_vec().len() as u32 + c.encode_var_vec().len() as u32 + } }, ) }) @@ -525,7 +527,7 @@ impl TreeNode { Some(link) => match link.aggregateData() { AggregateData::NoAggregateData => Ok(0), AggregateData::Sum(s) => Ok(0), - AggregateData::BigSum(_) => Ok(0), + AggregateData::BigSum(_) => Ok(0), AggregateData::Count(c) => Ok(c), AggregateData::CountAndSum(c, _) => Ok(c), }, @@ -603,7 +605,10 @@ impl TreeNode { .and_then(|a| a.checked_add(right_sum)) .ok_or(Overflow("count is overflowing"))?; - Ok(AggregateData::CountAndSum(aggregated_count_value, aggregated_sum_value)) + Ok(AggregateData::CountAndSum( + aggregated_count_value, + aggregated_sum_value, + )) } } } diff --git a/merk/src/tree/tree_feature_type.rs b/merk/src/tree/tree_feature_type.rs index cf40320e..f83199d7 100644 --- a/merk/src/tree/tree_feature_type.rs +++ b/merk/src/tree/tree_feature_type.rs @@ -8,6 +8,7 @@ use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use ed::Terminated; #[cfg(any(feature = "full", feature = "verify"))] use ed::{Decode, Encode}; +use grovedb_costs::TreeCostType; #[cfg(any(feature = "full", feature = "verify"))] use integer_encoding::{VarInt, VarIntReader, VarIntWriter}; @@ -15,9 +16,8 @@ use integer_encoding::{VarInt, VarIntReader, VarIntWriter}; use crate::tree::tree_feature_type::TreeFeatureType::{BasicMerkNode, SummedMerkNode}; use crate::{ merk::{NodeType, TreeType}, - TreeFeatureType::{BigSummedMerkNode, CountedMerkNode}, + TreeFeatureType::{BigSummedMerkNode, CountedMerkNode, CountedSummedMerkNode}, }; -use crate::TreeFeatureType::CountedSummedMerkNode; #[cfg(any(feature = "full", feature = "verify"))] #[derive(Copy, Clone, PartialEq, Eq, Debug)] @@ -42,7 +42,7 @@ impl TreeFeatureType { SummedMerkNode(_) => NodeType::SumNode, BigSummedMerkNode(_) => NodeType::BigSumNode, CountedMerkNode(_) => NodeType::CountNode, - CountedSummedMerkNode(_, _) => NodeType::CountSumNode, + CountedSummedMerkNode(..) => NodeType::CountSumNode, } } } @@ -54,7 +54,7 @@ pub enum AggregateData { Sum(i64), BigSum(i128), Count(u64), - CountAndSum(u64, i64) + CountAndSum(u64, i64), } impl AggregateData { @@ -64,7 +64,7 @@ impl AggregateData { AggregateData::Sum(_) => TreeType::SumTree, AggregateData::BigSum(_) => TreeType::BigSumTree, AggregateData::Count(_) => TreeType::CountTree, - AggregateData::CountAndSum(_, _) => TreeType::CountSumTree, + AggregateData::CountAndSum(..) => TreeType::CountSumTree, } } @@ -144,13 +144,22 @@ impl From for AggregateData { impl TreeFeatureType { #[inline] /// Get length of encoded SummedMerk - pub fn tree_feature_length(&self) -> Option { + pub fn tree_feature_specialized_type_and_length(&self) -> Option<(TreeCostType, u32)> { match self { BasicMerkNode => None, - SummedMerkNode(m) => Some(m.encode_var_vec().len() as u32), - BigSummedMerkNode(_) => Some(16), - CountedMerkNode(m) => Some(m.encode_var_vec().len() as u32), - CountedSummedMerkNode(count, sum) => Some(count.encode_var_vec().len() as u32 + sum.encode_var_vec().len() as u32), + SummedMerkNode(m) => Some(( + TreeCostType::TreeFeatureUsesVarIntCostAs8Bytes, + m.encode_var_vec().len() as u32, + )), + BigSummedMerkNode(_) => Some((TreeCostType::TreeFeatureUses16Bytes, 16)), + CountedMerkNode(m) => Some(( + TreeCostType::TreeFeatureUsesVarIntCostAs8Bytes, + m.encode_var_vec().len() as u32, + )), + CountedSummedMerkNode(count, sum) => Some(( + TreeCostType::TreeFeatureUsesTwoVarIntsCostAs16Bytes, + count.encode_var_vec().len() as u32 + sum.encode_var_vec().len() as u32, + )), } }