]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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. | |
4 | ||
5 | #ifndef ROCKSDB_LITE | |
6 | #include "table/plain_table_factory.h" | |
7 | ||
7c673cae | 8 | #include <stdint.h> |
11fdf7f2 | 9 | #include <memory> |
7c673cae | 10 | #include "db/dbformat.h" |
11fdf7f2 TL |
11 | #include "options/options_helper.h" |
12 | #include "port/port.h" | |
13 | #include "rocksdb/convenience.h" | |
7c673cae FG |
14 | #include "table/plain_table_builder.h" |
15 | #include "table/plain_table_reader.h" | |
11fdf7f2 | 16 | #include "util/string_util.h" |
7c673cae FG |
17 | |
18 | namespace rocksdb { | |
19 | ||
20 | Status PlainTableFactory::NewTableReader( | |
21 | const TableReaderOptions& table_reader_options, | |
494da23a TL |
22 | std::unique_ptr<RandomAccessFileReader>&& file, uint64_t file_size, |
23 | std::unique_ptr<TableReader>* table, | |
11fdf7f2 | 24 | bool /*prefetch_index_and_filter_in_cache*/) const { |
7c673cae FG |
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, | |
494da23a TL |
30 | table_options_.full_scan_mode, table_reader_options.immortal, |
31 | table_reader_options.prefix_extractor); | |
7c673cae FG |
32 | } |
33 | ||
34 | TableBuilder* PlainTableFactory::NewTableBuilder( | |
35 | const TableBuilderOptions& table_builder_options, uint32_t column_family_id, | |
36 | WritableFileWriter* file) const { | |
37 | // Ignore the skip_filters flag. PlainTable format is optimized for small | |
38 | // in-memory dbs. The skip_filters optimization is not useful for plain | |
39 | // tables | |
40 | // | |
41 | return new PlainTableBuilder( | |
11fdf7f2 | 42 | table_builder_options.ioptions, table_builder_options.moptions, |
7c673cae FG |
43 | table_builder_options.int_tbl_prop_collector_factories, column_family_id, |
44 | file, table_options_.user_key_len, table_options_.encoding_type, | |
45 | table_options_.index_sparseness, table_options_.bloom_bits_per_key, | |
46 | table_builder_options.column_family_name, 6, | |
47 | table_options_.huge_page_tlb_size, table_options_.hash_table_ratio, | |
48 | table_options_.store_index_in_file); | |
49 | } | |
50 | ||
51 | std::string PlainTableFactory::GetPrintableTableOptions() const { | |
52 | std::string ret; | |
53 | ret.reserve(20000); | |
54 | const int kBufferSize = 200; | |
55 | char buffer[kBufferSize]; | |
56 | ||
57 | snprintf(buffer, kBufferSize, " user_key_len: %u\n", | |
58 | table_options_.user_key_len); | |
59 | ret.append(buffer); | |
60 | snprintf(buffer, kBufferSize, " bloom_bits_per_key: %d\n", | |
61 | table_options_.bloom_bits_per_key); | |
62 | ret.append(buffer); | |
63 | snprintf(buffer, kBufferSize, " hash_table_ratio: %lf\n", | |
64 | table_options_.hash_table_ratio); | |
65 | ret.append(buffer); | |
66 | snprintf(buffer, kBufferSize, " index_sparseness: %" ROCKSDB_PRIszt "\n", | |
67 | table_options_.index_sparseness); | |
68 | ret.append(buffer); | |
69 | snprintf(buffer, kBufferSize, " huge_page_tlb_size: %" ROCKSDB_PRIszt "\n", | |
70 | table_options_.huge_page_tlb_size); | |
71 | ret.append(buffer); | |
72 | snprintf(buffer, kBufferSize, " encoding_type: %d\n", | |
73 | table_options_.encoding_type); | |
74 | ret.append(buffer); | |
75 | snprintf(buffer, kBufferSize, " full_scan_mode: %d\n", | |
76 | table_options_.full_scan_mode); | |
77 | ret.append(buffer); | |
78 | snprintf(buffer, kBufferSize, " store_index_in_file: %d\n", | |
79 | table_options_.store_index_in_file); | |
80 | ret.append(buffer); | |
81 | return ret; | |
82 | } | |
83 | ||
84 | const PlainTableOptions& PlainTableFactory::table_options() const { | |
85 | return table_options_; | |
86 | } | |
87 | ||
11fdf7f2 TL |
88 | Status GetPlainTableOptionsFromString(const PlainTableOptions& table_options, |
89 | const std::string& opts_str, | |
90 | PlainTableOptions* new_table_options) { | |
91 | std::unordered_map<std::string, std::string> opts_map; | |
92 | Status s = StringToMap(opts_str, &opts_map); | |
93 | if (!s.ok()) { | |
94 | return s; | |
95 | } | |
96 | return GetPlainTableOptionsFromMap(table_options, opts_map, | |
97 | new_table_options); | |
98 | } | |
99 | ||
100 | Status GetMemTableRepFactoryFromString( | |
101 | const std::string& opts_str, | |
102 | std::unique_ptr<MemTableRepFactory>* new_mem_factory) { | |
103 | std::vector<std::string> opts_list = StringSplit(opts_str, ':'); | |
104 | size_t len = opts_list.size(); | |
105 | ||
106 | if (opts_list.empty() || opts_list.size() > 2) { | |
107 | return Status::InvalidArgument("Can't parse memtable_factory option ", | |
108 | opts_str); | |
109 | } | |
110 | ||
111 | MemTableRepFactory* mem_factory = nullptr; | |
112 | ||
113 | if (opts_list[0] == "skip_list") { | |
114 | // Expecting format | |
115 | // skip_list:<lookahead> | |
116 | if (2 == len) { | |
117 | size_t lookahead = ParseSizeT(opts_list[1]); | |
118 | mem_factory = new SkipListFactory(lookahead); | |
119 | } else if (1 == len) { | |
120 | mem_factory = new SkipListFactory(); | |
121 | } | |
122 | } else if (opts_list[0] == "prefix_hash") { | |
123 | // Expecting format | |
124 | // prfix_hash:<hash_bucket_count> | |
125 | if (2 == len) { | |
126 | size_t hash_bucket_count = ParseSizeT(opts_list[1]); | |
127 | mem_factory = NewHashSkipListRepFactory(hash_bucket_count); | |
128 | } else if (1 == len) { | |
129 | mem_factory = NewHashSkipListRepFactory(); | |
130 | } | |
131 | } else if (opts_list[0] == "hash_linkedlist") { | |
132 | // Expecting format | |
133 | // hash_linkedlist:<hash_bucket_count> | |
134 | if (2 == len) { | |
135 | size_t hash_bucket_count = ParseSizeT(opts_list[1]); | |
136 | mem_factory = NewHashLinkListRepFactory(hash_bucket_count); | |
137 | } else if (1 == len) { | |
138 | mem_factory = NewHashLinkListRepFactory(); | |
139 | } | |
140 | } else if (opts_list[0] == "vector") { | |
141 | // Expecting format | |
142 | // vector:<count> | |
143 | if (2 == len) { | |
144 | size_t count = ParseSizeT(opts_list[1]); | |
145 | mem_factory = new VectorRepFactory(count); | |
146 | } else if (1 == len) { | |
147 | mem_factory = new VectorRepFactory(); | |
148 | } | |
149 | } else if (opts_list[0] == "cuckoo") { | |
494da23a TL |
150 | return Status::NotSupported( |
151 | "cuckoo hash memtable is not supported anymore."); | |
11fdf7f2 TL |
152 | } else { |
153 | return Status::InvalidArgument("Unrecognized memtable_factory option ", | |
154 | opts_str); | |
155 | } | |
156 | ||
157 | if (mem_factory != nullptr) { | |
158 | new_mem_factory->reset(mem_factory); | |
159 | } | |
160 | ||
161 | return Status::OK(); | |
162 | } | |
163 | ||
164 | std::string ParsePlainTableOptions(const std::string& name, | |
165 | const std::string& org_value, | |
166 | PlainTableOptions* new_options, | |
167 | bool input_strings_escaped = false, | |
168 | bool ignore_unknown_options = false) { | |
169 | const std::string& value = | |
170 | input_strings_escaped ? UnescapeOptionString(org_value) : org_value; | |
171 | const auto iter = plain_table_type_info.find(name); | |
172 | if (iter == plain_table_type_info.end()) { | |
173 | if (ignore_unknown_options) { | |
174 | return ""; | |
175 | } else { | |
176 | return "Unrecognized option"; | |
177 | } | |
178 | } | |
179 | const auto& opt_info = iter->second; | |
180 | if (opt_info.verification != OptionVerificationType::kDeprecated && | |
181 | !ParseOptionHelper(reinterpret_cast<char*>(new_options) + opt_info.offset, | |
182 | opt_info.type, value)) { | |
183 | return "Invalid value"; | |
184 | } | |
185 | return ""; | |
186 | } | |
187 | ||
188 | Status GetPlainTableOptionsFromMap( | |
189 | const PlainTableOptions& table_options, | |
190 | const std::unordered_map<std::string, std::string>& opts_map, | |
191 | PlainTableOptions* new_table_options, bool input_strings_escaped, | |
192 | bool /*ignore_unknown_options*/) { | |
193 | assert(new_table_options); | |
194 | *new_table_options = table_options; | |
195 | for (const auto& o : opts_map) { | |
196 | auto error_message = ParsePlainTableOptions( | |
197 | o.first, o.second, new_table_options, input_strings_escaped); | |
198 | if (error_message != "") { | |
199 | const auto iter = plain_table_type_info.find(o.first); | |
200 | if (iter == plain_table_type_info.end() || | |
201 | !input_strings_escaped || // !input_strings_escaped indicates | |
202 | // the old API, where everything is | |
203 | // parsable. | |
204 | (iter->second.verification != OptionVerificationType::kByName && | |
205 | iter->second.verification != | |
206 | OptionVerificationType::kByNameAllowNull && | |
207 | iter->second.verification != | |
208 | OptionVerificationType::kByNameAllowFromNull && | |
209 | iter->second.verification != OptionVerificationType::kDeprecated)) { | |
210 | // Restore "new_options" to the default "base_options". | |
211 | *new_table_options = table_options; | |
212 | return Status::InvalidArgument("Can't parse PlainTableOptions:", | |
213 | o.first + " " + error_message); | |
214 | } | |
215 | } | |
216 | } | |
217 | return Status::OK(); | |
218 | } | |
219 | ||
7c673cae FG |
220 | extern TableFactory* NewPlainTableFactory(const PlainTableOptions& options) { |
221 | return new PlainTableFactory(options); | |
222 | } | |
223 | ||
224 | const std::string PlainTablePropertyNames::kEncodingType = | |
225 | "rocksdb.plain.table.encoding.type"; | |
226 | ||
227 | const std::string PlainTablePropertyNames::kBloomVersion = | |
228 | "rocksdb.plain.table.bloom.version"; | |
229 | ||
230 | const std::string PlainTablePropertyNames::kNumBloomBlocks = | |
231 | "rocksdb.plain.table.bloom.numblocks"; | |
232 | ||
233 | } // namespace rocksdb | |
234 | #endif // ROCKSDB_LITE |