diff --git a/libraries/chain/chaindb/cache_map.cpp b/libraries/chain/chaindb/cache_map.cpp index 3f38fc2598a..17df6b6308d 100644 --- a/libraries/chain/chaindb/cache_map.cpp +++ b/libraries/chain/chaindb/cache_map.cpp @@ -322,7 +322,7 @@ namespace cyberway { namespace chaindb { } if (object_ptr->has_cell()) { - object_ptr->mark_deleted(); + object_ptr->release(); } object_ptr.reset(); } @@ -653,7 +653,9 @@ namespace cyberway { namespace chaindb { service_tree_.erase(service_itr); } - add_ram_usage(obj.cell(), -obj.service().size); + if (obj.has_cell()) { + add_ram_usage(obj.cell(), -obj.service().size); + } } } @@ -669,7 +671,7 @@ namespace cyberway { namespace chaindb { return false; } - void change_cache_object(cache_object& obj, const int delta, cache_indicies& indicies) { + void change_cache_object(cache_object& obj, const int delta) { add_ram_usage(obj.cell(), delta); if (is_system_code(obj.service().code)) { @@ -680,13 +682,13 @@ namespace cyberway { namespace chaindb { } // don't rebuild indicies for interchain objects - if (indicies.capacity()) { + if (obj.indicies_.capacity()) { return; } } - delete_cache_indicies(indicies); - build_cache_indicies(obj, indicies); + delete_cache_indicies(obj.indicies_); + build_cache_indicies(obj); } private: @@ -821,7 +823,7 @@ namespace cyberway { namespace chaindb { return nullptr; } - void build_cache_indicies(cache_object& obj, cache_indicies& indicies) { + void build_cache_indicies(cache_object& obj) { auto& object = obj.object(); if (object.is_null()) return; @@ -833,6 +835,7 @@ namespace cyberway { namespace chaindb { auto ttr = abi.find_table(service.table); if (!ttr) return; + auto& indicies = obj.indicies_; indicies.reserve(ttr->indexes.size() - 1 /* skip primary */); auto info = index_info(service.code, service.scope); info.table = ttr; @@ -920,6 +923,10 @@ namespace cyberway { namespace chaindb { service.cache_object_cnt++; } + if (is_new_ptr) { + build_cache_indicies(*obj_ptr.get()); + } + return obj_ptr; } @@ -1029,7 +1036,7 @@ namespace cyberway { namespace chaindb { blob_.clear(); if (has_cell()) { - map().change_cache_object(*this, delta, indicies_); + map().change_cache_object(*this, delta); } } @@ -1054,9 +1061,16 @@ namespace cyberway { namespace chaindb { } void cache_object::release() { - auto& pending_state = pending_cache_object_state::cast(*state_); - pending_state.cell->map->release_cache_object(*this, indicies_, pending_state.is_deleted); + auto state = state_; state_ = nullptr; + + auto lru_state_ptr = lru_cache_object_state::cast(state); + if (lru_state_ptr) { + lru_state_ptr->cell->map->release_cache_object(*this, indicies_, false); + } else { + auto& pending_state = pending_cache_object_state::cast(*state); + pending_state.cell->map->release_cache_object(*this, indicies_, pending_state.is_deleted); + } } bool cache_object::is_deleted() const { diff --git a/libraries/chain/include/cyberway/chaindb/cache_item.hpp b/libraries/chain/include/cyberway/chaindb/cache_item.hpp index dd31c823108..af8fa9caa6a 100644 --- a/libraries/chain/include/cyberway/chaindb/cache_item.hpp +++ b/libraries/chain/include/cyberway/chaindb/cache_item.hpp @@ -87,6 +87,19 @@ namespace cyberway { namespace chaindb { cache_data_ptr data_; // for interchain tables cache_indicies indicies_; + private: + friend class cache_map_impl; + friend struct lru_cache_cell; + friend struct system_cache_cell; + friend struct pending_cache_cell; + friend struct pending_cache_object_state; + + const cache_cell& cell() const; + cache_cell& cell(); + cache_map_impl& map(); + cache_object_state& state(); + cache_object_state* swap_state(cache_object_state& state); + public: cache_object() = default; cache_object(cache_object&&) = default; @@ -99,12 +112,6 @@ namespace cyberway { namespace chaindb { bool is_deleted() const; - const cache_cell& cell() const; - cache_cell& cell(); - cache_map_impl& map(); - cache_object_state& state(); - cache_object_state* swap_state(cache_object_state& state); - template bool is_valid_table(const Request& request) const { return