From bcea064b424750f3f2e7953371ae03085adcb39f Mon Sep 17 00:00:00 2001 From: canepat <16927169+canepat@users.noreply.github.com> Date: Tue, 25 Jun 2024 11:38:53 +0200 Subject: [PATCH] db: use ByteView in KV StateCache --- silkworm/db/kv/api/base_transaction.cpp | 6 ++---- silkworm/db/kv/api/state_cache.cpp | 26 +++++++++++++------------ silkworm/db/kv/api/state_cache.hpp | 16 +++++++-------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/silkworm/db/kv/api/base_transaction.cpp b/silkworm/db/kv/api/base_transaction.cpp index 13fee10a2c..9599eac80d 100644 --- a/silkworm/db/kv/api/base_transaction.cpp +++ b/silkworm/db/kv/api/base_transaction.cpp @@ -55,15 +55,13 @@ Task BaseTransaction::get_one_impl_with_cache(const std::string& table, B if (table == db::table::kPlainStateName) { std::shared_ptr view = state_cache_->get_view(*this); if (view != nullptr) { - // TODO(canepat) remove key copy changing DatabaseReader interface - const auto value = co_await view->get(silkworm::Bytes{key.data(), key.size()}); + const auto value = co_await view->get(key); co_return value ? *value : silkworm::Bytes{}; } } else if (table == db::table::kCodeName) { std::shared_ptr view = state_cache_->get_view(*this); if (view != nullptr) { - // TODO(canepat) remove key copy changing DatabaseReader interface - const auto value = co_await view->get_code(silkworm::Bytes{key.data(), key.size()}); + const auto value = co_await view->get_code(key); co_return value ? *value : silkworm::Bytes{}; } } diff --git a/silkworm/db/kv/api/state_cache.cpp b/silkworm/db/kv/api/state_cache.cpp index d8ee9a285a..277936ad98 100644 --- a/silkworm/db/kv/api/state_cache.cpp +++ b/silkworm/db/kv/api/state_cache.cpp @@ -32,11 +32,11 @@ namespace silkworm::db::kv::api { CoherentStateView::CoherentStateView(Transaction& txn, CoherentStateCache* cache) : txn_(txn), cache_(cache) {} -Task> CoherentStateView::get(const Bytes& key) { +Task> CoherentStateView::get(ByteView key) { co_return co_await cache_->get(key, txn_); } -Task> CoherentStateView::get_code(const Bytes& key) { +Task> CoherentStateView::get_code(ByteView key) { co_return co_await cache_->get_code(key, txn_); } @@ -156,7 +156,7 @@ void CoherentStateCache::process_storage_change(CoherentStateRoot* root, StateVi } } -bool CoherentStateCache::add(const KeyValue& kv, CoherentStateRoot* root, StateViewId view_id) { +bool CoherentStateCache::add(KeyValue&& kv, CoherentStateRoot* root, StateViewId view_id) { auto [it, inserted] = root->cache.insert(kv); SILK_DEBUG << "Data cache kv.key=" << to_hex(kv.key) << " inserted=" << inserted << " view=" << view_id; std::optional replaced; @@ -173,7 +173,7 @@ bool CoherentStateCache::add(const KeyValue& kv, CoherentStateRoot* root, StateV state_evictions_.remove(*replaced); SILK_DEBUG << "Data evictions removed replaced.key=" << to_hex(replaced->key); } - state_evictions_.push_front(kv); + state_evictions_.push_front(std::move(kv)); // Remove the longest unused key-value pair when size exceeded if (state_evictions_.size() > config_.max_state_keys) { @@ -186,7 +186,7 @@ bool CoherentStateCache::add(const KeyValue& kv, CoherentStateRoot* root, StateV return inserted; } -bool CoherentStateCache::add_code(const KeyValue& kv, CoherentStateRoot* root, StateViewId view_id) { +bool CoherentStateCache::add_code(KeyValue&& kv, CoherentStateRoot* root, StateViewId view_id) { auto [it, inserted] = root->code_cache.insert(kv); SILK_DEBUG << "Code cache kv.key=" << to_hex(kv.key) << " inserted=" << inserted << " view=" << view_id; std::optional replaced; @@ -203,7 +203,7 @@ bool CoherentStateCache::add_code(const KeyValue& kv, CoherentStateRoot* root, S code_evictions_.remove(*replaced); SILK_DEBUG << "Code evictions removed replaced.key=" << to_hex(replaced->key); } - code_evictions_.push_front(kv); + code_evictions_.push_front(std::move(kv)); // Remove the longest unused key-value pair when size exceeded if (code_evictions_.size() > config_.max_code_keys) { @@ -216,7 +216,7 @@ bool CoherentStateCache::add_code(const KeyValue& kv, CoherentStateRoot* root, S return inserted; } -Task> CoherentStateCache::get(const Bytes& key, Transaction& tx) { +Task> CoherentStateCache::get(ByteView key, Transaction& tx) { std::shared_lock read_lock{rw_mutex_}; const auto view_id = tx.view_id(); @@ -225,7 +225,7 @@ Task> CoherentStateCache::get(const Bytes& key, Transaction co_return std::nullopt; } - KeyValue kv{key}; + KeyValue kv{Bytes{key}}; auto& cache = root_it->second->cache; const auto kv_it = cache.find(kv); if (kv_it != cache.end()) { @@ -252,12 +252,13 @@ Task> CoherentStateCache::get(const Bytes& key, Transaction read_lock.unlock(); std::unique_lock write_lock{rw_mutex_}; - add({key, value}, root_it->second.get(), view_id); + kv.value = value; + add(std::move(kv), root_it->second.get(), view_id); co_return value; } -Task> CoherentStateCache::get_code(const Bytes& key, Transaction& tx) { +Task> CoherentStateCache::get_code(ByteView key, Transaction& tx) { std::shared_lock read_lock{rw_mutex_}; const auto view_id = tx.view_id(); @@ -266,7 +267,7 @@ Task> CoherentStateCache::get_code(const Bytes& key, Transa co_return std::nullopt; } - KeyValue kv{key}; + KeyValue kv{Bytes{key}}; auto& code_cache = root_it->second->code_cache; const auto kv_it = code_cache.find(kv); if (kv_it != code_cache.end()) { @@ -293,7 +294,8 @@ Task> CoherentStateCache::get_code(const Bytes& key, Transa read_lock.unlock(); std::unique_lock write_lock{rw_mutex_}; - add_code({key, value}, root_it->second.get(), view_id); + kv.value = value; + add_code(std::move(kv), root_it->second.get(), view_id); co_return value; } diff --git a/silkworm/db/kv/api/state_cache.hpp b/silkworm/db/kv/api/state_cache.hpp index 397c99c117..b976c33625 100644 --- a/silkworm/db/kv/api/state_cache.hpp +++ b/silkworm/db/kv/api/state_cache.hpp @@ -40,9 +40,9 @@ class StateView { public: virtual ~StateView() = default; - virtual Task> get(const Bytes& key) = 0; + virtual Task> get(ByteView key) = 0; - virtual Task> get_code(const Bytes& key) = 0; + virtual Task> get_code(ByteView key) = 0; }; class StateCache { @@ -95,9 +95,9 @@ class CoherentStateView : public StateView { CoherentStateView(const CoherentStateView&) = delete; CoherentStateView& operator=(const CoherentStateView&) = delete; - Task> get(const Bytes& key) override; + Task> get(ByteView key) override; - Task> get_code(const Bytes& key) override; + Task> get_code(ByteView key) override; private: Transaction& txn_; @@ -134,10 +134,10 @@ class CoherentStateCache : public StateCache { void process_code_change(CoherentStateRoot* root, StateViewId view_id, const remote::AccountChange& change); void process_delete_change(CoherentStateRoot* root, StateViewId view_id, const remote::AccountChange& change); void process_storage_change(CoherentStateRoot* root, StateViewId view_id, const remote::AccountChange& change); - bool add(const KeyValue& kv, CoherentStateRoot* root, StateViewId view_id); - bool add_code(const KeyValue& kv, CoherentStateRoot* root, StateViewId view_id); - Task> get(const Bytes& key, Transaction& txn); - Task> get_code(const Bytes& key, Transaction& txn); + bool add(KeyValue&& kv, CoherentStateRoot* root, StateViewId view_id); + bool add_code(KeyValue&& kv, CoherentStateRoot* root, StateViewId view_id); + Task> get(ByteView key, Transaction& txn); + Task> get_code(ByteView key, Transaction& txn); CoherentStateRoot* get_root(StateViewId view_id); CoherentStateRoot* advance_root(StateViewId view_id); void evict_roots(StateViewId next_view_id);