summaryrefslogtreecommitdiffstats
path: root/src/rocksdb/table/block_based/block_like_traits.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/rocksdb/table/block_based/block_like_traits.h182
1 files changed, 182 insertions, 0 deletions
diff --git a/src/rocksdb/table/block_based/block_like_traits.h b/src/rocksdb/table/block_based/block_like_traits.h
new file mode 100644
index 000000000..d406dbb5d
--- /dev/null
+++ b/src/rocksdb/table/block_based/block_like_traits.h
@@ -0,0 +1,182 @@
+// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
+// 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).
+
+#pragma once
+
+#include "cache/cache_entry_roles.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 {
+
+template <typename TBlocklike>
+class BlocklikeTraits;
+
+template <typename T, CacheEntryRole R>
+Cache::CacheItemHelper* GetCacheItemHelperForRole();
+
+template <typename TBlocklike>
+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<char[]> buf_data(new char[size]());
+ memcpy(buf_data.get(), buf, size);
+ BlockContents bc = BlockContents(std::move(buf_data), size);
+ TBlocklike* ucd_ptr = BlocklikeTraits<TBlocklike>::Create(
+ std::move(bc), read_amp_bytes_per_bit, statistics, using_zstd,
+ filter_policy);
+ *out_obj = reinterpret_cast<void*>(ucd_ptr);
+ *charge = size;
+ return Status::OK();
+ };
+}
+
+template <>
+class BlocklikeTraits<ParsedFullFilterBlock> {
+ public:
+ static ParsedFullFilterBlock* Create(BlockContents&& contents,
+ size_t /* read_amp_bytes_per_bit */,
+ Statistics* /* statistics */,
+ bool /* using_zstd */,
+ const FilterPolicy* filter_policy) {
+ return new ParsedFullFilterBlock(filter_policy, std::move(contents));
+ }
+
+ static uint32_t GetNumRestarts(const ParsedFullFilterBlock& /* block */) {
+ return 0;
+ }
+
+ static size_t SizeCallback(void* obj) {
+ assert(obj != nullptr);
+ ParsedFullFilterBlock* ptr = static_cast<ParsedFullFilterBlock*>(obj);
+ return ptr->GetBlockContentsData().size();
+ }
+
+ static Status SaveToCallback(void* from_obj, size_t from_offset,
+ size_t length, void* out) {
+ assert(from_obj != nullptr);
+ ParsedFullFilterBlock* ptr = static_cast<ParsedFullFilterBlock*>(from_obj);
+ const char* buf = ptr->GetBlockContentsData().data();
+ assert(length == ptr->GetBlockContentsData().size());
+ (void)from_offset;
+ memcpy(out, buf, length);
+ return Status::OK();
+ }
+
+ static Cache::CacheItemHelper* GetCacheItemHelper(BlockType block_type) {
+ (void)block_type;
+ assert(block_type == BlockType::kFilter);
+ return GetCacheItemHelperForRole<ParsedFullFilterBlock,
+ CacheEntryRole::kFilterBlock>();
+ }
+};
+
+template <>
+class BlocklikeTraits<Block> {
+ public:
+ static Block* Create(BlockContents&& contents, size_t read_amp_bytes_per_bit,
+ Statistics* statistics, bool /* using_zstd */,
+ const FilterPolicy* /* filter_policy */) {
+ return new Block(std::move(contents), read_amp_bytes_per_bit, statistics);
+ }
+
+ static uint32_t GetNumRestarts(const Block& block) {
+ return block.NumRestarts();
+ }
+
+ static size_t SizeCallback(void* obj) {
+ assert(obj != nullptr);
+ Block* ptr = static_cast<Block*>(obj);
+ return ptr->size();
+ }
+
+ static Status SaveToCallback(void* from_obj, size_t from_offset,
+ size_t length, void* out) {
+ assert(from_obj != nullptr);
+ Block* ptr = static_cast<Block*>(from_obj);
+ const char* buf = ptr->data();
+ assert(length == ptr->size());
+ (void)from_offset;
+ memcpy(out, buf, length);
+ return Status::OK();
+ }
+
+ static Cache::CacheItemHelper* GetCacheItemHelper(BlockType block_type) {
+ switch (block_type) {
+ case BlockType::kData:
+ return GetCacheItemHelperForRole<Block, CacheEntryRole::kDataBlock>();
+ case BlockType::kIndex:
+ return GetCacheItemHelperForRole<Block, CacheEntryRole::kIndexBlock>();
+ case BlockType::kFilterPartitionIndex:
+ return GetCacheItemHelperForRole<Block,
+ CacheEntryRole::kFilterMetaBlock>();
+ default:
+ // Not a recognized combination
+ assert(false);
+ FALLTHROUGH_INTENDED;
+ case BlockType::kRangeDeletion:
+ return GetCacheItemHelperForRole<Block, CacheEntryRole::kOtherBlock>();
+ }
+ }
+};
+
+template <>
+class BlocklikeTraits<UncompressionDict> {
+ public:
+ static UncompressionDict* Create(BlockContents&& contents,
+ size_t /* read_amp_bytes_per_bit */,
+ Statistics* /* statistics */,
+ bool using_zstd,
+ const FilterPolicy* /* filter_policy */) {
+ return new UncompressionDict(contents.data, std::move(contents.allocation),
+ using_zstd);
+ }
+
+ static uint32_t GetNumRestarts(const UncompressionDict& /* dict */) {
+ return 0;
+ }
+
+ static size_t SizeCallback(void* obj) {
+ assert(obj != nullptr);
+ UncompressionDict* ptr = static_cast<UncompressionDict*>(obj);
+ return ptr->slice_.size();
+ }
+
+ static Status SaveToCallback(void* from_obj, size_t from_offset,
+ size_t length, void* out) {
+ assert(from_obj != nullptr);
+ UncompressionDict* ptr = static_cast<UncompressionDict*>(from_obj);
+ const char* buf = ptr->slice_.data();
+ assert(length == ptr->slice_.size());
+ (void)from_offset;
+ memcpy(out, buf, length);
+ return Status::OK();
+ }
+
+ static Cache::CacheItemHelper* GetCacheItemHelper(BlockType block_type) {
+ (void)block_type;
+ assert(block_type == BlockType::kCompressionDictionary);
+ return GetCacheItemHelperForRole<UncompressionDict,
+ CacheEntryRole::kOtherBlock>();
+ }
+};
+
+// Get an CacheItemHelper pointer for value type T and role R.
+template <typename T, CacheEntryRole R>
+Cache::CacheItemHelper* GetCacheItemHelperForRole() {
+ static Cache::CacheItemHelper cache_helper(
+ BlocklikeTraits<T>::SizeCallback, BlocklikeTraits<T>::SaveToCallback,
+ GetCacheEntryDeleterForRole<T, R>());
+ return &cache_helper;
+}
+
+} // namespace ROCKSDB_NAMESPACE