// Copyright (c) Meta Platforms, Inc. and affiliates. // This source code is licensed under both the GPLv2 (found in the // COPYING file in the root directory) and Apache 2.0 License // (found in the LICENSE.Apache file in the root directory). // Code supporting block cache (Cache) access for block-based table, based on // the convenient APIs in typed_cache.h #pragma once #include #include "cache/typed_cache.h" #include "port/lang.h" #include "table/block_based/block.h" #include "table/block_based/block_type.h" #include "table/block_based/parsed_full_filter_block.h" #include "table/format.h" namespace ROCKSDB_NAMESPACE { // Metaprogramming wrappers for Block, to give each type a single role when // used with FullTypedCacheInterface. // (NOTE: previous attempts to create actual derived classes of Block with // virtual calls resulted in performance regression) class Block_kData : public Block { public: using Block::Block; static constexpr CacheEntryRole kCacheEntryRole = CacheEntryRole::kDataBlock; static constexpr BlockType kBlockType = BlockType::kData; }; class Block_kIndex : public Block { public: using Block::Block; static constexpr CacheEntryRole kCacheEntryRole = CacheEntryRole::kIndexBlock; static constexpr BlockType kBlockType = BlockType::kIndex; }; class Block_kFilterPartitionIndex : public Block { public: using Block::Block; static constexpr CacheEntryRole kCacheEntryRole = CacheEntryRole::kFilterMetaBlock; static constexpr BlockType kBlockType = BlockType::kFilterPartitionIndex; }; class Block_kRangeDeletion : public Block { public: using Block::Block; static constexpr CacheEntryRole kCacheEntryRole = CacheEntryRole::kOtherBlock; static constexpr BlockType kBlockType = BlockType::kRangeDeletion; }; // Useful for creating the Block even though meta index blocks are not // yet stored in block cache class Block_kMetaIndex : public Block { public: using Block::Block; static constexpr CacheEntryRole kCacheEntryRole = CacheEntryRole::kOtherBlock; static constexpr BlockType kBlockType = BlockType::kMetaIndex; }; struct BlockCreateContext : public Cache::CreateContext { BlockCreateContext() {} BlockCreateContext(const BlockBasedTableOptions* _table_options, Statistics* _statistics, bool _using_zstd, uint8_t _protection_bytes_per_key, const Comparator* _raw_ucmp, bool _index_value_is_full = false, bool _index_has_first_key = false) : table_options(_table_options), statistics(_statistics), using_zstd(_using_zstd), protection_bytes_per_key(_protection_bytes_per_key), raw_ucmp(_raw_ucmp), index_value_is_full(_index_value_is_full), index_has_first_key(_index_has_first_key) {} const BlockBasedTableOptions* table_options = nullptr; Statistics* statistics = nullptr; bool using_zstd = false; uint8_t protection_bytes_per_key = 0; const Comparator* raw_ucmp = nullptr; bool index_value_is_full; bool index_has_first_key; // For TypedCacheInterface template inline void Create(std::unique_ptr* parsed_out, size_t* charge_out, const Slice& data, MemoryAllocator* alloc) { Create(parsed_out, BlockContents(AllocateAndCopyBlock(data, alloc), data.size())); *charge_out = parsed_out->get()->ApproximateMemoryUsage(); } void Create(std::unique_ptr* parsed_out, BlockContents&& block); void Create(std::unique_ptr* parsed_out, BlockContents&& block); void Create(std::unique_ptr* parsed_out, BlockContents&& block); void Create(std::unique_ptr* parsed_out, BlockContents&& block); void Create(std::unique_ptr* parsed_out, BlockContents&& block); void Create(std::unique_ptr* parsed_out, BlockContents&& block); void Create(std::unique_ptr* parsed_out, BlockContents&& block); }; // Convenient cache interface to use for block_cache, with support for // SecondaryCache. template using BlockCacheInterface = FullTypedCacheInterface; // Shortcut name for cache handles under BlockCacheInterface template using BlockCacheTypedHandle = typename BlockCacheInterface::TypedHandle; // Selects the right helper based on BlockType and CacheTier const Cache::CacheItemHelper* GetCacheItemHelper( BlockType block_type, CacheTier lowest_used_cache_tier = CacheTier::kNonVolatileBlockTier); // For SFINAE check that a type is "blocklike" with a kCacheEntryRole member. // Can get difficult compiler/linker errors without a good check like this. template using WithBlocklikeCheck = std::enable_if_t< TBlocklike::kCacheEntryRole == CacheEntryRole::kMisc || true, TUse>; } // namespace ROCKSDB_NAMESPACE