/Users/deen/code/yugabyte-db/src/yb/rocksdb/table/block_based_table_factory.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
2 | | // This source code is licensed under the BSD-style license found in the |
3 | | // LICENSE file in the root directory of this source tree. An additional grant |
4 | | // of patent rights can be found in the PATENTS file in the same directory. |
5 | | // |
6 | | // The following only applies to changes made to this file as part of YugaByte development. |
7 | | // |
8 | | // Portions Copyright (c) YugaByte, Inc. |
9 | | // |
10 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
11 | | // in compliance with the License. You may obtain a copy of the License at |
12 | | // |
13 | | // http://www.apache.org/licenses/LICENSE-2.0 |
14 | | // |
15 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
16 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
17 | | // or implied. See the License for the specific language governing permissions and limitations |
18 | | // under the License. |
19 | | // |
20 | | // Copyright (c) 2011 The LevelDB Authors. All rights reserved. |
21 | | // Use of this source code is governed by a BSD-style license that can be |
22 | | // found in the LICENSE file. See the AUTHORS file for names of contributors. |
23 | | |
24 | | #include "yb/rocksdb/table/block_based_table_factory.h" |
25 | | |
26 | | #include <stdint.h> |
27 | | |
28 | | #include <memory> |
29 | | #include <string> |
30 | | |
31 | | #include "yb/rocksdb/cache.h" |
32 | | #include "yb/rocksdb/filter_policy.h" |
33 | | #include "yb/rocksdb/flush_block_policy.h" |
34 | | #include "yb/rocksdb/port/port.h" |
35 | | #include "yb/rocksdb/table/block_based_table_builder.h" |
36 | | #include "yb/rocksdb/table/block_based_table_reader.h" |
37 | | #include "yb/rocksdb/table/format.h" |
38 | | |
39 | | namespace rocksdb { |
40 | | |
41 | | BlockBasedTableFactory::BlockBasedTableFactory( |
42 | | const BlockBasedTableOptions& _table_options) |
43 | 5.29M | : table_options_(_table_options) { |
44 | 5.29M | if (table_options_.flush_block_policy_factory == nullptr) { |
45 | 5.29M | table_options_.flush_block_policy_factory.reset( |
46 | 5.29M | new FlushBlockBySizePolicyFactory()); |
47 | 5.29M | } |
48 | 5.29M | if (table_options_.no_block_cache) { |
49 | 48.8k | table_options_.block_cache.reset(); |
50 | 5.24M | } else if (table_options_.block_cache == nullptr) { |
51 | 4.86M | table_options_.block_cache = NewLRUCache(8 << 20); |
52 | 4.86M | } |
53 | 5.29M | if (table_options_.block_size_deviation < 0 || |
54 | 5.29M | table_options_.block_size_deviation > 100) { |
55 | 4 | table_options_.block_size_deviation = 0; |
56 | 4 | } |
57 | 5.29M | if (table_options_.block_restart_interval < 1) { |
58 | 3 | table_options_.block_restart_interval = 1; |
59 | 3 | } |
60 | 5.29M | if (table_options_.index_block_restart_interval < 1) { |
61 | 6 | table_options_.index_block_restart_interval = 1; |
62 | 6 | } |
63 | 5.29M | } |
64 | | |
65 | | Status BlockBasedTableFactory::NewTableReader( |
66 | | const TableReaderOptions& table_reader_options, |
67 | | unique_ptr<RandomAccessFileReader>&& file, uint64_t file_size, |
68 | 72.6k | unique_ptr<TableReader>* table_reader) const { |
69 | 72.6k | return NewTableReader(table_reader_options, std::move(file), file_size, |
70 | 72.6k | table_reader, DataIndexLoadMode::LAZY, PrefetchFilter::YES); |
71 | 72.6k | } |
72 | | |
73 | | Status BlockBasedTableFactory::NewTableReader( |
74 | | const TableReaderOptions& table_reader_options, |
75 | | unique_ptr<RandomAccessFileReader>&& base_file, uint64_t base_file_size, |
76 | | unique_ptr<TableReader>* table_reader, DataIndexLoadMode prefetch_data_index, |
77 | 72.6k | PrefetchFilter prefetch_filter) const { |
78 | 72.6k | return BlockBasedTable::Open( |
79 | 72.6k | table_reader_options.ioptions, table_reader_options.env_options, |
80 | 72.6k | table_options_, table_reader_options.internal_comparator, std::move(base_file), |
81 | 72.6k | base_file_size, table_reader, prefetch_data_index, prefetch_filter, |
82 | 72.6k | table_reader_options.skip_filters); |
83 | 72.6k | } |
84 | | |
85 | | TableBuilder* BlockBasedTableFactory::NewTableBuilder( |
86 | | const TableBuilderOptions& table_builder_options, uint32_t column_family_id, |
87 | 61.4k | WritableFileWriter* base_file, WritableFileWriter* data_file) const { |
88 | | // base_file should be not nullptr, data_file should either point to different file writer |
89 | | // or be nullptr in order to produce single SST file containing both data and metadata. |
90 | 61.4k | assert(base_file); |
91 | 61.4k | assert(base_file != data_file); |
92 | 61.4k | auto table_builder = new BlockBasedTableBuilder( |
93 | 61.4k | table_builder_options.ioptions, table_options_, |
94 | 61.4k | table_builder_options.internal_comparator, |
95 | 61.4k | *table_builder_options.int_tbl_prop_collector_factories, |
96 | 61.4k | column_family_id, |
97 | 61.4k | base_file, |
98 | 61.4k | data_file, |
99 | 61.4k | table_builder_options.compression_type, |
100 | 61.4k | table_builder_options.compression_opts, |
101 | 61.4k | table_builder_options.skip_filters); |
102 | | |
103 | 61.4k | return table_builder; |
104 | 61.4k | } |
105 | | |
106 | | Status BlockBasedTableFactory::SanitizeOptions( |
107 | | const DBOptions& db_opts, |
108 | 343k | const ColumnFamilyOptions& cf_opts) const { |
109 | 343k | if (table_options_.index_type == IndexType::kHashSearch && |
110 | 569 | cf_opts.prefix_extractor == nullptr) { |
111 | 1 | return STATUS(InvalidArgument, "Hash index is specified for block-based " |
112 | 1 | "table, but prefix_extractor is not given"); |
113 | 1 | } |
114 | 343k | if (table_options_.cache_index_and_filter_blocks && |
115 | 328k | table_options_.no_block_cache) { |
116 | 0 | return STATUS(InvalidArgument, "Enable cache_index_and_filter_blocks, " |
117 | 0 | ", but block cache is disabled"); |
118 | 0 | } |
119 | 343k | if (!BlockBasedTableSupportedVersion(table_options_.format_version)) { |
120 | 0 | return STATUS(InvalidArgument, |
121 | 0 | "Unsupported BlockBasedTable format_version. Please check " |
122 | 0 | "include/rocksdb/table.h for more info"); |
123 | 0 | } |
124 | 343k | return Status::OK(); |
125 | 343k | } |
126 | | |
127 | 16.3k | std::string BlockBasedTableFactory::GetPrintableTableOptions() const { |
128 | 16.3k | std::string ret; |
129 | 16.3k | ret.reserve(20000); |
130 | 16.3k | const int kBufferSize = 200; |
131 | 16.3k | char buffer[kBufferSize]; |
132 | | |
133 | 16.3k | snprintf(buffer, kBufferSize, " flush_block_policy_factory: %s (%p)\n", |
134 | 16.3k | table_options_.flush_block_policy_factory->Name(), |
135 | 16.3k | table_options_.flush_block_policy_factory.get()); |
136 | 16.3k | ret.append(buffer); |
137 | 16.3k | snprintf(buffer, kBufferSize, " cache_index_and_filter_blocks: %d\n", |
138 | 16.3k | table_options_.cache_index_and_filter_blocks); |
139 | 16.3k | ret.append(buffer); |
140 | 16.3k | snprintf(buffer, kBufferSize, " index_type: %d\n", |
141 | 16.3k | yb::to_underlying(table_options_.index_type)); |
142 | 16.3k | ret.append(buffer); |
143 | 16.3k | snprintf(buffer, kBufferSize, " hash_index_allow_collision: %d\n", |
144 | 16.3k | table_options_.hash_index_allow_collision); |
145 | 16.3k | ret.append(buffer); |
146 | 16.3k | snprintf(buffer, kBufferSize, " checksum: %d\n", |
147 | 16.3k | table_options_.checksum); |
148 | 16.3k | ret.append(buffer); |
149 | 16.3k | snprintf(buffer, kBufferSize, " no_block_cache: %d\n", |
150 | 16.3k | table_options_.no_block_cache); |
151 | 16.3k | ret.append(buffer); |
152 | 16.3k | snprintf(buffer, kBufferSize, " block_cache: %p\n", |
153 | 16.3k | table_options_.block_cache.get()); |
154 | 16.3k | ret.append(buffer); |
155 | 16.3k | if (table_options_.block_cache) { |
156 | 16.3k | snprintf(buffer, kBufferSize, " block_cache_size: %" ROCKSDB_PRIszt "\n", |
157 | 16.3k | table_options_.block_cache->GetCapacity()); |
158 | 16.3k | ret.append(buffer); |
159 | 16.3k | } |
160 | 16.3k | snprintf(buffer, kBufferSize, " block_cache_compressed: %p\n", |
161 | 16.3k | table_options_.block_cache_compressed.get()); |
162 | 16.3k | ret.append(buffer); |
163 | 16.3k | if (table_options_.block_cache_compressed) { |
164 | 356 | snprintf(buffer, kBufferSize, |
165 | 356 | " block_cache_compressed_size: %" ROCKSDB_PRIszt "\n", |
166 | 356 | table_options_.block_cache_compressed->GetCapacity()); |
167 | 356 | ret.append(buffer); |
168 | 356 | } |
169 | 16.3k | snprintf(buffer, kBufferSize, " block_size: %" ROCKSDB_PRIszt "\n", |
170 | 16.3k | table_options_.block_size); |
171 | 16.3k | ret.append(buffer); |
172 | 16.3k | snprintf(buffer, kBufferSize, " block_size_deviation: %d\n", |
173 | 16.3k | table_options_.block_size_deviation); |
174 | 16.3k | ret.append(buffer); |
175 | 16.3k | snprintf(buffer, kBufferSize, " block_restart_interval: %d\n", |
176 | 16.3k | table_options_.block_restart_interval); |
177 | 16.3k | ret.append(buffer); |
178 | 16.3k | snprintf(buffer, kBufferSize, " index_block_restart_interval: %d\n", |
179 | 16.3k | table_options_.index_block_restart_interval); |
180 | 16.3k | ret.append(buffer); |
181 | 16.3k | snprintf(buffer, kBufferSize, " filter_policy: %s\n", |
182 | 16.3k | table_options_.filter_policy == nullptr ? |
183 | 15.4k | "nullptr" : table_options_.filter_policy->Name()); |
184 | 16.3k | ret.append(buffer); |
185 | 16.3k | snprintf(buffer, kBufferSize, " whole_key_filtering: %d\n", |
186 | 16.3k | table_options_.whole_key_filtering); |
187 | 16.3k | ret.append(buffer); |
188 | 16.3k | snprintf(buffer, kBufferSize, " skip_table_builder_flush: %d\n", |
189 | 16.3k | table_options_.skip_table_builder_flush); |
190 | 16.3k | ret.append(buffer); |
191 | 16.3k | snprintf(buffer, kBufferSize, " format_version: %d\n", |
192 | 16.3k | table_options_.format_version); |
193 | 16.3k | ret.append(buffer); |
194 | 16.3k | return ret; |
195 | 16.3k | } |
196 | | |
197 | 3.01M | const BlockBasedTableOptions& BlockBasedTableFactory::table_options() const { |
198 | 3.01M | return table_options_; |
199 | 3.01M | } |
200 | | std::shared_ptr<TableAwareReadFileFilter> BlockBasedTableFactory::NewTableAwareReadFileFilter( |
201 | 8.67M | const ReadOptions &read_options, const Slice &user_key) const { |
202 | 8.67M | return std::make_shared<BloomFilterAwareFileFilter>(read_options, user_key); |
203 | 8.67M | } |
204 | | |
205 | | TableFactory* NewBlockBasedTableFactory( |
206 | 435k | const BlockBasedTableOptions& _table_options) { |
207 | 435k | return new BlockBasedTableFactory(_table_options); |
208 | 435k | } |
209 | | |
210 | | const char BlockBasedTablePropertyNames::kIndexType[] = |
211 | | "rocksdb.block.based.table.index.type"; |
212 | | const char BlockBasedTablePropertyNames::kNumIndexLevels[] = |
213 | | "rocksdb.block.based.table.index.num.levels"; |
214 | | const char BlockBasedTablePropertyNames::kWholeKeyFiltering[] = |
215 | | "rocksdb.block.based.table.whole.key.filtering"; |
216 | | const char BlockBasedTablePropertyNames::kPrefixFiltering[] = |
217 | | "rocksdb.block.based.table.prefix.filtering"; |
218 | | const char BlockBasedTablePropertyNames::kDataBlockKeyValueEncodingFormat[] = |
219 | | "rocksdb.block.based.table.data.block.key.value.encoding.format"; |
220 | | const char kHashIndexPrefixesBlock[] = "rocksdb.hashindex.prefixes"; |
221 | | const char kHashIndexPrefixesMetadataBlock[] = |
222 | | "rocksdb.hashindex.metadata"; |
223 | | const char kPropTrue[] = "1"; |
224 | | const char kPropFalse[] = "0"; |
225 | | |
226 | | } // namespace rocksdb |