1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. See the AUTHORS file for names of contributors.
6 #include "table/plain_table_factory.h"
10 #include "db/dbformat.h"
11 #include "options/options_helper.h"
12 #include "port/port.h"
13 #include "rocksdb/convenience.h"
14 #include "table/plain_table_builder.h"
15 #include "table/plain_table_reader.h"
16 #include "util/string_util.h"
20 Status
PlainTableFactory::NewTableReader(
21 const TableReaderOptions
& table_reader_options
,
22 unique_ptr
<RandomAccessFileReader
>&& file
, uint64_t file_size
,
23 unique_ptr
<TableReader
>* table
,
24 bool /*prefetch_index_and_filter_in_cache*/) const {
25 return PlainTableReader::Open(
26 table_reader_options
.ioptions
, table_reader_options
.env_options
,
27 table_reader_options
.internal_comparator
, std::move(file
), file_size
,
28 table
, table_options_
.bloom_bits_per_key
, table_options_
.hash_table_ratio
,
29 table_options_
.index_sparseness
, table_options_
.huge_page_tlb_size
,
30 table_options_
.full_scan_mode
, table_reader_options
.prefix_extractor
);
33 TableBuilder
* PlainTableFactory::NewTableBuilder(
34 const TableBuilderOptions
& table_builder_options
, uint32_t column_family_id
,
35 WritableFileWriter
* file
) const {
36 // Ignore the skip_filters flag. PlainTable format is optimized for small
37 // in-memory dbs. The skip_filters optimization is not useful for plain
40 return new PlainTableBuilder(
41 table_builder_options
.ioptions
, table_builder_options
.moptions
,
42 table_builder_options
.int_tbl_prop_collector_factories
, column_family_id
,
43 file
, table_options_
.user_key_len
, table_options_
.encoding_type
,
44 table_options_
.index_sparseness
, table_options_
.bloom_bits_per_key
,
45 table_builder_options
.column_family_name
, 6,
46 table_options_
.huge_page_tlb_size
, table_options_
.hash_table_ratio
,
47 table_options_
.store_index_in_file
);
50 std::string
PlainTableFactory::GetPrintableTableOptions() const {
53 const int kBufferSize
= 200;
54 char buffer
[kBufferSize
];
56 snprintf(buffer
, kBufferSize
, " user_key_len: %u\n",
57 table_options_
.user_key_len
);
59 snprintf(buffer
, kBufferSize
, " bloom_bits_per_key: %d\n",
60 table_options_
.bloom_bits_per_key
);
62 snprintf(buffer
, kBufferSize
, " hash_table_ratio: %lf\n",
63 table_options_
.hash_table_ratio
);
65 snprintf(buffer
, kBufferSize
, " index_sparseness: %" ROCKSDB_PRIszt
"\n",
66 table_options_
.index_sparseness
);
68 snprintf(buffer
, kBufferSize
, " huge_page_tlb_size: %" ROCKSDB_PRIszt
"\n",
69 table_options_
.huge_page_tlb_size
);
71 snprintf(buffer
, kBufferSize
, " encoding_type: %d\n",
72 table_options_
.encoding_type
);
74 snprintf(buffer
, kBufferSize
, " full_scan_mode: %d\n",
75 table_options_
.full_scan_mode
);
77 snprintf(buffer
, kBufferSize
, " store_index_in_file: %d\n",
78 table_options_
.store_index_in_file
);
83 const PlainTableOptions
& PlainTableFactory::table_options() const {
84 return table_options_
;
87 Status
GetPlainTableOptionsFromString(const PlainTableOptions
& table_options
,
88 const std::string
& opts_str
,
89 PlainTableOptions
* new_table_options
) {
90 std::unordered_map
<std::string
, std::string
> opts_map
;
91 Status s
= StringToMap(opts_str
, &opts_map
);
95 return GetPlainTableOptionsFromMap(table_options
, opts_map
,
99 Status
GetMemTableRepFactoryFromString(
100 const std::string
& opts_str
,
101 std::unique_ptr
<MemTableRepFactory
>* new_mem_factory
) {
102 std::vector
<std::string
> opts_list
= StringSplit(opts_str
, ':');
103 size_t len
= opts_list
.size();
105 if (opts_list
.empty() || opts_list
.size() > 2) {
106 return Status::InvalidArgument("Can't parse memtable_factory option ",
110 MemTableRepFactory
* mem_factory
= nullptr;
112 if (opts_list
[0] == "skip_list") {
114 // skip_list:<lookahead>
116 size_t lookahead
= ParseSizeT(opts_list
[1]);
117 mem_factory
= new SkipListFactory(lookahead
);
118 } else if (1 == len
) {
119 mem_factory
= new SkipListFactory();
121 } else if (opts_list
[0] == "prefix_hash") {
123 // prfix_hash:<hash_bucket_count>
125 size_t hash_bucket_count
= ParseSizeT(opts_list
[1]);
126 mem_factory
= NewHashSkipListRepFactory(hash_bucket_count
);
127 } else if (1 == len
) {
128 mem_factory
= NewHashSkipListRepFactory();
130 } else if (opts_list
[0] == "hash_linkedlist") {
132 // hash_linkedlist:<hash_bucket_count>
134 size_t hash_bucket_count
= ParseSizeT(opts_list
[1]);
135 mem_factory
= NewHashLinkListRepFactory(hash_bucket_count
);
136 } else if (1 == len
) {
137 mem_factory
= NewHashLinkListRepFactory();
139 } else if (opts_list
[0] == "vector") {
143 size_t count
= ParseSizeT(opts_list
[1]);
144 mem_factory
= new VectorRepFactory(count
);
145 } else if (1 == len
) {
146 mem_factory
= new VectorRepFactory();
148 } else if (opts_list
[0] == "cuckoo") {
150 // cuckoo:<write_buffer_size>
152 size_t write_buffer_size
= ParseSizeT(opts_list
[1]);
153 mem_factory
= NewHashCuckooRepFactory(write_buffer_size
);
154 } else if (1 == len
) {
155 return Status::InvalidArgument("Can't parse memtable_factory option ",
159 return Status::InvalidArgument("Unrecognized memtable_factory option ",
163 if (mem_factory
!= nullptr) {
164 new_mem_factory
->reset(mem_factory
);
170 std::string
ParsePlainTableOptions(const std::string
& name
,
171 const std::string
& org_value
,
172 PlainTableOptions
* new_options
,
173 bool input_strings_escaped
= false,
174 bool ignore_unknown_options
= false) {
175 const std::string
& value
=
176 input_strings_escaped
? UnescapeOptionString(org_value
) : org_value
;
177 const auto iter
= plain_table_type_info
.find(name
);
178 if (iter
== plain_table_type_info
.end()) {
179 if (ignore_unknown_options
) {
182 return "Unrecognized option";
185 const auto& opt_info
= iter
->second
;
186 if (opt_info
.verification
!= OptionVerificationType::kDeprecated
&&
187 !ParseOptionHelper(reinterpret_cast<char*>(new_options
) + opt_info
.offset
,
188 opt_info
.type
, value
)) {
189 return "Invalid value";
194 Status
GetPlainTableOptionsFromMap(
195 const PlainTableOptions
& table_options
,
196 const std::unordered_map
<std::string
, std::string
>& opts_map
,
197 PlainTableOptions
* new_table_options
, bool input_strings_escaped
,
198 bool /*ignore_unknown_options*/) {
199 assert(new_table_options
);
200 *new_table_options
= table_options
;
201 for (const auto& o
: opts_map
) {
202 auto error_message
= ParsePlainTableOptions(
203 o
.first
, o
.second
, new_table_options
, input_strings_escaped
);
204 if (error_message
!= "") {
205 const auto iter
= plain_table_type_info
.find(o
.first
);
206 if (iter
== plain_table_type_info
.end() ||
207 !input_strings_escaped
|| // !input_strings_escaped indicates
208 // the old API, where everything is
210 (iter
->second
.verification
!= OptionVerificationType::kByName
&&
211 iter
->second
.verification
!=
212 OptionVerificationType::kByNameAllowNull
&&
213 iter
->second
.verification
!=
214 OptionVerificationType::kByNameAllowFromNull
&&
215 iter
->second
.verification
!= OptionVerificationType::kDeprecated
)) {
216 // Restore "new_options" to the default "base_options".
217 *new_table_options
= table_options
;
218 return Status::InvalidArgument("Can't parse PlainTableOptions:",
219 o
.first
+ " " + error_message
);
226 extern TableFactory
* NewPlainTableFactory(const PlainTableOptions
& options
) {
227 return new PlainTableFactory(options
);
230 const std::string
PlainTablePropertyNames::kEncodingType
=
231 "rocksdb.plain.table.encoding.type";
233 const std::string
PlainTablePropertyNames::kBloomVersion
=
234 "rocksdb.plain.table.bloom.version";
236 const std::string
PlainTablePropertyNames::kNumBloomBlocks
=
237 "rocksdb.plain.table.bloom.numblocks";
239 } // namespace rocksdb
240 #endif // ROCKSDB_LITE