16#include "msgpack/assert.hpp"
25#include <unordered_map>
56 void reset(uint32_t depth);
131 journals_.emplace_back(
Journal(meta_));
136 if (journals_.empty()) {
137 throw std::runtime_error(
"Cannot revert without a checkpoint");
145 Journal& journal = journals_.back();
148 for (
const auto& [index, optional_node_hash] : journal.
nodes_by_index_[i]) {
150 if (!optional_node_hash.has_value()) {
151 nodes_by_index_[i].erase(index);
154 nodes_by_index_[i][index] = optional_node_hash.value();
162 if (!optional_leaf.has_value()) {
163 leaf_pre_image_by_index_.erase(index);
167 leaf_pre_image_by_index_[index] = optional_leaf.value();
178 journals_.pop_back();
183 if (journals_.empty()) {
184 throw std::runtime_error(
"Cannot commit without a checkpoint");
191 if (journals_.size() == 1) {
196 Journal& current_journal = journals_.back();
197 Journal& previous_journal = journals_[journals_.size() - 2];
199 for (uint32_t i = 0; i < current_journal.
nodes_by_index_.size(); ++i) {
200 for (
const auto& [index, optional_node_hash] : current_journal.
nodes_by_index_[i]) {
227 journals_.pop_back();
232 while (!journals_.empty()) {
239 while (!journals_.empty()) {
253template <
typename LeafValueType>
257 if (meta_ != other.
meta_) {
277 for (
const auto& [leaf_hash, leaf] : leaves_) {
278 auto it = other.
leaves_.find(leaf_hash);
279 if (it == other.
leaves_.end()) {
282 if (it->second != leaf) {
288 for (
const auto& [node_hash, node] : nodes_) {
289 auto it = other.
nodes_.find(node_hash);
290 if (it == other.
nodes_.end()) {
293 if (it->second != node) {
300template <
typename LeafValueType>
305 if (indices_.empty()) {
309 auto it = indices_.lower_bound(new_leaf_key);
310 if (it == indices_.end()) {
316 return std::make_pair(
false, it->first > retrieved_value ? it->second : db_index);
319 if (it->first == new_leaf_key) {
327 if (it == indices_.begin()) {
333 return std::make_pair(
false, it->first > retrieved_value ? it->second : db_index);
336template <
typename LeafValueType>
340 typename std::unordered_map<fr, IndexedLeafValueType>::const_iterator it = leaves_.find(leaf_hash);
341 if (it != leaves_.end()) {
342 leaf_pre_image = it->second;
348template <
typename LeafValueType>
352 leaves_[leaf_hash] = leaf_pre_image;
355template <
typename LeafValueType>
359 typename std::unordered_map<index_t, IndexedLeafValueType>::const_iterator it =
360 leaf_pre_image_by_index_.find(index);
361 if (it != leaf_pre_image_by_index_.end()) {
362 leaf_pre_image = it->second;
368template <
typename LeafValueType>
373 if (journals_.empty()) {
374 leaf_pre_image_by_index_[index] = leaf_pre_image;
379 Journal& journal = journals_.back();
383 auto cache_iter = leaf_pre_image_by_index_.find(index);
384 if (cache_iter == leaf_pre_image_by_index_.end()) {
393 leaf_pre_image_by_index_[index] = leaf_pre_image;
396template <
typename LeafValueType>
400 auto result = indices_.insert({
key, index });
401 if (result.second && !journals_.empty()) {
403 Journal& journal = journals_.back();
408template <
typename LeafValueType>
411 auto it = indices_.find(
uint256_t(leaf_key));
412 if (it == indices_.end()) {
418template <
typename LeafValueType>
421 nodes_[node_hash] = node;
424template <
typename LeafValueType>
427 auto it = nodes_.find(node_hash);
428 if (it == nodes_.end()) {
435template <
typename LeafValueType>
438 auto it = nodes_by_index_[level].find(index);
439 if (it == nodes_by_index_[level].end()) {
445template <
typename LeafValueType>
449 if (journals_.empty()) {
450 nodes_by_index_[level][index] = node;
455 Journal& journal = journals_.back();
458 auto cacheIter = nodes_by_index_[level].find(index);
459 if (cacheIter == nodes_by_index_[level].end()) {
468 nodes_by_index_[level][index] = node;
std::unique_ptr< ContentAddressedCache > UniquePtr
std::vector< Journal > journals_
void put_leaf_by_index(const index_t &index, const IndexedLeafValueType &leaf_pre_image)
bool get_leaf_by_index(const index_t &index, IndexedLeafValueType &leaf_pre_image) const
ContentAddressedCache & operator=(const ContentAddressedCache &other)=default
void put_meta(const TreeMeta &meta)
void update_leaf_key_index(const index_t &index, const fr &leaf_key)
std::unordered_map< fr, IndexedLeafValueType > leaves_
std::map< uint256_t, index_t > indices_
void put_leaf_preimage_by_hash(const fr &leaf_hash, const IndexedLeafValueType &leaf_pre_image)
std::optional< fr > get_node_by_index(uint32_t level, const index_t &index) const
const std::map< uint256_t, index_t > & get_indices() const
std::shared_ptr< ContentAddressedCache > SharedPtr
std::unordered_map< fr, NodePayload > nodes_
std::optional< index_t > get_leaf_key_index(const fr &leaf_key) const
void put_node(const fr &node_hash, const NodePayload &node)
const TreeMeta & get_meta() const
ContentAddressedCache(ContentAddressedCache &&other) noexcept=default
std::pair< bool, index_t > find_low_value(const uint256_t &new_leaf_key, const uint256_t &retrieved_value, const index_t &db_index) const
bool get_node(const fr &node_hash, NodePayload &node) const
bool is_equivalent_to(const ContentAddressedCache &other) const
bool get_leaf_preimage_by_hash(const fr &leaf_hash, IndexedLeafValueType &leaf_pre_image) const
ContentAddressedCache(const ContentAddressedCache &other)=default
void reset(uint32_t depth)
bool operator==(const ContentAddressedCache &other) const =default
std::unordered_map< index_t, IndexedLeafValueType > leaf_pre_image_by_index_
~ContentAddressedCache()=default
void put_node_by_index(uint32_t level, const index_t &index, const fr &node)
ContentAddressedCache()=delete
std::vector< std::unordered_map< index_t, fr > > nodes_by_index_
ContentAddressedCache & operator=(ContentAddressedCache &&other) noexcept=default
PublicDataLeafValue LeafValueType
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::vector< std::unordered_map< index_t, std::optional< fr > > > nodes_by_index_
std::vector< uint256_t > new_leaf_keys_
std::unordered_map< index_t, std::optional< IndexedLeafValueType > > leaf_pre_image_by_index_