1 // Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
8 #include "cache/cache_entry_roles.h"
10 #include "table/block_based/block.h"
11 #include "table/block_based/block_type.h"
12 #include "table/block_based/parsed_full_filter_block.h"
13 #include "table/format.h"
15 namespace ROCKSDB_NAMESPACE
{
17 template <typename TBlocklike
>
18 class BlocklikeTraits
;
20 template <typename T
, CacheEntryRole R
>
21 Cache::CacheItemHelper
* GetCacheItemHelperForRole();
23 template <typename TBlocklike
>
24 Cache::CreateCallback
GetCreateCallback(size_t read_amp_bytes_per_bit
,
25 Statistics
* statistics
, bool using_zstd
,
26 const FilterPolicy
* filter_policy
) {
27 return [read_amp_bytes_per_bit
, statistics
, using_zstd
, filter_policy
](
28 const void* buf
, size_t size
, void** out_obj
,
29 size_t* charge
) -> Status
{
30 assert(buf
!= nullptr);
31 std::unique_ptr
<char[]> buf_data(new char[size
]());
32 memcpy(buf_data
.get(), buf
, size
);
33 BlockContents bc
= BlockContents(std::move(buf_data
), size
);
34 TBlocklike
* ucd_ptr
= BlocklikeTraits
<TBlocklike
>::Create(
35 std::move(bc
), read_amp_bytes_per_bit
, statistics
, using_zstd
,
37 *out_obj
= reinterpret_cast<void*>(ucd_ptr
);
44 class BlocklikeTraits
<ParsedFullFilterBlock
> {
46 static ParsedFullFilterBlock
* Create(BlockContents
&& contents
,
47 size_t /* read_amp_bytes_per_bit */,
48 Statistics
* /* statistics */,
49 bool /* using_zstd */,
50 const FilterPolicy
* filter_policy
) {
51 return new ParsedFullFilterBlock(filter_policy
, std::move(contents
));
54 static uint32_t GetNumRestarts(const ParsedFullFilterBlock
& /* block */) {
58 static size_t SizeCallback(void* obj
) {
59 assert(obj
!= nullptr);
60 ParsedFullFilterBlock
* ptr
= static_cast<ParsedFullFilterBlock
*>(obj
);
61 return ptr
->GetBlockContentsData().size();
64 static Status
SaveToCallback(void* from_obj
, size_t from_offset
,
65 size_t length
, void* out
) {
66 assert(from_obj
!= nullptr);
67 ParsedFullFilterBlock
* ptr
= static_cast<ParsedFullFilterBlock
*>(from_obj
);
68 const char* buf
= ptr
->GetBlockContentsData().data();
69 assert(length
== ptr
->GetBlockContentsData().size());
71 memcpy(out
, buf
, length
);
75 static Cache::CacheItemHelper
* GetCacheItemHelper(BlockType block_type
) {
77 assert(block_type
== BlockType::kFilter
);
78 return GetCacheItemHelperForRole
<ParsedFullFilterBlock
,
79 CacheEntryRole::kFilterBlock
>();
84 class BlocklikeTraits
<Block
> {
86 static Block
* Create(BlockContents
&& contents
, size_t read_amp_bytes_per_bit
,
87 Statistics
* statistics
, bool /* using_zstd */,
88 const FilterPolicy
* /* filter_policy */) {
89 return new Block(std::move(contents
), read_amp_bytes_per_bit
, statistics
);
92 static uint32_t GetNumRestarts(const Block
& block
) {
93 return block
.NumRestarts();
96 static size_t SizeCallback(void* obj
) {
97 assert(obj
!= nullptr);
98 Block
* ptr
= static_cast<Block
*>(obj
);
102 static Status
SaveToCallback(void* from_obj
, size_t from_offset
,
103 size_t length
, void* out
) {
104 assert(from_obj
!= nullptr);
105 Block
* ptr
= static_cast<Block
*>(from_obj
);
106 const char* buf
= ptr
->data();
107 assert(length
== ptr
->size());
109 memcpy(out
, buf
, length
);
113 static Cache::CacheItemHelper
* GetCacheItemHelper(BlockType block_type
) {
114 switch (block_type
) {
115 case BlockType::kData
:
116 return GetCacheItemHelperForRole
<Block
, CacheEntryRole::kDataBlock
>();
117 case BlockType::kIndex
:
118 return GetCacheItemHelperForRole
<Block
, CacheEntryRole::kIndexBlock
>();
119 case BlockType::kFilterPartitionIndex
:
120 return GetCacheItemHelperForRole
<Block
,
121 CacheEntryRole::kFilterMetaBlock
>();
123 // Not a recognized combination
125 FALLTHROUGH_INTENDED
;
126 case BlockType::kRangeDeletion
:
127 return GetCacheItemHelperForRole
<Block
, CacheEntryRole::kOtherBlock
>();
133 class BlocklikeTraits
<UncompressionDict
> {
135 static UncompressionDict
* Create(BlockContents
&& contents
,
136 size_t /* read_amp_bytes_per_bit */,
137 Statistics
* /* statistics */,
139 const FilterPolicy
* /* filter_policy */) {
140 return new UncompressionDict(contents
.data
, std::move(contents
.allocation
),
144 static uint32_t GetNumRestarts(const UncompressionDict
& /* dict */) {
148 static size_t SizeCallback(void* obj
) {
149 assert(obj
!= nullptr);
150 UncompressionDict
* ptr
= static_cast<UncompressionDict
*>(obj
);
151 return ptr
->slice_
.size();
154 static Status
SaveToCallback(void* from_obj
, size_t from_offset
,
155 size_t length
, void* out
) {
156 assert(from_obj
!= nullptr);
157 UncompressionDict
* ptr
= static_cast<UncompressionDict
*>(from_obj
);
158 const char* buf
= ptr
->slice_
.data();
159 assert(length
== ptr
->slice_
.size());
161 memcpy(out
, buf
, length
);
165 static Cache::CacheItemHelper
* GetCacheItemHelper(BlockType block_type
) {
167 assert(block_type
== BlockType::kCompressionDictionary
);
168 return GetCacheItemHelperForRole
<UncompressionDict
,
169 CacheEntryRole::kOtherBlock
>();
173 // Get an CacheItemHelper pointer for value type T and role R.
174 template <typename T
, CacheEntryRole R
>
175 Cache::CacheItemHelper
* GetCacheItemHelperForRole() {
176 static Cache::CacheItemHelper
cache_helper(
177 BlocklikeTraits
<T
>::SizeCallback
, BlocklikeTraits
<T
>::SaveToCallback
,
178 GetCacheEntryDeleterForRole
<T
, R
>());
179 return &cache_helper
;
182 } // namespace ROCKSDB_NAMESPACE