1 // Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
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.
7 #include "table/plain/plain_table_factory.h"
13 #include "db/dbformat.h"
14 #include "options/configurable_helper.h"
15 #include "port/port.h"
16 #include "rocksdb/convenience.h"
17 #include "rocksdb/utilities/options_type.h"
18 #include "table/plain/plain_table_builder.h"
19 #include "table/plain/plain_table_reader.h"
20 #include "util/string_util.h"
22 namespace ROCKSDB_NAMESPACE
{
23 static std::unordered_map
<std::string
, OptionTypeInfo
> plain_table_type_info
= {
25 {offsetof(struct PlainTableOptions
, user_key_len
), OptionType::kUInt32T
,
26 OptionVerificationType::kNormal
, OptionTypeFlags::kNone
}},
27 {"bloom_bits_per_key",
28 {offsetof(struct PlainTableOptions
, bloom_bits_per_key
), OptionType::kInt
,
29 OptionVerificationType::kNormal
, OptionTypeFlags::kNone
}},
31 {offsetof(struct PlainTableOptions
, hash_table_ratio
), OptionType::kDouble
,
32 OptionVerificationType::kNormal
, OptionTypeFlags::kNone
}},
34 {offsetof(struct PlainTableOptions
, index_sparseness
), OptionType::kSizeT
,
35 OptionVerificationType::kNormal
, OptionTypeFlags::kNone
}},
36 {"huge_page_tlb_size",
37 {offsetof(struct PlainTableOptions
, huge_page_tlb_size
),
38 OptionType::kSizeT
, OptionVerificationType::kNormal
,
39 OptionTypeFlags::kNone
}},
41 {offsetof(struct PlainTableOptions
, encoding_type
),
42 OptionType::kEncodingType
, OptionVerificationType::kNormal
,
43 OptionTypeFlags::kNone
}},
45 {offsetof(struct PlainTableOptions
, full_scan_mode
), OptionType::kBoolean
,
46 OptionVerificationType::kNormal
, OptionTypeFlags::kNone
}},
47 {"store_index_in_file",
48 {offsetof(struct PlainTableOptions
, store_index_in_file
),
49 OptionType::kBoolean
, OptionVerificationType::kNormal
,
50 OptionTypeFlags::kNone
}},
53 PlainTableFactory::PlainTableFactory(const PlainTableOptions
& options
)
54 : table_options_(options
) {
55 ConfigurableHelper::RegisterOptions(*this, &table_options_
,
56 &plain_table_type_info
);
59 Status
PlainTableFactory::NewTableReader(
60 const ReadOptions
& /*ro*/, const TableReaderOptions
& table_reader_options
,
61 std::unique_ptr
<RandomAccessFileReader
>&& file
, uint64_t file_size
,
62 std::unique_ptr
<TableReader
>* table
,
63 bool /*prefetch_index_and_filter_in_cache*/) const {
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
,
69 table_options_
.full_scan_mode
, table_reader_options
.immortal
,
70 table_reader_options
.prefix_extractor
);
73 TableBuilder
* PlainTableFactory::NewTableBuilder(
74 const TableBuilderOptions
& table_builder_options
, uint32_t column_family_id
,
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
80 return new PlainTableBuilder(
81 table_builder_options
.ioptions
, table_builder_options
.moptions
,
82 table_builder_options
.int_tbl_prop_collector_factories
, column_family_id
,
83 file
, table_options_
.user_key_len
, table_options_
.encoding_type
,
84 table_options_
.index_sparseness
, table_options_
.bloom_bits_per_key
,
85 table_builder_options
.column_family_name
, 6,
86 table_options_
.huge_page_tlb_size
, table_options_
.hash_table_ratio
,
87 table_options_
.store_index_in_file
, table_builder_options
.db_id
,
88 table_builder_options
.db_session_id
);
91 std::string
PlainTableFactory::GetPrintableOptions() const {
94 const int kBufferSize
= 200;
95 char buffer
[kBufferSize
];
97 snprintf(buffer
, kBufferSize
, " user_key_len: %u\n",
98 table_options_
.user_key_len
);
100 snprintf(buffer
, kBufferSize
, " bloom_bits_per_key: %d\n",
101 table_options_
.bloom_bits_per_key
);
103 snprintf(buffer
, kBufferSize
, " hash_table_ratio: %lf\n",
104 table_options_
.hash_table_ratio
);
106 snprintf(buffer
, kBufferSize
, " index_sparseness: %" ROCKSDB_PRIszt
"\n",
107 table_options_
.index_sparseness
);
109 snprintf(buffer
, kBufferSize
, " huge_page_tlb_size: %" ROCKSDB_PRIszt
"\n",
110 table_options_
.huge_page_tlb_size
);
112 snprintf(buffer
, kBufferSize
, " encoding_type: %d\n",
113 table_options_
.encoding_type
);
115 snprintf(buffer
, kBufferSize
, " full_scan_mode: %d\n",
116 table_options_
.full_scan_mode
);
118 snprintf(buffer
, kBufferSize
, " store_index_in_file: %d\n",
119 table_options_
.store_index_in_file
);
124 Status
GetPlainTableOptionsFromString(const PlainTableOptions
& table_options
,
125 const std::string
& opts_str
,
126 PlainTableOptions
* new_table_options
) {
127 ConfigOptions config_options
;
128 config_options
.input_strings_escaped
= false;
129 config_options
.ignore_unknown_options
= false;
130 config_options
.invoke_prepare_options
= false;
131 return GetPlainTableOptionsFromString(config_options
, table_options
, opts_str
,
135 Status
GetPlainTableOptionsFromString(const ConfigOptions
& config_options
,
136 const PlainTableOptions
& table_options
,
137 const std::string
& opts_str
,
138 PlainTableOptions
* new_table_options
) {
139 std::unordered_map
<std::string
, std::string
> opts_map
;
140 Status s
= StringToMap(opts_str
, &opts_map
);
145 s
= GetPlainTableOptionsFromMap(config_options
, table_options
, opts_map
,
147 // Translate any errors (NotFound, NotSupported, to InvalidArgument
148 if (s
.ok() || s
.IsInvalidArgument()) {
151 return Status::InvalidArgument(s
.getState());
155 Status
GetMemTableRepFactoryFromString(
156 const std::string
& opts_str
,
157 std::unique_ptr
<MemTableRepFactory
>* new_mem_factory
) {
158 std::vector
<std::string
> opts_list
= StringSplit(opts_str
, ':');
159 size_t len
= opts_list
.size();
161 if (opts_list
.empty() || opts_list
.size() > 2) {
162 return Status::InvalidArgument("Can't parse memtable_factory option ",
166 MemTableRepFactory
* mem_factory
= nullptr;
168 if (opts_list
[0] == "skip_list" || opts_list
[0] == "SkipListFactory") {
170 // skip_list:<lookahead>
172 size_t lookahead
= ParseSizeT(opts_list
[1]);
173 mem_factory
= new SkipListFactory(lookahead
);
174 } else if (1 == len
) {
175 mem_factory
= new SkipListFactory();
177 } else if (opts_list
[0] == "prefix_hash" ||
178 opts_list
[0] == "HashSkipListRepFactory") {
180 // prfix_hash:<hash_bucket_count>
182 size_t hash_bucket_count
= ParseSizeT(opts_list
[1]);
183 mem_factory
= NewHashSkipListRepFactory(hash_bucket_count
);
184 } else if (1 == len
) {
185 mem_factory
= NewHashSkipListRepFactory();
187 } else if (opts_list
[0] == "hash_linkedlist" ||
188 opts_list
[0] == "HashLinkListRepFactory") {
190 // hash_linkedlist:<hash_bucket_count>
192 size_t hash_bucket_count
= ParseSizeT(opts_list
[1]);
193 mem_factory
= NewHashLinkListRepFactory(hash_bucket_count
);
194 } else if (1 == len
) {
195 mem_factory
= NewHashLinkListRepFactory();
197 } else if (opts_list
[0] == "vector" || opts_list
[0] == "VectorRepFactory") {
201 size_t count
= ParseSizeT(opts_list
[1]);
202 mem_factory
= new VectorRepFactory(count
);
203 } else if (1 == len
) {
204 mem_factory
= new VectorRepFactory();
206 } else if (opts_list
[0] == "cuckoo") {
207 return Status::NotSupported(
208 "cuckoo hash memtable is not supported anymore.");
210 return Status::InvalidArgument("Unrecognized memtable_factory option ",
214 if (mem_factory
!= nullptr) {
215 new_mem_factory
->reset(mem_factory
);
221 Status
GetPlainTableOptionsFromMap(
222 const PlainTableOptions
& table_options
,
223 const std::unordered_map
<std::string
, std::string
>& opts_map
,
224 PlainTableOptions
* new_table_options
, bool input_strings_escaped
,
225 bool ignore_unknown_options
) {
226 ConfigOptions config_options
;
227 config_options
.input_strings_escaped
= input_strings_escaped
;
228 config_options
.ignore_unknown_options
= ignore_unknown_options
;
229 return GetPlainTableOptionsFromMap(config_options
, table_options
, opts_map
,
233 Status
GetPlainTableOptionsFromMap(
234 const ConfigOptions
& config_options
, const PlainTableOptions
& table_options
,
235 const std::unordered_map
<std::string
, std::string
>& opts_map
,
236 PlainTableOptions
* new_table_options
) {
237 assert(new_table_options
);
238 PlainTableFactory
ptf(table_options
);
239 Status s
= ptf
.ConfigureFromMap(config_options
, opts_map
);
241 *new_table_options
= *(ptf
.GetOptions
<PlainTableOptions
>());
243 // Restore "new_options" to the default "base_options".
244 *new_table_options
= table_options
;
249 extern TableFactory
* NewPlainTableFactory(const PlainTableOptions
& options
) {
250 return new PlainTableFactory(options
);
253 const std::string
PlainTablePropertyNames::kEncodingType
=
254 "rocksdb.plain.table.encoding.type";
256 const std::string
PlainTablePropertyNames::kBloomVersion
=
257 "rocksdb.plain.table.bloom.version";
259 const std::string
PlainTablePropertyNames::kNumBloomBlocks
=
260 "rocksdb.plain.table.bloom.numblocks";
262 } // namespace ROCKSDB_NAMESPACE
263 #endif // ROCKSDB_LITE