34template <
typename LeafType,
typename HashingPolicy>
38 , max_leaves(1 << depth)
43 BB_ASSERT_GT(num_default_values,
static_cast<size_t>(0),
"Number of default values is not greater than 0");
46 default_leaves.reserve(num_default_values);
48 for (
size_t i = 0; i < num_default_values; ++i) {
50 default_leaves.push_back(LeafType::padding(i + 1));
56 for (
size_t i = 0; i < default_leaves.size(); ++i) {
58 index_t next_index = i == (default_leaves.size() - 1) ? 0 : i + 1;
59 FF next_key = i == (default_leaves.size() - 1) ? 0 : default_leaves.at(i + 1).get_key();
66 tree.update_element(i, leaf_hash);
73template <
typename LeafType,
typename HashingPolicy>
78 , max_leaves(1 << depth)
82 BB_ASSERT_GT(initial_leaves.size(),
static_cast<size_t>(0),
"Initial leaves size is not greater than 0");
85 for (
size_t i = 0; i < initial_leaves.size(); ++i) {
86 auto& leaf = initial_leaves[i];
88 FF leaf_hash = HashingPolicy::hash(leaf.get_hash_inputs());
89 tree.update_element(i, leaf_hash);
92 leaves.assign(initial_leaves.begin(), initial_leaves.end());
96template <
typename LeafType,
typename HashingPolicy>
101 size_t low_index = 0;
103 for (
size_t i = 0; i < leaves.size(); ++i) {
105 if (leaf_key_integer == key_integer) {
108 if (leaf_key_integer < key_integer && leaf_key_integer > low_key_integer) {
109 low_key_integer = leaf_key_integer;
117template <
typename LeafType,
typename HashingPolicy>
120 BB_ASSERT_DEBUG(leaf_index < leaves.size(),
"Leaf index out of bounds");
121 return leaves.at(leaf_index);
124template <
typename LeafType,
typename HashingPolicy>
127 return tree.get_sibling_path(leaf_index);
130template <
typename LeafType,
typename HashingPolicy>
135 .next_available_leaf_index = leaves.size(),
139template <
typename LeafType,
typename HashingPolicy>
147 for (
const auto& leaf_to_insert : leaves_to_insert) {
148 FF key = leaf_to_insert.get_key();
153 low_leaf, find_low_leaf_result.
index, tree.get_sibling_path(find_low_leaf_result.
index)));
158 index_t insertion_index = leaves.size();
160 low_leaf.nextIndex = insertion_index;
163 tree.update_element(find_low_leaf_result.
index, low_leaf_hash);
165 append_leaf(new_indexed_leaf);
167 tree.update_element(insertion_index, new_leaf_hash);
170 new_indexed_leaf, insertion_index, tree.get_sibling_path(insertion_index)));
172 }
else if (LeafType::is_updateable()) {
176 tree.update_element(find_low_leaf_result.
index, low_leaf_hash);
182 throw std::runtime_error(
"Leaf is not updateable");
189template <
typename LeafType,
typename HashingPolicy>
192 if (leaves.size() == max_leaves) {
193 throw std::runtime_error(
"IndexedMemoryTree is full");
196 leaves.push_back(leaf);
#define BB_ASSERT_GT(left, right,...)
#define BB_ASSERT_DEBUG(expression,...)
AppendOnlyTreeSnapshot get_snapshot() const
SequentialInsertionResult< LeafType > insert_indexed_leaves(std::span< const LeafType > leaves)
IndexedMemoryTree(size_t depth, std::span< IndexedLeaf< LeafType > > initial_leaves)
IndexedMemoryTree(size_t depth, size_t num_default_values)
void append_leaf(const IndexedLeaf< LeafType > &leaf)
GetLowIndexedLeafResponse get_low_indexed_leaf(const FF &key) const
std::vector< IndexedLeaf< LeafType > > leaves
IndexedLeaf< LeafType > get_leaf_preimage(size_t leaf_index) const
SiblingPath get_sibling_path(size_t leaf_index) const
MemoryTree< HashingPolicy > tree
IndexedTreeLeafData low_leaf
AVM range check gadget for witness generation.
::bb::crypto::merkle_tree::fr_sibling_path SiblingPath
::bb::crypto::merkle_tree::index_t index_t
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::vector< FF > get_hash_inputs() const
std::vector< fr > get_hash_inputs() const
std::vector< crypto::merkle_tree::LeafUpdateWitnessData< LeafValueType > > low_leaf_witness_data
std::vector< crypto::merkle_tree::LeafUpdateWitnessData< LeafValueType > > insertion_witness_data