16#include "msgpack/assert.hpp"
25#include <unordered_map>
133 journals_.emplace_back(
Journal(meta_));
134 return static_cast<uint32_t
>(journals_.size());
139 if (journals_.empty()) {
140 throw std::runtime_error(
"Cannot revert without a checkpoint");
148 Journal& journal = journals_.back();
153 if (!optional_node_hash.has_value()) {
154 nodes_by_index_[i].erase(
index);
157 nodes_by_index_[i][
index] = optional_node_hash.value();
165 if (!optional_leaf.has_value()) {
166 leaf_pre_image_by_index_.erase(
index);
170 leaf_pre_image_by_index_[
index] = optional_leaf.value();
181 journals_.pop_back();
186 if (journals_.empty()) {
187 throw std::runtime_error(
"Cannot commit without a checkpoint");
194 if (journals_.size() == 1) {
199 Journal& current_journal = journals_.back();
200 Journal& previous_journal = journals_[journals_.size() - 2];
202 for (uint32_t i = 0; i < current_journal.
nodes_by_index_.size(); ++i) {
230 journals_.pop_back();
235 while (!journals_.empty()) {
242 while (!journals_.empty()) {
248 return static_cast<uint32_t
>(journals_.size());
253 if (target_depth >= journals_.size()) {
254 throw std::runtime_error(
"Invalid depth for commit_to_depth");
256 while (journals_.size() > target_depth) {
263 if (target_depth >= journals_.size()) {
264 throw std::runtime_error(
"Invalid depth for revert_to_depth");
266 while (journals_.size() > target_depth) {
281template <
typename LeafValueType>
285 if (meta_ != other.
meta_) {
305 for (
const auto& [leaf_hash, leaf] : leaves_) {
306 auto it = other.
leaves_.find(leaf_hash);
307 if (it == other.
leaves_.end()) {
310 if (it->second != leaf) {
316 for (
const auto& [node_hash, node] : nodes_) {
317 auto it = other.
nodes_.find(node_hash);
318 if (it == other.
nodes_.end()) {
321 if (it->second != node) {
328template <
typename LeafValueType>
333 if (indices_.empty()) {
337 auto it = indices_.lower_bound(new_leaf_key);
338 if (it == indices_.end()) {
344 return std::make_pair(
false, it->first > retrieved_value ? it->second : db_index);
347 if (it->first == new_leaf_key) {
355 if (it == indices_.begin()) {
361 return std::make_pair(
false, it->first > retrieved_value ? it->second : db_index);
364template <
typename LeafValueType>
368 typename std::unordered_map<fr, IndexedLeafValueType>::const_iterator it = leaves_.find(leaf_hash);
369 if (it != leaves_.end()) {
370 leaf_pre_image = it->second;
376template <
typename LeafValueType>
380 leaves_[leaf_hash] = leaf_pre_image;
383template <
typename LeafValueType>
387 typename std::unordered_map<index_t, IndexedLeafValueType>::const_iterator it =
388 leaf_pre_image_by_index_.find(
index);
389 if (it != leaf_pre_image_by_index_.end()) {
390 leaf_pre_image = it->second;
396template <
typename LeafValueType>
401 if (journals_.empty()) {
402 leaf_pre_image_by_index_[
index] = leaf_pre_image;
407 Journal& journal = journals_.back();
411 auto cache_iter = leaf_pre_image_by_index_.find(
index);
412 if (cache_iter == leaf_pre_image_by_index_.end()) {
421 leaf_pre_image_by_index_[
index] = leaf_pre_image;
424template <
typename LeafValueType>
428 auto result = indices_.insert({
key,
index });
429 if (result.second && !journals_.empty()) {
431 Journal& journal = journals_.back();
436template <
typename LeafValueType>
439 auto it = indices_.find(
uint256_t(leaf_key));
440 if (it == indices_.end()) {
446template <
typename LeafValueType>
449 nodes_[node_hash] = node;
452template <
typename LeafValueType>
455 auto it = nodes_.find(node_hash);
456 if (it == nodes_.end()) {
463template <
typename LeafValueType>
466 auto it = nodes_by_index_[level].find(
index);
467 if (it == nodes_by_index_[level].end()) {
473template <
typename LeafValueType>
477 if (journals_.empty()) {
478 nodes_by_index_[level][
index] = node;
483 Journal& journal = journals_.back();
486 auto cacheIter = nodes_by_index_[level].find(
index);
487 if (cacheIter == nodes_by_index_[level].end()) {
496 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
void revert_to_depth(uint32_t depth)
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_
ContentAddressedCache(uint32_t depth)
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 commit_to_depth(uint32_t depth)
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_