diff --git a/HISTORY.md b/HISTORY.md index 21b8e76d8..f4e11c68c 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -41,7 +41,6 @@ ### Performance Improvements * Instead of constructing `FragmentedRangeTombstoneList` during every read operation, it is now constructed once and stored in immutable memtables. This improves speed of querying range tombstones from immutable memtables. -* Improve read performance by avoiding dynamic memory allocation. * When using iterators with the integrated BlobDB implementation, blob cache handles are now released immediately when the iterator's position changes. ## Behavior Change diff --git a/table/block_based/block_based_table_reader.cc b/table/block_based/block_based_table_reader.cc index 52606f6ba..0c45693a4 100644 --- a/table/block_based/block_based_table_reader.cc +++ b/table/block_based/block_based_table_reader.cc @@ -1251,12 +1251,8 @@ Status BlockBasedTable::GetDataBlockFromCache( Statistics* statistics = rep_->ioptions.statistics.get(); bool using_zstd = rep_->blocks_definitely_zstd_compressed; const FilterPolicy* filter_policy = rep_->filter_policy; - CacheCreateCallback callback(read_amp_bytes_per_bit, statistics, - using_zstd, filter_policy); - // avoid dynamic memory allocation by using the reference (std::ref) of the - // callback. Otherwise, binding a functor to std::function will allocate extra - // memory from heap. - Cache::CreateCallback create_cb(std::ref(callback)); + Cache::CreateCallback create_cb = GetCreateCallback( + read_amp_bytes_per_bit, statistics, using_zstd, filter_policy); // Lookup uncompressed cache first if (block_cache != nullptr) { @@ -1286,11 +1282,8 @@ Status BlockBasedTable::GetDataBlockFromCache( BlockContents contents; if (rep_->ioptions.lowest_used_cache_tier == CacheTier::kNonVolatileBlockTier) { - CacheCreateCallback special_callback( + Cache::CreateCallback create_cb_special = GetCreateCallback( read_amp_bytes_per_bit, statistics, using_zstd, filter_policy); - // avoid dynamic memory allocation by using the reference (std::ref) of the - // callback. Make sure the callback is only used within this code block. - Cache::CreateCallback create_cb_special(std::ref(special_callback)); block_cache_compressed_handle = block_cache_compressed->Lookup( cache_key, BlocklikeTraits::GetCacheItemHelper(block_type), diff --git a/table/block_based/block_like_traits.h b/table/block_based/block_like_traits.h index 86df17db2..aeb255114 100644 --- a/table/block_based/block_like_traits.h +++ b/table/block_based/block_like_traits.h @@ -21,42 +21,24 @@ template Cache::CacheItemHelper* GetCacheItemHelperForRole(); template -class CacheCreateCallback { - public: - CacheCreateCallback() = delete; - CacheCreateCallback(const CacheCreateCallback&) = delete; - CacheCreateCallback(CacheCreateCallback&&) = delete; - CacheCreateCallback& operator=(const CacheCreateCallback&) = delete; - CacheCreateCallback& operator=(CacheCreateCallback&&) = delete; - - explicit CacheCreateCallback(size_t read_amp_bytes_per_bit, - Statistics* statistics, bool using_zstd, - const FilterPolicy* filter_policy) - : read_amp_bytes_per_bit_(read_amp_bytes_per_bit), - statistics_(statistics), - using_zstd_(using_zstd), - filter_policy_(filter_policy) {} - - Status operator()(const void* buf, size_t size, void** out_obj, - size_t* charge) { +Cache::CreateCallback GetCreateCallback(size_t read_amp_bytes_per_bit, + Statistics* statistics, bool using_zstd, + const FilterPolicy* filter_policy) { + return [read_amp_bytes_per_bit, statistics, using_zstd, filter_policy]( + const void* buf, size_t size, void** out_obj, + size_t* charge) -> Status { assert(buf != nullptr); std::unique_ptr buf_data(new char[size]()); memcpy(buf_data.get(), buf, size); BlockContents bc = BlockContents(std::move(buf_data), size); TBlocklike* ucd_ptr = BlocklikeTraits::Create( - std::move(bc), read_amp_bytes_per_bit_, statistics_, using_zstd_, - filter_policy_); + std::move(bc), read_amp_bytes_per_bit, statistics, using_zstd, + filter_policy); *out_obj = reinterpret_cast(ucd_ptr); *charge = size; return Status::OK(); - } - - private: - const size_t read_amp_bytes_per_bit_; - Statistics* statistics_; - const bool using_zstd_; - const FilterPolicy* filter_policy_; -}; + }; +} template <> class BlocklikeTraits {