]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/table/plain/plain_table_factory.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rocksdb / table / plain / plain_table_factory.cc
CommitLineData
f67539c2 1// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
7c673cae
FG
2// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file. See the AUTHORS file for names of contributors.
5
f67539c2 6#include "table/plain/plain_table_factory.h"
7c673cae 7
7c673cae 8#include <stdint.h>
20effc67 9
11fdf7f2 10#include <memory>
20effc67 11
7c673cae 12#include "db/dbformat.h"
11fdf7f2
TL
13#include "port/port.h"
14#include "rocksdb/convenience.h"
1e59de90
TL
15#include "rocksdb/utilities/customizable_util.h"
16#include "rocksdb/utilities/object_registry.h"
20effc67 17#include "rocksdb/utilities/options_type.h"
f67539c2
TL
18#include "table/plain/plain_table_builder.h"
19#include "table/plain/plain_table_reader.h"
11fdf7f2 20#include "util/string_util.h"
7c673cae 21
f67539c2 22namespace ROCKSDB_NAMESPACE {
1e59de90 23#ifndef ROCKSDB_LITE
20effc67
TL
24static std::unordered_map<std::string, OptionTypeInfo> plain_table_type_info = {
25 {"user_key_len",
26 {offsetof(struct PlainTableOptions, user_key_len), OptionType::kUInt32T,
27 OptionVerificationType::kNormal, OptionTypeFlags::kNone}},
28 {"bloom_bits_per_key",
29 {offsetof(struct PlainTableOptions, bloom_bits_per_key), OptionType::kInt,
30 OptionVerificationType::kNormal, OptionTypeFlags::kNone}},
31 {"hash_table_ratio",
32 {offsetof(struct PlainTableOptions, hash_table_ratio), OptionType::kDouble,
33 OptionVerificationType::kNormal, OptionTypeFlags::kNone}},
34 {"index_sparseness",
35 {offsetof(struct PlainTableOptions, index_sparseness), OptionType::kSizeT,
36 OptionVerificationType::kNormal, OptionTypeFlags::kNone}},
37 {"huge_page_tlb_size",
38 {offsetof(struct PlainTableOptions, huge_page_tlb_size),
39 OptionType::kSizeT, OptionVerificationType::kNormal,
40 OptionTypeFlags::kNone}},
41 {"encoding_type",
42 {offsetof(struct PlainTableOptions, encoding_type),
43 OptionType::kEncodingType, OptionVerificationType::kNormal,
44 OptionTypeFlags::kNone}},
45 {"full_scan_mode",
46 {offsetof(struct PlainTableOptions, full_scan_mode), OptionType::kBoolean,
47 OptionVerificationType::kNormal, OptionTypeFlags::kNone}},
48 {"store_index_in_file",
49 {offsetof(struct PlainTableOptions, store_index_in_file),
50 OptionType::kBoolean, OptionVerificationType::kNormal,
51 OptionTypeFlags::kNone}},
52};
53
54PlainTableFactory::PlainTableFactory(const PlainTableOptions& options)
55 : table_options_(options) {
1e59de90 56 RegisterOptions(&table_options_, &plain_table_type_info);
20effc67 57}
7c673cae
FG
58
59Status PlainTableFactory::NewTableReader(
20effc67 60 const ReadOptions& /*ro*/, const TableReaderOptions& table_reader_options,
494da23a
TL
61 std::unique_ptr<RandomAccessFileReader>&& file, uint64_t file_size,
62 std::unique_ptr<TableReader>* table,
11fdf7f2 63 bool /*prefetch_index_and_filter_in_cache*/) const {
7c673cae
FG
64 return PlainTableReader::Open(
65 table_reader_options.ioptions, table_reader_options.env_options,
66 table_reader_options.internal_comparator, std::move(file), file_size,
67 table, table_options_.bloom_bits_per_key, table_options_.hash_table_ratio,
68 table_options_.index_sparseness, table_options_.huge_page_tlb_size,
494da23a 69 table_options_.full_scan_mode, table_reader_options.immortal,
1e59de90 70 table_reader_options.prefix_extractor.get());
7c673cae
FG
71}
72
73TableBuilder* PlainTableFactory::NewTableBuilder(
1e59de90 74 const TableBuilderOptions& table_builder_options,
7c673cae
FG
75 WritableFileWriter* file) const {
76 // Ignore the skip_filters flag. PlainTable format is optimized for small
77 // in-memory dbs. The skip_filters optimization is not useful for plain
78 // tables
79 //
80 return new PlainTableBuilder(
11fdf7f2 81 table_builder_options.ioptions, table_builder_options.moptions,
1e59de90
TL
82 table_builder_options.int_tbl_prop_collector_factories,
83 table_builder_options.column_family_id,
84 table_builder_options.level_at_creation, file,
85 table_options_.user_key_len, table_options_.encoding_type,
7c673cae
FG
86 table_options_.index_sparseness, table_options_.bloom_bits_per_key,
87 table_builder_options.column_family_name, 6,
88 table_options_.huge_page_tlb_size, table_options_.hash_table_ratio,
20effc67 89 table_options_.store_index_in_file, table_builder_options.db_id,
1e59de90 90 table_builder_options.db_session_id, table_builder_options.cur_file_num);
7c673cae
FG
91}
92
20effc67 93std::string PlainTableFactory::GetPrintableOptions() const {
7c673cae
FG
94 std::string ret;
95 ret.reserve(20000);
96 const int kBufferSize = 200;
97 char buffer[kBufferSize];
98
99 snprintf(buffer, kBufferSize, " user_key_len: %u\n",
100 table_options_.user_key_len);
101 ret.append(buffer);
102 snprintf(buffer, kBufferSize, " bloom_bits_per_key: %d\n",
103 table_options_.bloom_bits_per_key);
104 ret.append(buffer);
105 snprintf(buffer, kBufferSize, " hash_table_ratio: %lf\n",
106 table_options_.hash_table_ratio);
107 ret.append(buffer);
108 snprintf(buffer, kBufferSize, " index_sparseness: %" ROCKSDB_PRIszt "\n",
109 table_options_.index_sparseness);
110 ret.append(buffer);
111 snprintf(buffer, kBufferSize, " huge_page_tlb_size: %" ROCKSDB_PRIszt "\n",
112 table_options_.huge_page_tlb_size);
113 ret.append(buffer);
114 snprintf(buffer, kBufferSize, " encoding_type: %d\n",
115 table_options_.encoding_type);
116 ret.append(buffer);
117 snprintf(buffer, kBufferSize, " full_scan_mode: %d\n",
118 table_options_.full_scan_mode);
119 ret.append(buffer);
120 snprintf(buffer, kBufferSize, " store_index_in_file: %d\n",
121 table_options_.store_index_in_file);
122 ret.append(buffer);
123 return ret;
124}
125
20effc67
TL
126Status GetPlainTableOptionsFromString(const PlainTableOptions& table_options,
127 const std::string& opts_str,
128 PlainTableOptions* new_table_options) {
129 ConfigOptions config_options;
130 config_options.input_strings_escaped = false;
131 config_options.ignore_unknown_options = false;
132 config_options.invoke_prepare_options = false;
133 return GetPlainTableOptionsFromString(config_options, table_options, opts_str,
134 new_table_options);
7c673cae
FG
135}
136
20effc67
TL
137Status GetPlainTableOptionsFromString(const ConfigOptions& config_options,
138 const PlainTableOptions& table_options,
11fdf7f2
TL
139 const std::string& opts_str,
140 PlainTableOptions* new_table_options) {
141 std::unordered_map<std::string, std::string> opts_map;
142 Status s = StringToMap(opts_str, &opts_map);
143 if (!s.ok()) {
144 return s;
145 }
20effc67
TL
146
147 s = GetPlainTableOptionsFromMap(config_options, table_options, opts_map,
148 new_table_options);
149 // Translate any errors (NotFound, NotSupported, to InvalidArgument
150 if (s.ok() || s.IsInvalidArgument()) {
151 return s;
152 } else {
153 return Status::InvalidArgument(s.getState());
154 }
11fdf7f2 155}
1e59de90 156#endif // ROCKSDB_LITE
11fdf7f2 157
1e59de90
TL
158#ifndef ROCKSDB_LITE
159static int RegisterBuiltinMemTableRepFactory(ObjectLibrary& library,
160 const std::string& /*arg*/) {
161 // The MemTableRepFactory built-in classes will be either a class
162 // (VectorRepFactory) or a nickname (vector), followed optionally by ":#",
163 // where # is the "size" of the factory.
164 auto AsPattern = [](const std::string& name, const std::string& alt) {
165 auto pattern = ObjectLibrary::PatternEntry(name, true);
166 pattern.AnotherName(alt);
167 pattern.AddNumber(":");
168 return pattern;
169 };
170 library.AddFactory<MemTableRepFactory>(
171 AsPattern(VectorRepFactory::kClassName(), VectorRepFactory::kNickName()),
172 [](const std::string& uri, std::unique_ptr<MemTableRepFactory>* guard,
173 std::string* /*errmsg*/) {
174 auto colon = uri.find(":");
175 if (colon != std::string::npos) {
176 size_t count = ParseSizeT(uri.substr(colon + 1));
177 guard->reset(new VectorRepFactory(count));
178 } else {
179 guard->reset(new VectorRepFactory());
180 }
181 return guard->get();
182 });
183 library.AddFactory<MemTableRepFactory>(
184 AsPattern(SkipListFactory::kClassName(), SkipListFactory::kNickName()),
185 [](const std::string& uri, std::unique_ptr<MemTableRepFactory>* guard,
186 std::string* /*errmsg*/) {
187 auto colon = uri.find(":");
188 if (colon != std::string::npos) {
189 size_t lookahead = ParseSizeT(uri.substr(colon + 1));
190 guard->reset(new SkipListFactory(lookahead));
191 } else {
192 guard->reset(new SkipListFactory());
193 }
194 return guard->get();
195 });
196 library.AddFactory<MemTableRepFactory>(
197 AsPattern("HashLinkListRepFactory", "hash_linkedlist"),
198 [](const std::string& uri, std::unique_ptr<MemTableRepFactory>* guard,
199 std::string* /*errmsg*/) {
200 // Expecting format: hash_linkedlist:<hash_bucket_count>
201 auto colon = uri.find(":");
202 if (colon != std::string::npos) {
203 size_t hash_bucket_count = ParseSizeT(uri.substr(colon + 1));
204 guard->reset(NewHashLinkListRepFactory(hash_bucket_count));
205 } else {
206 guard->reset(NewHashLinkListRepFactory());
207 }
208 return guard->get();
209 });
210 library.AddFactory<MemTableRepFactory>(
211 AsPattern("HashSkipListRepFactory", "prefix_hash"),
212 [](const std::string& uri, std::unique_ptr<MemTableRepFactory>* guard,
213 std::string* /*errmsg*/) {
214 // Expecting format: prefix_hash:<hash_bucket_count>
215 auto colon = uri.find(":");
216 if (colon != std::string::npos) {
217 size_t hash_bucket_count = ParseSizeT(uri.substr(colon + 1));
218 guard->reset(NewHashSkipListRepFactory(hash_bucket_count));
219 } else {
220 guard->reset(NewHashSkipListRepFactory());
221 }
222 return guard->get();
223 });
224 library.AddFactory<MemTableRepFactory>(
225 "cuckoo",
226 [](const std::string& /*uri*/,
227 std::unique_ptr<MemTableRepFactory>* /*guard*/, std::string* errmsg) {
228 *errmsg = "cuckoo hash memtable is not supported anymore.";
229 return nullptr;
230 });
11fdf7f2 231
1e59de90
TL
232 size_t num_types;
233 return static_cast<int>(library.GetFactoryCount(&num_types));
234}
235#endif // ROCKSDB_LITE
11fdf7f2 236
1e59de90
TL
237Status GetMemTableRepFactoryFromString(
238 const std::string& opts_str, std::unique_ptr<MemTableRepFactory>* result) {
239 ConfigOptions config_options;
240 config_options.ignore_unsupported_options = false;
241 config_options.ignore_unknown_options = false;
242 return MemTableRepFactory::CreateFromString(config_options, opts_str, result);
243}
11fdf7f2 244
1e59de90
TL
245Status MemTableRepFactory::CreateFromString(
246 const ConfigOptions& config_options, const std::string& value,
247 std::unique_ptr<MemTableRepFactory>* result) {
248#ifndef ROCKSDB_LITE
249 static std::once_flag once;
250 std::call_once(once, [&]() {
251 RegisterBuiltinMemTableRepFactory(*(ObjectLibrary::Default().get()), "");
252 });
253#endif // ROCKSDB_LITE
254 std::string id;
255 std::unordered_map<std::string, std::string> opt_map;
256 Status status = Customizable::GetOptionsMap(config_options, result->get(),
257 value, &id, &opt_map);
258 if (!status.ok()) { // GetOptionsMap failed
259 return status;
260 } else if (value.empty()) {
261 // No Id and no options. Clear the object
262 result->reset();
263 return Status::OK();
264 } else if (id.empty()) { // We have no Id but have options. Not good
265 return Status::NotSupported("Cannot reset object ", id);
11fdf7f2 266 } else {
1e59de90
TL
267#ifndef ROCKSDB_LITE
268 status = NewUniqueObject<MemTableRepFactory>(config_options, id, opt_map,
269 result);
270#else
271 // To make it possible to configure the memtables in LITE mode, the ID
272 // is of the form <name>:<size>, where name is the name of the class and
273 // <size> is the length of the object (e.g. skip_list:10).
274 std::vector<std::string> opts_list = StringSplit(id, ':');
275 if (opts_list.empty() || opts_list.size() > 2 || !opt_map.empty()) {
276 status = Status::InvalidArgument("Can't parse memtable_factory option ",
277 value);
278 } else if (opts_list[0] == SkipListFactory::kNickName() ||
279 opts_list[0] == SkipListFactory::kClassName()) {
280 // Expecting format
281 // skip_list:<lookahead>
282 if (opts_list.size() == 2) {
283 size_t lookahead = ParseSizeT(opts_list[1]);
284 result->reset(new SkipListFactory(lookahead));
285 } else {
286 result->reset(new SkipListFactory());
287 }
288 } else if (!config_options.ignore_unsupported_options) {
289 status = Status::NotSupported("Cannot load object in LITE mode ", id);
290 }
291#endif // ROCKSDB_LITE
11fdf7f2 292 }
1e59de90
TL
293 return status;
294}
11fdf7f2 295
1e59de90
TL
296Status MemTableRepFactory::CreateFromString(
297 const ConfigOptions& config_options, const std::string& value,
298 std::shared_ptr<MemTableRepFactory>* result) {
299 std::unique_ptr<MemTableRepFactory> factory;
300 Status s = CreateFromString(config_options, value, &factory);
301 if (factory && s.ok()) {
302 result->reset(factory.release());
11fdf7f2 303 }
1e59de90 304 return s;
11fdf7f2
TL
305}
306
1e59de90 307#ifndef ROCKSDB_LITE
11fdf7f2
TL
308Status GetPlainTableOptionsFromMap(
309 const PlainTableOptions& table_options,
310 const std::unordered_map<std::string, std::string>& opts_map,
311 PlainTableOptions* new_table_options, bool input_strings_escaped,
20effc67
TL
312 bool ignore_unknown_options) {
313 ConfigOptions config_options;
314 config_options.input_strings_escaped = input_strings_escaped;
315 config_options.ignore_unknown_options = ignore_unknown_options;
316 return GetPlainTableOptionsFromMap(config_options, table_options, opts_map,
317 new_table_options);
318}
319
320Status GetPlainTableOptionsFromMap(
321 const ConfigOptions& config_options, const PlainTableOptions& table_options,
322 const std::unordered_map<std::string, std::string>& opts_map,
323 PlainTableOptions* new_table_options) {
11fdf7f2 324 assert(new_table_options);
20effc67
TL
325 PlainTableFactory ptf(table_options);
326 Status s = ptf.ConfigureFromMap(config_options, opts_map);
327 if (s.ok()) {
328 *new_table_options = *(ptf.GetOptions<PlainTableOptions>());
329 } else {
330 // Restore "new_options" to the default "base_options".
331 *new_table_options = table_options;
11fdf7f2 332 }
20effc67 333 return s;
11fdf7f2
TL
334}
335
7c673cae
FG
336extern TableFactory* NewPlainTableFactory(const PlainTableOptions& options) {
337 return new PlainTableFactory(options);
338}
339
340const std::string PlainTablePropertyNames::kEncodingType =
341 "rocksdb.plain.table.encoding.type";
342
343const std::string PlainTablePropertyNames::kBloomVersion =
344 "rocksdb.plain.table.bloom.version";
345
346const std::string PlainTablePropertyNames::kNumBloomBlocks =
347 "rocksdb.plain.table.bloom.numblocks";
348
7c673cae 349#endif // ROCKSDB_LITE
1e59de90 350} // namespace ROCKSDB_NAMESPACE