/src/rocksdb/options/options_helper.cc
Line | Count | Source |
1 | | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
2 | | // This source code is licensed under both the GPLv2 (found in the |
3 | | // COPYING file in the root directory) and Apache 2.0 License |
4 | | // (found in the LICENSE.Apache file in the root directory). |
5 | | #include "options/options_helper.h" |
6 | | |
7 | | #include <atomic> |
8 | | #include <cassert> |
9 | | #include <cctype> |
10 | | #include <cstdlib> |
11 | | #include <set> |
12 | | #include <unordered_set> |
13 | | #include <vector> |
14 | | |
15 | | #include "options/cf_options.h" |
16 | | #include "options/db_options.h" |
17 | | #include "rocksdb/cache.h" |
18 | | #include "rocksdb/compaction_filter.h" |
19 | | #include "rocksdb/convenience.h" |
20 | | #include "rocksdb/filter_policy.h" |
21 | | #include "rocksdb/flush_block_policy.h" |
22 | | #include "rocksdb/memtablerep.h" |
23 | | #include "rocksdb/merge_operator.h" |
24 | | #include "rocksdb/options.h" |
25 | | #include "rocksdb/rate_limiter.h" |
26 | | #include "rocksdb/slice_transform.h" |
27 | | #include "rocksdb/table.h" |
28 | | #include "rocksdb/utilities/object_registry.h" |
29 | | #include "rocksdb/utilities/options_type.h" |
30 | | #include "util/string_util.h" |
31 | | |
32 | | namespace ROCKSDB_NAMESPACE { |
33 | 107k | ConfigOptions::ConfigOptions() : registry(ObjectRegistry::NewInstance()) { |
34 | 107k | env = Env::Default(); |
35 | 107k | } |
36 | | |
37 | 0 | ConfigOptions::ConfigOptions(const DBOptions& db_opts) : env(db_opts.env) { |
38 | 0 | registry = ObjectRegistry::NewInstance(); |
39 | 0 | } |
40 | | |
41 | | Status ValidateOptions(const DBOptions& db_opts, |
42 | 28.5k | const ColumnFamilyOptions& cf_opts) { |
43 | 28.5k | Status s; |
44 | 28.5k | auto db_cfg = DBOptionsAsConfigurable(db_opts); |
45 | 28.5k | auto cf_cfg = CFOptionsAsConfigurable(cf_opts); |
46 | 28.5k | s = db_cfg->ValidateOptions(db_opts, cf_opts); |
47 | 28.5k | if (s.ok()) { |
48 | 28.5k | s = cf_cfg->ValidateOptions(db_opts, cf_opts); |
49 | 28.5k | } |
50 | 28.5k | return s; |
51 | 28.5k | } |
52 | | |
53 | | DBOptions BuildDBOptions(const ImmutableDBOptions& immutable_db_options, |
54 | 140k | const MutableDBOptions& mutable_db_options) { |
55 | 140k | DBOptions options; |
56 | 140k | BuildDBOptions(immutable_db_options, mutable_db_options, options); |
57 | 140k | return options; |
58 | 140k | } |
59 | | |
60 | | void BuildDBOptions(const ImmutableDBOptions& immutable_db_options, |
61 | | const MutableDBOptions& mutable_db_options, |
62 | 140k | DBOptions& options) { |
63 | 140k | options.create_if_missing = immutable_db_options.create_if_missing; |
64 | 140k | options.create_missing_column_families = |
65 | 140k | immutable_db_options.create_missing_column_families; |
66 | 140k | options.error_if_exists = immutable_db_options.error_if_exists; |
67 | 140k | options.paranoid_checks = immutable_db_options.paranoid_checks; |
68 | 140k | options.flush_verify_memtable_count = |
69 | 140k | immutable_db_options.flush_verify_memtable_count; |
70 | 140k | options.compaction_verify_record_count = |
71 | 140k | immutable_db_options.compaction_verify_record_count; |
72 | 140k | options.track_and_verify_wals_in_manifest = |
73 | 140k | immutable_db_options.track_and_verify_wals_in_manifest; |
74 | 140k | options.track_and_verify_wals = immutable_db_options.track_and_verify_wals; |
75 | 140k | options.verify_sst_unique_id_in_manifest = |
76 | 140k | immutable_db_options.verify_sst_unique_id_in_manifest; |
77 | 140k | options.env = immutable_db_options.env; |
78 | 140k | options.rate_limiter = immutable_db_options.rate_limiter; |
79 | 140k | options.sst_file_manager = immutable_db_options.sst_file_manager; |
80 | 140k | options.info_log = immutable_db_options.info_log; |
81 | 140k | options.info_log_level = immutable_db_options.info_log_level; |
82 | 140k | options.max_open_files = mutable_db_options.max_open_files; |
83 | 140k | options.max_file_opening_threads = |
84 | 140k | immutable_db_options.max_file_opening_threads; |
85 | 140k | options.max_total_wal_size = mutable_db_options.max_total_wal_size; |
86 | 140k | options.statistics = immutable_db_options.statistics; |
87 | 140k | options.use_fsync = immutable_db_options.use_fsync; |
88 | 140k | options.db_paths = immutable_db_options.db_paths; |
89 | 140k | options.db_log_dir = immutable_db_options.db_log_dir; |
90 | 140k | options.wal_dir = immutable_db_options.wal_dir; |
91 | 140k | options.delete_obsolete_files_period_micros = |
92 | 140k | mutable_db_options.delete_obsolete_files_period_micros; |
93 | 140k | options.max_background_jobs = mutable_db_options.max_background_jobs; |
94 | 140k | options.max_background_compactions = |
95 | 140k | mutable_db_options.max_background_compactions; |
96 | 140k | options.max_subcompactions = mutable_db_options.max_subcompactions; |
97 | 140k | options.max_background_flushes = mutable_db_options.max_background_flushes; |
98 | 140k | options.max_log_file_size = immutable_db_options.max_log_file_size; |
99 | 140k | options.log_file_time_to_roll = immutable_db_options.log_file_time_to_roll; |
100 | 140k | options.keep_log_file_num = immutable_db_options.keep_log_file_num; |
101 | 140k | options.recycle_log_file_num = immutable_db_options.recycle_log_file_num; |
102 | 140k | options.max_manifest_file_size = mutable_db_options.max_manifest_file_size; |
103 | 140k | options.max_manifest_space_amp_pct = |
104 | 140k | mutable_db_options.max_manifest_space_amp_pct; |
105 | 140k | options.table_cache_numshardbits = |
106 | 140k | immutable_db_options.table_cache_numshardbits; |
107 | 140k | options.WAL_ttl_seconds = immutable_db_options.WAL_ttl_seconds; |
108 | 140k | options.WAL_size_limit_MB = immutable_db_options.WAL_size_limit_MB; |
109 | 140k | options.manifest_preallocation_size = |
110 | 140k | mutable_db_options.manifest_preallocation_size; |
111 | 140k | options.allow_mmap_reads = immutable_db_options.allow_mmap_reads; |
112 | 140k | options.allow_mmap_writes = immutable_db_options.allow_mmap_writes; |
113 | 140k | options.use_direct_reads = immutable_db_options.use_direct_reads; |
114 | 140k | options.use_direct_io_for_flush_and_compaction = |
115 | 140k | immutable_db_options.use_direct_io_for_flush_and_compaction; |
116 | 140k | options.allow_fallocate = immutable_db_options.allow_fallocate; |
117 | 140k | options.is_fd_close_on_exec = immutable_db_options.is_fd_close_on_exec; |
118 | 140k | options.stats_dump_period_sec = mutable_db_options.stats_dump_period_sec; |
119 | 140k | options.stats_persist_period_sec = |
120 | 140k | mutable_db_options.stats_persist_period_sec; |
121 | 140k | options.persist_stats_to_disk = immutable_db_options.persist_stats_to_disk; |
122 | 140k | options.stats_history_buffer_size = |
123 | 140k | mutable_db_options.stats_history_buffer_size; |
124 | 140k | options.advise_random_on_open = immutable_db_options.advise_random_on_open; |
125 | 140k | options.db_write_buffer_size = immutable_db_options.db_write_buffer_size; |
126 | 140k | options.write_buffer_manager = immutable_db_options.write_buffer_manager; |
127 | 140k | options.compaction_readahead_size = |
128 | 140k | mutable_db_options.compaction_readahead_size; |
129 | 140k | options.writable_file_max_buffer_size = |
130 | 140k | mutable_db_options.writable_file_max_buffer_size; |
131 | 140k | options.use_adaptive_mutex = immutable_db_options.use_adaptive_mutex; |
132 | 140k | options.bytes_per_sync = mutable_db_options.bytes_per_sync; |
133 | 140k | options.wal_bytes_per_sync = mutable_db_options.wal_bytes_per_sync; |
134 | 140k | options.strict_bytes_per_sync = mutable_db_options.strict_bytes_per_sync; |
135 | 140k | options.listeners = immutable_db_options.listeners; |
136 | 140k | options.enable_thread_tracking = immutable_db_options.enable_thread_tracking; |
137 | 140k | options.delayed_write_rate = mutable_db_options.delayed_write_rate; |
138 | 140k | options.enable_pipelined_write = immutable_db_options.enable_pipelined_write; |
139 | 140k | options.unordered_write = immutable_db_options.unordered_write; |
140 | 140k | options.allow_concurrent_memtable_write = |
141 | 140k | immutable_db_options.allow_concurrent_memtable_write; |
142 | 140k | options.enable_write_thread_adaptive_yield = |
143 | 140k | immutable_db_options.enable_write_thread_adaptive_yield; |
144 | 140k | options.max_write_batch_group_size_bytes = |
145 | 140k | immutable_db_options.max_write_batch_group_size_bytes; |
146 | 140k | options.write_thread_max_yield_usec = |
147 | 140k | immutable_db_options.write_thread_max_yield_usec; |
148 | 140k | options.write_thread_slow_yield_usec = |
149 | 140k | immutable_db_options.write_thread_slow_yield_usec; |
150 | 140k | options.skip_stats_update_on_db_open = |
151 | 140k | immutable_db_options.skip_stats_update_on_db_open; |
152 | 140k | options.skip_checking_sst_file_sizes_on_db_open = |
153 | 140k | immutable_db_options.skip_checking_sst_file_sizes_on_db_open; |
154 | 140k | options.wal_recovery_mode = immutable_db_options.wal_recovery_mode; |
155 | 140k | options.allow_2pc = immutable_db_options.allow_2pc; |
156 | 140k | options.row_cache = immutable_db_options.row_cache; |
157 | 140k | options.wal_filter = immutable_db_options.wal_filter; |
158 | 140k | options.dump_malloc_stats = immutable_db_options.dump_malloc_stats; |
159 | 140k | options.avoid_flush_during_recovery = |
160 | 140k | immutable_db_options.avoid_flush_during_recovery; |
161 | 140k | options.avoid_flush_during_shutdown = |
162 | 140k | mutable_db_options.avoid_flush_during_shutdown; |
163 | 140k | options.allow_ingest_behind = immutable_db_options.allow_ingest_behind; |
164 | 140k | options.two_write_queues = immutable_db_options.two_write_queues; |
165 | 140k | options.manual_wal_flush = immutable_db_options.manual_wal_flush; |
166 | 140k | options.wal_compression = immutable_db_options.wal_compression; |
167 | 140k | options.background_close_inactive_wals = |
168 | 140k | immutable_db_options.background_close_inactive_wals; |
169 | 140k | options.atomic_flush = immutable_db_options.atomic_flush; |
170 | 140k | options.avoid_unnecessary_blocking_io = |
171 | 140k | immutable_db_options.avoid_unnecessary_blocking_io; |
172 | 140k | options.write_dbid_to_manifest = immutable_db_options.write_dbid_to_manifest; |
173 | 140k | options.write_identity_file = immutable_db_options.write_identity_file; |
174 | 140k | options.prefix_seek_opt_in_only = |
175 | 140k | immutable_db_options.prefix_seek_opt_in_only; |
176 | 140k | options.log_readahead_size = immutable_db_options.log_readahead_size; |
177 | 140k | options.file_checksum_gen_factory = |
178 | 140k | immutable_db_options.file_checksum_gen_factory; |
179 | 140k | options.best_efforts_recovery = immutable_db_options.best_efforts_recovery; |
180 | 140k | options.max_bgerror_resume_count = |
181 | 140k | immutable_db_options.max_bgerror_resume_count; |
182 | 140k | options.bgerror_resume_retry_interval = |
183 | 140k | immutable_db_options.bgerror_resume_retry_interval; |
184 | 140k | options.db_host_id = immutable_db_options.db_host_id; |
185 | 140k | options.allow_data_in_errors = immutable_db_options.allow_data_in_errors; |
186 | 140k | options.checksum_handoff_file_types = |
187 | 140k | immutable_db_options.checksum_handoff_file_types; |
188 | 140k | options.lowest_used_cache_tier = immutable_db_options.lowest_used_cache_tier; |
189 | 140k | options.enforce_single_del_contracts = |
190 | 140k | immutable_db_options.enforce_single_del_contracts; |
191 | 140k | options.daily_offpeak_time_utc = mutable_db_options.daily_offpeak_time_utc; |
192 | 140k | options.follower_refresh_catchup_period_ms = |
193 | 140k | immutable_db_options.follower_refresh_catchup_period_ms; |
194 | 140k | options.follower_catchup_retry_count = |
195 | 140k | immutable_db_options.follower_catchup_retry_count; |
196 | 140k | options.follower_catchup_retry_wait_ms = |
197 | 140k | immutable_db_options.follower_catchup_retry_wait_ms; |
198 | 140k | options.metadata_write_temperature = |
199 | 140k | immutable_db_options.metadata_write_temperature; |
200 | 140k | options.wal_write_temperature = immutable_db_options.wal_write_temperature; |
201 | 140k | options.compaction_service = immutable_db_options.compaction_service; |
202 | 140k | options.calculate_sst_write_lifetime_hint_set = |
203 | 140k | immutable_db_options.calculate_sst_write_lifetime_hint_set; |
204 | 140k | } |
205 | | |
206 | | ColumnFamilyOptions BuildColumnFamilyOptions( |
207 | | const ColumnFamilyOptions& options, |
208 | 92.3k | const MutableCFOptions& mutable_cf_options) { |
209 | 92.3k | ColumnFamilyOptions cf_opts(options); |
210 | 92.3k | UpdateColumnFamilyOptions(mutable_cf_options, &cf_opts); |
211 | | // TODO(yhchiang): find some way to handle the following derived options |
212 | | // * max_file_size |
213 | 92.3k | return cf_opts; |
214 | 92.3k | } |
215 | | |
216 | | void UpdateColumnFamilyOptions(const MutableCFOptions& moptions, |
217 | 147k | ColumnFamilyOptions* cf_opts) { |
218 | | // Memtable related options |
219 | 147k | cf_opts->write_buffer_size = moptions.write_buffer_size; |
220 | 147k | cf_opts->max_write_buffer_number = moptions.max_write_buffer_number; |
221 | 147k | cf_opts->arena_block_size = moptions.arena_block_size; |
222 | 147k | cf_opts->memtable_prefix_bloom_size_ratio = |
223 | 147k | moptions.memtable_prefix_bloom_size_ratio; |
224 | 147k | cf_opts->memtable_whole_key_filtering = moptions.memtable_whole_key_filtering; |
225 | 147k | cf_opts->memtable_huge_page_size = moptions.memtable_huge_page_size; |
226 | 147k | cf_opts->max_successive_merges = moptions.max_successive_merges; |
227 | 147k | cf_opts->strict_max_successive_merges = moptions.strict_max_successive_merges; |
228 | 147k | cf_opts->inplace_update_num_locks = moptions.inplace_update_num_locks; |
229 | 147k | cf_opts->prefix_extractor = moptions.prefix_extractor; |
230 | 147k | cf_opts->experimental_mempurge_threshold = |
231 | 147k | moptions.experimental_mempurge_threshold; |
232 | 147k | cf_opts->memtable_protection_bytes_per_key = |
233 | 147k | moptions.memtable_protection_bytes_per_key; |
234 | 147k | cf_opts->block_protection_bytes_per_key = |
235 | 147k | moptions.block_protection_bytes_per_key; |
236 | 147k | cf_opts->paranoid_memory_checks = moptions.paranoid_memory_checks; |
237 | 147k | cf_opts->memtable_veirfy_per_key_checksum_on_seek = |
238 | 147k | moptions.memtable_veirfy_per_key_checksum_on_seek; |
239 | 147k | cf_opts->bottommost_file_compaction_delay = |
240 | 147k | moptions.bottommost_file_compaction_delay; |
241 | | |
242 | | // Compaction related options |
243 | 147k | cf_opts->disable_auto_compactions = moptions.disable_auto_compactions; |
244 | 147k | cf_opts->table_factory = moptions.table_factory; |
245 | 147k | cf_opts->soft_pending_compaction_bytes_limit = |
246 | 147k | moptions.soft_pending_compaction_bytes_limit; |
247 | 147k | cf_opts->hard_pending_compaction_bytes_limit = |
248 | 147k | moptions.hard_pending_compaction_bytes_limit; |
249 | 147k | cf_opts->level0_file_num_compaction_trigger = |
250 | 147k | moptions.level0_file_num_compaction_trigger; |
251 | 147k | cf_opts->level0_slowdown_writes_trigger = |
252 | 147k | moptions.level0_slowdown_writes_trigger; |
253 | 147k | cf_opts->level0_stop_writes_trigger = moptions.level0_stop_writes_trigger; |
254 | 147k | cf_opts->max_compaction_bytes = moptions.max_compaction_bytes; |
255 | 147k | cf_opts->target_file_size_base = moptions.target_file_size_base; |
256 | 147k | cf_opts->target_file_size_multiplier = moptions.target_file_size_multiplier; |
257 | 147k | cf_opts->target_file_size_is_upper_bound = |
258 | 147k | moptions.target_file_size_is_upper_bound; |
259 | 147k | cf_opts->max_bytes_for_level_base = moptions.max_bytes_for_level_base; |
260 | 147k | cf_opts->max_bytes_for_level_multiplier = |
261 | 147k | moptions.max_bytes_for_level_multiplier; |
262 | 147k | cf_opts->ttl = moptions.ttl; |
263 | 147k | cf_opts->periodic_compaction_seconds = moptions.periodic_compaction_seconds; |
264 | 147k | cf_opts->preclude_last_level_data_seconds = |
265 | 147k | moptions.preclude_last_level_data_seconds; |
266 | 147k | cf_opts->preserve_internal_time_seconds = |
267 | 147k | moptions.preserve_internal_time_seconds; |
268 | | |
269 | 147k | cf_opts->max_bytes_for_level_multiplier_additional.clear(); |
270 | 1.03M | for (auto value : moptions.max_bytes_for_level_multiplier_additional) { |
271 | 1.03M | cf_opts->max_bytes_for_level_multiplier_additional.emplace_back(value); |
272 | 1.03M | } |
273 | | |
274 | 147k | cf_opts->compaction_options_fifo = moptions.compaction_options_fifo; |
275 | 147k | cf_opts->compaction_options_universal = moptions.compaction_options_universal; |
276 | | |
277 | 147k | cf_opts->verify_output_flags = moptions.verify_output_flags; |
278 | | |
279 | | // Blob file related options |
280 | 147k | cf_opts->enable_blob_files = moptions.enable_blob_files; |
281 | 147k | cf_opts->min_blob_size = moptions.min_blob_size; |
282 | 147k | cf_opts->blob_file_size = moptions.blob_file_size; |
283 | 147k | cf_opts->blob_compression_type = moptions.blob_compression_type; |
284 | 147k | cf_opts->enable_blob_garbage_collection = |
285 | 147k | moptions.enable_blob_garbage_collection; |
286 | 147k | cf_opts->blob_garbage_collection_age_cutoff = |
287 | 147k | moptions.blob_garbage_collection_age_cutoff; |
288 | 147k | cf_opts->blob_garbage_collection_force_threshold = |
289 | 147k | moptions.blob_garbage_collection_force_threshold; |
290 | 147k | cf_opts->blob_compaction_readahead_size = |
291 | 147k | moptions.blob_compaction_readahead_size; |
292 | 147k | cf_opts->blob_file_starting_level = moptions.blob_file_starting_level; |
293 | 147k | cf_opts->prepopulate_blob_cache = moptions.prepopulate_blob_cache; |
294 | | |
295 | | // Misc options |
296 | 147k | cf_opts->max_sequential_skip_in_iterations = |
297 | 147k | moptions.max_sequential_skip_in_iterations; |
298 | 147k | cf_opts->paranoid_file_checks = moptions.paranoid_file_checks; |
299 | 147k | cf_opts->report_bg_io_stats = moptions.report_bg_io_stats; |
300 | 147k | cf_opts->compression = moptions.compression; |
301 | 147k | cf_opts->compression_opts = moptions.compression_opts; |
302 | 147k | cf_opts->bottommost_compression = moptions.bottommost_compression; |
303 | 147k | cf_opts->bottommost_compression_opts = moptions.bottommost_compression_opts; |
304 | 147k | cf_opts->compression_manager = moptions.compression_manager; |
305 | 147k | cf_opts->sample_for_compression = moptions.sample_for_compression; |
306 | 147k | cf_opts->compression_per_level = moptions.compression_per_level; |
307 | 147k | cf_opts->last_level_temperature = moptions.last_level_temperature; |
308 | 147k | cf_opts->default_write_temperature = moptions.default_write_temperature; |
309 | 147k | cf_opts->memtable_max_range_deletions = moptions.memtable_max_range_deletions; |
310 | 147k | cf_opts->uncache_aggressiveness = moptions.uncache_aggressiveness; |
311 | 147k | cf_opts->memtable_op_scan_flush_trigger = |
312 | 147k | moptions.memtable_op_scan_flush_trigger; |
313 | 147k | cf_opts->memtable_avg_op_scan_flush_trigger = |
314 | 147k | moptions.memtable_avg_op_scan_flush_trigger; |
315 | 147k | } |
316 | | |
317 | | void UpdateColumnFamilyOptions(const ImmutableCFOptions& ioptions, |
318 | 55.0k | ColumnFamilyOptions* cf_opts) { |
319 | 55.0k | cf_opts->compaction_style = ioptions.compaction_style; |
320 | 55.0k | cf_opts->compaction_pri = ioptions.compaction_pri; |
321 | 55.0k | cf_opts->comparator = ioptions.user_comparator; |
322 | 55.0k | cf_opts->merge_operator = ioptions.merge_operator; |
323 | 55.0k | cf_opts->compaction_filter = ioptions.compaction_filter; |
324 | 55.0k | cf_opts->compaction_filter_factory = ioptions.compaction_filter_factory; |
325 | 55.0k | cf_opts->min_write_buffer_number_to_merge = |
326 | 55.0k | ioptions.min_write_buffer_number_to_merge; |
327 | 55.0k | cf_opts->max_write_buffer_size_to_maintain = |
328 | 55.0k | ioptions.max_write_buffer_size_to_maintain; |
329 | 55.0k | cf_opts->inplace_update_support = ioptions.inplace_update_support; |
330 | 55.0k | cf_opts->inplace_callback = ioptions.inplace_callback; |
331 | 55.0k | cf_opts->memtable_factory = ioptions.memtable_factory; |
332 | 55.0k | cf_opts->table_properties_collector_factories = |
333 | 55.0k | ioptions.table_properties_collector_factories; |
334 | 55.0k | cf_opts->bloom_locality = ioptions.bloom_locality; |
335 | 55.0k | cf_opts->level_compaction_dynamic_level_bytes = |
336 | 55.0k | ioptions.level_compaction_dynamic_level_bytes; |
337 | 55.0k | cf_opts->num_levels = ioptions.num_levels; |
338 | 55.0k | cf_opts->optimize_filters_for_hits = ioptions.optimize_filters_for_hits; |
339 | 55.0k | cf_opts->force_consistency_checks = ioptions.force_consistency_checks; |
340 | 55.0k | cf_opts->disallow_memtable_writes = ioptions.disallow_memtable_writes; |
341 | 55.0k | cf_opts->memtable_insert_with_hint_prefix_extractor = |
342 | 55.0k | ioptions.memtable_insert_with_hint_prefix_extractor; |
343 | 55.0k | cf_opts->cf_paths = ioptions.cf_paths; |
344 | 55.0k | cf_opts->compaction_thread_limiter = ioptions.compaction_thread_limiter; |
345 | 55.0k | cf_opts->sst_partitioner_factory = ioptions.sst_partitioner_factory; |
346 | 55.0k | cf_opts->blob_cache = ioptions.blob_cache; |
347 | 55.0k | cf_opts->persist_user_defined_timestamps = |
348 | 55.0k | ioptions.persist_user_defined_timestamps; |
349 | 55.0k | cf_opts->default_temperature = ioptions.default_temperature; |
350 | 55.0k | cf_opts->cf_allow_ingest_behind = ioptions.cf_allow_ingest_behind; |
351 | | |
352 | | // TODO(yhchiang): find some way to handle the following derived options |
353 | | // * max_file_size |
354 | 55.0k | } |
355 | | |
356 | | std::map<CompactionStyle, std::string> |
357 | | OptionsHelper::compaction_style_to_string = { |
358 | | {kCompactionStyleLevel, "kCompactionStyleLevel"}, |
359 | | {kCompactionStyleUniversal, "kCompactionStyleUniversal"}, |
360 | | {kCompactionStyleFIFO, "kCompactionStyleFIFO"}, |
361 | | {kCompactionStyleNone, "kCompactionStyleNone"}}; |
362 | | |
363 | | std::map<CompactionPri, std::string> OptionsHelper::compaction_pri_to_string = { |
364 | | {kByCompensatedSize, "kByCompensatedSize"}, |
365 | | {kOldestLargestSeqFirst, "kOldestLargestSeqFirst"}, |
366 | | {kOldestSmallestSeqFirst, "kOldestSmallestSeqFirst"}, |
367 | | {kMinOverlappingRatio, "kMinOverlappingRatio"}, |
368 | | {kRoundRobin, "kRoundRobin"}}; |
369 | | |
370 | | std::map<CompactionStopStyle, std::string> |
371 | | OptionsHelper::compaction_stop_style_to_string = { |
372 | | {kCompactionStopStyleSimilarSize, "kCompactionStopStyleSimilarSize"}, |
373 | | {kCompactionStopStyleTotalSize, "kCompactionStopStyleTotalSize"}}; |
374 | | |
375 | | std::map<Temperature, std::string> OptionsHelper::temperature_to_string = { |
376 | | {Temperature::kUnknown, "kUnknown"}, {Temperature::kHot, "kHot"}, |
377 | | {Temperature::kWarm, "kWarm"}, {Temperature::kCool, "kCool"}, |
378 | | {Temperature::kCold, "kCold"}, {Temperature::kIce, "kIce"}}; |
379 | | |
380 | | std::unordered_map<std::string, ChecksumType> |
381 | | OptionsHelper::checksum_type_string_map = {{"kNoChecksum", kNoChecksum}, |
382 | | {"kCRC32c", kCRC32c}, |
383 | | {"kxxHash", kxxHash}, |
384 | | {"kxxHash64", kxxHash64}, |
385 | | {"kXXH3", kXXH3}}; |
386 | | |
387 | | std::unordered_map<std::string, CompressionType> |
388 | | OptionsHelper::compression_type_string_map = { |
389 | | {"kNoCompression", kNoCompression}, |
390 | | {"kSnappyCompression", kSnappyCompression}, |
391 | | {"kZlibCompression", kZlibCompression}, |
392 | | {"kBZip2Compression", kBZip2Compression}, |
393 | | {"kLZ4Compression", kLZ4Compression}, |
394 | | {"kLZ4HCCompression", kLZ4HCCompression}, |
395 | | {"kXpressCompression", kXpressCompression}, |
396 | | {"kZSTD", kZSTD}, |
397 | | {"kCustomCompression80", kCustomCompression80}, |
398 | | {"kCustomCompression81", kCustomCompression81}, |
399 | | {"kCustomCompression82", kCustomCompression82}, |
400 | | {"kCustomCompression83", kCustomCompression83}, |
401 | | {"kCustomCompression84", kCustomCompression84}, |
402 | | {"kCustomCompression85", kCustomCompression85}, |
403 | | {"kCustomCompression86", kCustomCompression86}, |
404 | | {"kCustomCompression87", kCustomCompression87}, |
405 | | {"kCustomCompression88", kCustomCompression88}, |
406 | | {"kCustomCompression89", kCustomCompression89}, |
407 | | {"kCustomCompression8A", kCustomCompression8A}, |
408 | | {"kCustomCompression8B", kCustomCompression8B}, |
409 | | {"kCustomCompression8C", kCustomCompression8C}, |
410 | | {"kCustomCompression8D", kCustomCompression8D}, |
411 | | {"kCustomCompression8E", kCustomCompression8E}, |
412 | | {"kCustomCompression8F", kCustomCompression8F}, |
413 | | {"kCustomCompression90", kCustomCompression90}, |
414 | | {"kCustomCompression91", kCustomCompression91}, |
415 | | {"kCustomCompression92", kCustomCompression92}, |
416 | | {"kCustomCompression93", kCustomCompression93}, |
417 | | {"kCustomCompression94", kCustomCompression94}, |
418 | | {"kCustomCompression95", kCustomCompression95}, |
419 | | {"kCustomCompression96", kCustomCompression96}, |
420 | | {"kCustomCompression97", kCustomCompression97}, |
421 | | {"kCustomCompression98", kCustomCompression98}, |
422 | | {"kCustomCompression99", kCustomCompression99}, |
423 | | {"kCustomCompression9A", kCustomCompression9A}, |
424 | | {"kCustomCompression9B", kCustomCompression9B}, |
425 | | {"kCustomCompression9C", kCustomCompression9C}, |
426 | | {"kCustomCompression9D", kCustomCompression9D}, |
427 | | {"kCustomCompression9E", kCustomCompression9E}, |
428 | | {"kCustomCompression9F", kCustomCompression9F}, |
429 | | {"kCustomCompressionA0", kCustomCompressionA0}, |
430 | | {"kCustomCompressionA1", kCustomCompressionA1}, |
431 | | {"kCustomCompressionA2", kCustomCompressionA2}, |
432 | | {"kCustomCompressionA3", kCustomCompressionA3}, |
433 | | {"kCustomCompressionA4", kCustomCompressionA4}, |
434 | | {"kCustomCompressionA5", kCustomCompressionA5}, |
435 | | {"kCustomCompressionA6", kCustomCompressionA6}, |
436 | | {"kCustomCompressionA7", kCustomCompressionA7}, |
437 | | {"kCustomCompressionA8", kCustomCompressionA8}, |
438 | | {"kCustomCompressionA9", kCustomCompressionA9}, |
439 | | {"kCustomCompressionAA", kCustomCompressionAA}, |
440 | | {"kCustomCompressionAB", kCustomCompressionAB}, |
441 | | {"kCustomCompressionAC", kCustomCompressionAC}, |
442 | | {"kCustomCompressionAD", kCustomCompressionAD}, |
443 | | {"kCustomCompressionAE", kCustomCompressionAE}, |
444 | | {"kCustomCompressionAF", kCustomCompressionAF}, |
445 | | {"kCustomCompressionB0", kCustomCompressionB0}, |
446 | | {"kCustomCompressionB1", kCustomCompressionB1}, |
447 | | {"kCustomCompressionB2", kCustomCompressionB2}, |
448 | | {"kCustomCompressionB3", kCustomCompressionB3}, |
449 | | {"kCustomCompressionB4", kCustomCompressionB4}, |
450 | | {"kCustomCompressionB5", kCustomCompressionB5}, |
451 | | {"kCustomCompressionB6", kCustomCompressionB6}, |
452 | | {"kCustomCompressionB7", kCustomCompressionB7}, |
453 | | {"kCustomCompressionB8", kCustomCompressionB8}, |
454 | | {"kCustomCompressionB9", kCustomCompressionB9}, |
455 | | {"kCustomCompressionBA", kCustomCompressionBA}, |
456 | | {"kCustomCompressionBB", kCustomCompressionBB}, |
457 | | {"kCustomCompressionBC", kCustomCompressionBC}, |
458 | | {"kCustomCompressionBD", kCustomCompressionBD}, |
459 | | {"kCustomCompressionBE", kCustomCompressionBE}, |
460 | | {"kCustomCompressionBF", kCustomCompressionBF}, |
461 | | {"kCustomCompressionC0", kCustomCompressionC0}, |
462 | | {"kCustomCompressionC1", kCustomCompressionC1}, |
463 | | {"kCustomCompressionC2", kCustomCompressionC2}, |
464 | | {"kCustomCompressionC3", kCustomCompressionC3}, |
465 | | {"kCustomCompressionC4", kCustomCompressionC4}, |
466 | | {"kCustomCompressionC5", kCustomCompressionC5}, |
467 | | {"kCustomCompressionC6", kCustomCompressionC6}, |
468 | | {"kCustomCompressionC7", kCustomCompressionC7}, |
469 | | {"kCustomCompressionC8", kCustomCompressionC8}, |
470 | | {"kCustomCompressionC9", kCustomCompressionC9}, |
471 | | {"kCustomCompressionCA", kCustomCompressionCA}, |
472 | | {"kCustomCompressionCB", kCustomCompressionCB}, |
473 | | {"kCustomCompressionCC", kCustomCompressionCC}, |
474 | | {"kCustomCompressionCD", kCustomCompressionCD}, |
475 | | {"kCustomCompressionCE", kCustomCompressionCE}, |
476 | | {"kCustomCompressionCF", kCustomCompressionCF}, |
477 | | {"kCustomCompressionD0", kCustomCompressionD0}, |
478 | | {"kCustomCompressionD1", kCustomCompressionD1}, |
479 | | {"kCustomCompressionD2", kCustomCompressionD2}, |
480 | | {"kCustomCompressionD3", kCustomCompressionD3}, |
481 | | {"kCustomCompressionD4", kCustomCompressionD4}, |
482 | | {"kCustomCompressionD5", kCustomCompressionD5}, |
483 | | {"kCustomCompressionD6", kCustomCompressionD6}, |
484 | | {"kCustomCompressionD7", kCustomCompressionD7}, |
485 | | {"kCustomCompressionD8", kCustomCompressionD8}, |
486 | | {"kCustomCompressionD9", kCustomCompressionD9}, |
487 | | {"kCustomCompressionDA", kCustomCompressionDA}, |
488 | | {"kCustomCompressionDB", kCustomCompressionDB}, |
489 | | {"kCustomCompressionDC", kCustomCompressionDC}, |
490 | | {"kCustomCompressionDD", kCustomCompressionDD}, |
491 | | {"kCustomCompressionDE", kCustomCompressionDE}, |
492 | | {"kCustomCompressionDF", kCustomCompressionDF}, |
493 | | {"kCustomCompressionE0", kCustomCompressionE0}, |
494 | | {"kCustomCompressionE1", kCustomCompressionE1}, |
495 | | {"kCustomCompressionE2", kCustomCompressionE2}, |
496 | | {"kCustomCompressionE3", kCustomCompressionE3}, |
497 | | {"kCustomCompressionE4", kCustomCompressionE4}, |
498 | | {"kCustomCompressionE5", kCustomCompressionE5}, |
499 | | {"kCustomCompressionE6", kCustomCompressionE6}, |
500 | | {"kCustomCompressionE7", kCustomCompressionE7}, |
501 | | {"kCustomCompressionE8", kCustomCompressionE8}, |
502 | | {"kCustomCompressionE9", kCustomCompressionE9}, |
503 | | {"kCustomCompressionEA", kCustomCompressionEA}, |
504 | | {"kCustomCompressionEB", kCustomCompressionEB}, |
505 | | {"kCustomCompressionEC", kCustomCompressionEC}, |
506 | | {"kCustomCompressionED", kCustomCompressionED}, |
507 | | {"kCustomCompressionEE", kCustomCompressionEE}, |
508 | | {"kCustomCompressionEF", kCustomCompressionEF}, |
509 | | {"kCustomCompressionF0", kCustomCompressionF0}, |
510 | | {"kCustomCompressionF1", kCustomCompressionF1}, |
511 | | {"kCustomCompressionF2", kCustomCompressionF2}, |
512 | | {"kCustomCompressionF3", kCustomCompressionF3}, |
513 | | {"kCustomCompressionF4", kCustomCompressionF4}, |
514 | | {"kCustomCompressionF5", kCustomCompressionF5}, |
515 | | {"kCustomCompressionF6", kCustomCompressionF6}, |
516 | | {"kCustomCompressionF7", kCustomCompressionF7}, |
517 | | {"kCustomCompressionF8", kCustomCompressionF8}, |
518 | | {"kCustomCompressionF9", kCustomCompressionF9}, |
519 | | {"kCustomCompressionFA", kCustomCompressionFA}, |
520 | | {"kCustomCompressionFB", kCustomCompressionFB}, |
521 | | {"kCustomCompressionFC", kCustomCompressionFC}, |
522 | | {"kCustomCompressionFD", kCustomCompressionFD}, |
523 | | {"kCustomCompressionFE", kCustomCompressionFE}, |
524 | | {"kDisableCompressionOption", kDisableCompressionOption}}; |
525 | | |
526 | 0 | const std::vector<CompressionType>& GetSupportedCompressions() { |
527 | 0 | static std::vector<CompressionType> supported_compressions = []() { |
528 | | // std::set internally to deduplicate potential name aliases |
529 | 0 | std::set<CompressionType> comp_set; |
530 | 0 | for (const auto& comp_to_name : |
531 | 0 | OptionsHelper::compression_type_string_map) { |
532 | 0 | CompressionType t = comp_to_name.second; |
533 | 0 | if (t != kDisableCompressionOption && CompressionTypeSupported(t)) { |
534 | 0 | comp_set.insert(t); |
535 | 0 | } |
536 | 0 | } |
537 | 0 | return std::vector<CompressionType>(comp_set.begin(), comp_set.end()); |
538 | 0 | }(); |
539 | 0 | return supported_compressions; |
540 | 0 | } |
541 | | |
542 | 0 | const std::vector<CompressionType>& GetSupportedDictCompressions() { |
543 | 0 | static std::vector<CompressionType> supported_dict_compressions = []() { |
544 | 0 | std::set<CompressionType> comp_set; |
545 | 0 | for (const auto& comp_to_name : |
546 | 0 | OptionsHelper::compression_type_string_map) { |
547 | 0 | CompressionType t = comp_to_name.second; |
548 | 0 | if (t != kDisableCompressionOption && DictCompressionTypeSupported(t)) { |
549 | 0 | comp_set.insert(t); |
550 | 0 | } |
551 | 0 | } |
552 | 0 | return std::vector<CompressionType>(comp_set.begin(), comp_set.end()); |
553 | 0 | }(); |
554 | 0 | return supported_dict_compressions; |
555 | 0 | } |
556 | | |
557 | 0 | const std::vector<ChecksumType>& GetSupportedChecksums() { |
558 | 0 | static std::vector<ChecksumType> supported_checksums = []() { |
559 | 0 | std::set<ChecksumType> checksum_types; |
560 | 0 | for (const auto& e : OptionsHelper::checksum_type_string_map) { |
561 | 0 | checksum_types.insert(e.second); |
562 | 0 | } |
563 | 0 | return std::vector<ChecksumType>(checksum_types.begin(), |
564 | 0 | checksum_types.end()); |
565 | 0 | }(); |
566 | 0 | return supported_checksums; |
567 | 0 | } |
568 | | |
569 | | static bool ParseOptionHelper(void* opt_address, const OptionType& opt_type, |
570 | 10.7M | const std::string& value) { |
571 | 10.7M | switch (opt_type) { |
572 | 3.97M | case OptionType::kBoolean: |
573 | 3.97M | *static_cast<bool*>(opt_address) = ParseBoolean("", value); |
574 | 3.97M | break; |
575 | 1.94M | case OptionType::kInt: |
576 | 1.94M | *static_cast<int*>(opt_address) = ParseInt(value); |
577 | 1.94M | break; |
578 | 0 | case OptionType::kInt32T: |
579 | 0 | *static_cast<int32_t*>(opt_address) = ParseInt32(value); |
580 | 0 | break; |
581 | 55.0k | case OptionType::kInt64T: |
582 | 55.0k | PutUnaligned(static_cast<int64_t*>(opt_address), ParseInt64(value)); |
583 | 55.0k | break; |
584 | 294k | case OptionType::kUInt: |
585 | 294k | *static_cast<unsigned int*>(opt_address) = ParseUint32(value); |
586 | 294k | break; |
587 | 55.0k | case OptionType::kUInt8T: |
588 | 55.0k | *static_cast<uint8_t*>(opt_address) = ParseUint8(value); |
589 | 55.0k | break; |
590 | 752k | case OptionType::kUInt32T: |
591 | 752k | *static_cast<uint32_t*>(opt_address) = ParseUint32(value); |
592 | 752k | break; |
593 | 1.71M | case OptionType::kUInt64T: |
594 | 1.71M | PutUnaligned(static_cast<uint64_t*>(opt_address), ParseUint64(value)); |
595 | 1.71M | break; |
596 | 923k | case OptionType::kSizeT: |
597 | 923k | PutUnaligned(static_cast<size_t*>(opt_address), ParseSizeT(value)); |
598 | 923k | break; |
599 | 0 | case OptionType::kAtomicInt: |
600 | 0 | static_cast<std::atomic<int>*>(opt_address) |
601 | 0 | ->store(ParseInt(value), std::memory_order_release); |
602 | 0 | break; |
603 | 37.3k | case OptionType::kString: |
604 | 37.3k | *static_cast<std::string*>(opt_address) = value; |
605 | 37.3k | break; |
606 | 330k | case OptionType::kDouble: |
607 | 330k | *static_cast<double*>(opt_address) = ParseDouble(value); |
608 | 330k | break; |
609 | 55.0k | case OptionType::kCompactionStyle: |
610 | 55.0k | return ParseEnum<CompactionStyle>( |
611 | 55.0k | compaction_style_string_map, value, |
612 | 55.0k | static_cast<CompactionStyle*>(opt_address)); |
613 | 55.0k | case OptionType::kCompactionPri: |
614 | 55.0k | return ParseEnum<CompactionPri>(compaction_pri_string_map, value, |
615 | 55.0k | static_cast<CompactionPri*>(opt_address)); |
616 | 202k | case OptionType::kCompressionType: |
617 | 202k | return ParseEnum<CompressionType>( |
618 | 202k | compression_type_string_map, value, |
619 | 202k | static_cast<CompressionType*>(opt_address)); |
620 | 55.0k | case OptionType::kChecksumType: |
621 | 55.0k | return ParseEnum<ChecksumType>(checksum_type_string_map, value, |
622 | 55.0k | static_cast<ChecksumType*>(opt_address)); |
623 | 0 | case OptionType::kEncodingType: |
624 | 0 | return ParseEnum<EncodingType>(encoding_type_string_map, value, |
625 | 0 | static_cast<EncodingType*>(opt_address)); |
626 | 55.0k | case OptionType::kCompactionStopStyle: |
627 | 55.0k | return ParseEnum<CompactionStopStyle>( |
628 | 55.0k | compaction_stop_style_string_map, value, |
629 | 55.0k | static_cast<CompactionStopStyle*>(opt_address)); |
630 | 0 | case OptionType::kEncodedString: { |
631 | 0 | std::string* output_addr = static_cast<std::string*>(opt_address); |
632 | 0 | (Slice(value)).DecodeHex(output_addr); |
633 | 0 | break; |
634 | 0 | } |
635 | 239k | case OptionType::kTemperature: { |
636 | 239k | return ParseEnum<Temperature>(temperature_string_map, value, |
637 | 239k | static_cast<Temperature*>(opt_address)); |
638 | 0 | } |
639 | 0 | default: |
640 | 0 | return false; |
641 | 10.7M | } |
642 | 10.0M | return true; |
643 | 10.7M | } |
644 | | |
645 | | bool SerializeSingleOptionHelper(const void* opt_address, |
646 | | const OptionType opt_type, |
647 | 23.4M | std::string* value) { |
648 | 23.4M | assert(value); |
649 | 23.4M | switch (opt_type) { |
650 | 8.77M | case OptionType::kBoolean: |
651 | 8.77M | *value = *(static_cast<const bool*>(opt_address)) ? "true" : "false"; |
652 | 8.77M | break; |
653 | 4.06M | case OptionType::kInt: |
654 | 4.06M | *value = std::to_string(*(static_cast<const int*>(opt_address))); |
655 | 4.06M | break; |
656 | 0 | case OptionType::kInt32T: |
657 | 0 | *value = std::to_string(*(static_cast<const int32_t*>(opt_address))); |
658 | 0 | break; |
659 | 110k | case OptionType::kInt64T: { |
660 | 110k | int64_t v; |
661 | 110k | GetUnaligned(static_cast<const int64_t*>(opt_address), &v); |
662 | 110k | *value = std::to_string(v); |
663 | 110k | } break; |
664 | 589k | case OptionType::kUInt: |
665 | 589k | *value = std::to_string(*(static_cast<const unsigned int*>(opt_address))); |
666 | 589k | break; |
667 | 110k | case OptionType::kUInt8T: |
668 | 110k | *value = std::to_string(*(static_cast<const uint8_t*>(opt_address))); |
669 | 110k | break; |
670 | 1.72M | case OptionType::kUInt32T: |
671 | 1.72M | *value = std::to_string(*(static_cast<const uint32_t*>(opt_address))); |
672 | 1.72M | break; |
673 | 3.54M | case OptionType::kUInt64T: { |
674 | 3.54M | uint64_t v; |
675 | 3.54M | GetUnaligned(static_cast<const uint64_t*>(opt_address), &v); |
676 | 3.54M | *value = std::to_string(v); |
677 | 3.54M | } break; |
678 | 2.12M | case OptionType::kSizeT: { |
679 | 2.12M | size_t v; |
680 | 2.12M | GetUnaligned(static_cast<const size_t*>(opt_address), &v); |
681 | 2.12M | *value = std::to_string(v); |
682 | 2.12M | } break; |
683 | 715k | case OptionType::kDouble: |
684 | 715k | *value = std::to_string(*(static_cast<const double*>(opt_address))); |
685 | 715k | break; |
686 | 0 | case OptionType::kAtomicInt: |
687 | 0 | *value = std::to_string(static_cast<const std::atomic<int>*>(opt_address) |
688 | 0 | ->load(std::memory_order_acquire)); |
689 | 0 | break; |
690 | 298k | case OptionType::kString: |
691 | 298k | *value = |
692 | 298k | EscapeOptionString(*(static_cast<const std::string*>(opt_address))); |
693 | 298k | break; |
694 | 110k | case OptionType::kCompactionStyle: |
695 | 110k | return SerializeEnum<CompactionStyle>( |
696 | 110k | compaction_style_string_map, |
697 | 110k | *(static_cast<const CompactionStyle*>(opt_address)), value); |
698 | 110k | case OptionType::kCompactionPri: |
699 | 110k | return SerializeEnum<CompactionPri>( |
700 | 110k | compaction_pri_string_map, |
701 | 110k | *(static_cast<const CompactionPri*>(opt_address)), value); |
702 | 404k | case OptionType::kCompressionType: |
703 | 404k | return SerializeEnum<CompressionType>( |
704 | 404k | compression_type_string_map, |
705 | 404k | *(static_cast<const CompressionType*>(opt_address)), value); |
706 | 165k | case OptionType::kChecksumType: |
707 | 165k | return SerializeEnum<ChecksumType>( |
708 | 165k | checksum_type_string_map, |
709 | 165k | *static_cast<const ChecksumType*>(opt_address), value); |
710 | 0 | case OptionType::kEncodingType: |
711 | 0 | return SerializeEnum<EncodingType>( |
712 | 0 | encoding_type_string_map, |
713 | 0 | *static_cast<const EncodingType*>(opt_address), value); |
714 | 110k | case OptionType::kCompactionStopStyle: |
715 | 110k | return SerializeEnum<CompactionStopStyle>( |
716 | 110k | compaction_stop_style_string_map, |
717 | 110k | *static_cast<const CompactionStopStyle*>(opt_address), value); |
718 | 0 | case OptionType::kEncodedString: { |
719 | 0 | const auto* ptr = static_cast<const std::string*>(opt_address); |
720 | 0 | *value = (Slice(*ptr)).ToString(true); |
721 | 0 | break; |
722 | 0 | } |
723 | 479k | case OptionType::kTemperature: { |
724 | 479k | return SerializeEnum<Temperature>( |
725 | 479k | temperature_string_map, *static_cast<const Temperature*>(opt_address), |
726 | 479k | value); |
727 | 0 | } |
728 | 0 | default: |
729 | 0 | return false; |
730 | 23.4M | } |
731 | 22.0M | return true; |
732 | 23.4M | } |
733 | | |
734 | | template <typename T> |
735 | | Status ConfigureFromMap( |
736 | | const ConfigOptions& config_options, |
737 | | const std::unordered_map<std::string, std::string>& opt_map, |
738 | 92.3k | const std::string& option_name, Configurable* config, T* new_opts) { |
739 | 92.3k | Status s = config->ConfigureFromMap(config_options, opt_map); |
740 | 92.3k | if (s.ok()) { |
741 | 92.3k | *new_opts = *(config->GetOptions<T>(option_name)); |
742 | 92.3k | } |
743 | 92.3k | return s; |
744 | 92.3k | } rocksdb::Status rocksdb::ConfigureFromMap<rocksdb::ColumnFamilyOptions>(rocksdb::ConfigOptions const&, std::__1::unordered_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::hash<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::equal_to<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, rocksdb::Configurable*, rocksdb::ColumnFamilyOptions*) Line | Count | Source | 738 | 55.0k | const std::string& option_name, Configurable* config, T* new_opts) { | 739 | 55.0k | Status s = config->ConfigureFromMap(config_options, opt_map); | 740 | 55.0k | if (s.ok()) { | 741 | 55.0k | *new_opts = *(config->GetOptions<T>(option_name)); | 742 | 55.0k | } | 743 | 55.0k | return s; | 744 | 55.0k | } |
rocksdb::Status rocksdb::ConfigureFromMap<rocksdb::DBOptions>(rocksdb::ConfigOptions const&, std::__1::unordered_map<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::hash<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::equal_to<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, rocksdb::Configurable*, rocksdb::DBOptions*) Line | Count | Source | 738 | 37.3k | const std::string& option_name, Configurable* config, T* new_opts) { | 739 | 37.3k | Status s = config->ConfigureFromMap(config_options, opt_map); | 740 | 37.3k | if (s.ok()) { | 741 | 37.3k | *new_opts = *(config->GetOptions<T>(option_name)); | 742 | 37.3k | } | 743 | 37.3k | return s; | 744 | 37.3k | } |
|
745 | | |
746 | | Status StringToMap(const std::string& opts_str, |
747 | 385k | std::unordered_map<std::string, std::string>* opts_map) { |
748 | 385k | assert(opts_map); |
749 | | // Example: |
750 | | // opts_str = "write_buffer_size=1024;max_write_buffer_number=2;" |
751 | | // "nested_opt={opt1=1;opt2=2};max_bytes_for_level_base=100" |
752 | 385k | size_t pos = 0; |
753 | 385k | std::string opts = trim(opts_str); |
754 | | // If the input string starts and ends with "{...}", strip off the brackets |
755 | 660k | while (opts.size() > 2 && opts[0] == '{' && opts[opts.size() - 1] == '}') { |
756 | 275k | opts = trim(opts.substr(1, opts.size() - 2)); |
757 | 275k | } |
758 | | |
759 | 2.64M | while (pos < opts.size()) { |
760 | 2.25M | size_t eq_pos = opts.find_first_of("={};", pos); |
761 | 2.25M | if (eq_pos == std::string::npos) { |
762 | 0 | return Status::InvalidArgument("Mismatched key value pair, '=' expected"); |
763 | 2.25M | } else if (opts[eq_pos] != '=') { |
764 | 0 | return Status::InvalidArgument("Unexpected char in key"); |
765 | 0 | } |
766 | | |
767 | 2.25M | std::string key = trim(opts.substr(pos, eq_pos - pos)); |
768 | 2.25M | if (key.empty()) { |
769 | 0 | return Status::InvalidArgument("Empty key found"); |
770 | 0 | } |
771 | | |
772 | 2.25M | std::string value; |
773 | 2.25M | Status s = OptionTypeInfo::NextToken(opts, ';', eq_pos + 1, &pos, &value); |
774 | 2.25M | if (!s.ok()) { |
775 | 0 | return s; |
776 | 2.25M | } else { |
777 | 2.25M | (*opts_map)[key] = value; |
778 | 2.25M | if (pos == std::string::npos) { |
779 | 0 | break; |
780 | 2.25M | } else { |
781 | 2.25M | pos++; |
782 | 2.25M | } |
783 | 2.25M | } |
784 | 2.25M | } |
785 | | |
786 | 385k | return Status::OK(); |
787 | 385k | } |
788 | | |
789 | | Status GetStringFromDBOptions(std::string* opt_string, |
790 | | const DBOptions& db_options, |
791 | 0 | const std::string& delimiter) { |
792 | 0 | ConfigOptions config_options(db_options); |
793 | 0 | config_options.delimiter = delimiter; |
794 | 0 | return GetStringFromDBOptions(config_options, db_options, opt_string); |
795 | 0 | } |
796 | | |
797 | | Status GetStringFromDBOptions(const ConfigOptions& config_options, |
798 | | const DBOptions& db_options, |
799 | 37.3k | std::string* opt_string) { |
800 | 37.3k | assert(opt_string); |
801 | 37.3k | opt_string->clear(); |
802 | 37.3k | auto config = DBOptionsAsConfigurable(db_options); |
803 | 37.3k | return config->GetOptionString(config_options, opt_string); |
804 | 37.3k | } |
805 | | |
806 | | Status GetStringFromColumnFamilyOptions(std::string* opt_string, |
807 | | const ColumnFamilyOptions& cf_options, |
808 | 0 | const std::string& delimiter) { |
809 | 0 | ConfigOptions config_options; |
810 | 0 | config_options.delimiter = delimiter; |
811 | 0 | return GetStringFromColumnFamilyOptions(config_options, cf_options, |
812 | 0 | opt_string); |
813 | 0 | } |
814 | | |
815 | | Status GetStringFromColumnFamilyOptions(const ConfigOptions& config_options, |
816 | | const ColumnFamilyOptions& cf_options, |
817 | 55.0k | std::string* opt_string) { |
818 | 55.0k | const auto config = CFOptionsAsConfigurable(cf_options); |
819 | 55.0k | return config->GetOptionString(config_options, opt_string); |
820 | 55.0k | } |
821 | | |
822 | | Status GetStringFromCompressionType(std::string* compression_str, |
823 | 0 | CompressionType compression_type) { |
824 | 0 | bool ok = SerializeEnum<CompressionType>(compression_type_string_map, |
825 | 0 | compression_type, compression_str); |
826 | 0 | if (ok) { |
827 | 0 | return Status::OK(); |
828 | 0 | } else { |
829 | 0 | return Status::InvalidArgument("Invalid compression types"); |
830 | 0 | } |
831 | 0 | } |
832 | | |
833 | | Status GetColumnFamilyOptionsFromMap( |
834 | | const ConfigOptions& config_options, |
835 | | const ColumnFamilyOptions& base_options, |
836 | | const std::unordered_map<std::string, std::string>& opts_map, |
837 | 55.0k | ColumnFamilyOptions* new_options) { |
838 | 55.0k | assert(new_options); |
839 | | |
840 | 55.0k | *new_options = base_options; |
841 | | |
842 | 55.0k | const auto config = CFOptionsAsConfigurable(base_options); |
843 | 55.0k | Status s = ConfigureFromMap<ColumnFamilyOptions>( |
844 | 55.0k | config_options, opts_map, OptionsHelper::kCFOptionsName, config.get(), |
845 | 55.0k | new_options); |
846 | | // Translate any errors (NotFound, NotSupported, to InvalidArgument |
847 | 55.0k | if (s.ok() || s.IsInvalidArgument()) { |
848 | 55.0k | return s; |
849 | 55.0k | } else { |
850 | 0 | return Status::InvalidArgument(s.getState()); |
851 | 0 | } |
852 | 55.0k | } |
853 | | |
854 | | Status GetColumnFamilyOptionsFromString(const ConfigOptions& config_options, |
855 | | const ColumnFamilyOptions& base_options, |
856 | | const std::string& opts_str, |
857 | 0 | ColumnFamilyOptions* new_options) { |
858 | 0 | std::unordered_map<std::string, std::string> opts_map; |
859 | 0 | Status s = StringToMap(opts_str, &opts_map); |
860 | 0 | if (!s.ok()) { |
861 | 0 | *new_options = base_options; |
862 | 0 | return s; |
863 | 0 | } |
864 | 0 | return GetColumnFamilyOptionsFromMap(config_options, base_options, opts_map, |
865 | 0 | new_options); |
866 | 0 | } |
867 | | |
868 | | Status GetDBOptionsFromMap( |
869 | | const ConfigOptions& config_options, const DBOptions& base_options, |
870 | | const std::unordered_map<std::string, std::string>& opts_map, |
871 | 37.3k | DBOptions* new_options) { |
872 | 37.3k | assert(new_options); |
873 | 37.3k | *new_options = base_options; |
874 | 37.3k | auto config = DBOptionsAsConfigurable(base_options); |
875 | 37.3k | Status s = ConfigureFromMap<DBOptions>(config_options, opts_map, |
876 | 37.3k | OptionsHelper::kDBOptionsName, |
877 | 37.3k | config.get(), new_options); |
878 | | // Translate any errors (NotFound, NotSupported, to InvalidArgument |
879 | 37.3k | if (s.ok() || s.IsInvalidArgument()) { |
880 | 37.3k | return s; |
881 | 37.3k | } else { |
882 | 0 | return Status::InvalidArgument(s.getState()); |
883 | 0 | } |
884 | 37.3k | } |
885 | | |
886 | | Status GetDBOptionsFromString(const ConfigOptions& config_options, |
887 | | const DBOptions& base_options, |
888 | | const std::string& opts_str, |
889 | 0 | DBOptions* new_options) { |
890 | 0 | std::unordered_map<std::string, std::string> opts_map; |
891 | 0 | Status s = StringToMap(opts_str, &opts_map); |
892 | 0 | if (!s.ok()) { |
893 | 0 | *new_options = base_options; |
894 | 0 | return s; |
895 | 0 | } |
896 | 0 | return GetDBOptionsFromMap(config_options, base_options, opts_map, |
897 | 0 | new_options); |
898 | 0 | } |
899 | | |
900 | | Status GetOptionsFromString(const Options& base_options, |
901 | 0 | const std::string& opts_str, Options* new_options) { |
902 | 0 | ConfigOptions config_options(base_options); |
903 | 0 | config_options.input_strings_escaped = false; |
904 | 0 | config_options.ignore_unknown_options = false; |
905 | |
|
906 | 0 | return GetOptionsFromString(config_options, base_options, opts_str, |
907 | 0 | new_options); |
908 | 0 | } |
909 | | |
910 | | Status GetOptionsFromString(const ConfigOptions& config_options, |
911 | | const Options& base_options, |
912 | 0 | const std::string& opts_str, Options* new_options) { |
913 | 0 | ColumnFamilyOptions new_cf_options; |
914 | 0 | std::unordered_map<std::string, std::string> unused_opts; |
915 | 0 | std::unordered_map<std::string, std::string> opts_map; |
916 | |
|
917 | 0 | assert(new_options); |
918 | 0 | *new_options = base_options; |
919 | 0 | Status s = StringToMap(opts_str, &opts_map); |
920 | 0 | if (!s.ok()) { |
921 | 0 | return s; |
922 | 0 | } |
923 | 0 | auto config = DBOptionsAsConfigurable(base_options); |
924 | 0 | s = config->ConfigureFromMap(config_options, opts_map, &unused_opts); |
925 | |
|
926 | 0 | if (s.ok()) { |
927 | 0 | DBOptions* new_db_options = |
928 | 0 | config->GetOptions<DBOptions>(OptionsHelper::kDBOptionsName); |
929 | 0 | if (!unused_opts.empty()) { |
930 | 0 | s = GetColumnFamilyOptionsFromMap(config_options, base_options, |
931 | 0 | unused_opts, &new_cf_options); |
932 | 0 | if (s.ok()) { |
933 | 0 | *new_options = Options(*new_db_options, new_cf_options); |
934 | 0 | } |
935 | 0 | } else { |
936 | 0 | *new_options = Options(*new_db_options, base_options); |
937 | 0 | } |
938 | 0 | } |
939 | | // Translate any errors (NotFound, NotSupported, to InvalidArgument |
940 | 0 | if (s.ok() || s.IsInvalidArgument()) { |
941 | 0 | return s; |
942 | 0 | } else { |
943 | 0 | return Status::InvalidArgument(s.getState()); |
944 | 0 | } |
945 | 0 | } |
946 | | |
947 | | std::unordered_map<std::string, EncodingType> |
948 | | OptionsHelper::encoding_type_string_map = {{"kPlain", kPlain}, |
949 | | {"kPrefix", kPrefix}}; |
950 | | |
951 | | std::unordered_map<std::string, CompactionStyle> |
952 | | OptionsHelper::compaction_style_string_map = { |
953 | | {"kCompactionStyleLevel", kCompactionStyleLevel}, |
954 | | {"kCompactionStyleUniversal", kCompactionStyleUniversal}, |
955 | | {"kCompactionStyleFIFO", kCompactionStyleFIFO}, |
956 | | {"kCompactionStyleNone", kCompactionStyleNone}}; |
957 | | |
958 | | std::unordered_map<std::string, CompactionPri> |
959 | | OptionsHelper::compaction_pri_string_map = { |
960 | | {"kByCompensatedSize", kByCompensatedSize}, |
961 | | {"kOldestLargestSeqFirst", kOldestLargestSeqFirst}, |
962 | | {"kOldestSmallestSeqFirst", kOldestSmallestSeqFirst}, |
963 | | {"kMinOverlappingRatio", kMinOverlappingRatio}, |
964 | | {"kRoundRobin", kRoundRobin}}; |
965 | | |
966 | | std::unordered_map<std::string, CompactionStopStyle> |
967 | | OptionsHelper::compaction_stop_style_string_map = { |
968 | | {"kCompactionStopStyleSimilarSize", kCompactionStopStyleSimilarSize}, |
969 | | {"kCompactionStopStyleTotalSize", kCompactionStopStyleTotalSize}}; |
970 | | |
971 | | std::unordered_map<std::string, Temperature> |
972 | | OptionsHelper::temperature_string_map = { |
973 | | {"kUnknown", Temperature::kUnknown}, {"kHot", Temperature::kHot}, |
974 | | {"kWarm", Temperature::kWarm}, {"kCool", Temperature::kCool}, |
975 | | {"kCold", Temperature::kCold}, {"kIce", Temperature::kIce}}; |
976 | | |
977 | | std::unordered_map<std::string, PrepopulateBlobCache> |
978 | | OptionsHelper::prepopulate_blob_cache_string_map = { |
979 | | {"kDisable", PrepopulateBlobCache::kDisable}, |
980 | | {"kFlushOnly", PrepopulateBlobCache::kFlushOnly}}; |
981 | | |
982 | | Status OptionTypeInfo::NextToken(const std::string& opts, char delimiter, |
983 | 2.64M | size_t pos, size_t* end, std::string* token) { |
984 | 2.64M | while (pos < opts.size() && isspace(opts[pos])) { |
985 | 0 | ++pos; |
986 | 0 | } |
987 | | // Empty value at the end |
988 | 2.64M | if (pos >= opts.size()) { |
989 | 0 | *token = ""; |
990 | 0 | *end = std::string::npos; |
991 | 0 | return Status::OK(); |
992 | 2.64M | } else if (opts[pos] == '{') { |
993 | 0 | int count = 1; |
994 | 0 | size_t brace_pos = pos + 1; |
995 | 0 | while (brace_pos < opts.size()) { |
996 | 0 | if (opts[brace_pos] == '{') { |
997 | 0 | ++count; |
998 | 0 | } else if (opts[brace_pos] == '}') { |
999 | 0 | --count; |
1000 | 0 | if (count == 0) { |
1001 | 0 | break; |
1002 | 0 | } |
1003 | 0 | } |
1004 | 0 | ++brace_pos; |
1005 | 0 | } |
1006 | | // found the matching closing brace |
1007 | 0 | if (count == 0) { |
1008 | 0 | *token = trim(opts.substr(pos + 1, brace_pos - pos - 1)); |
1009 | | // skip all whitespace and move to the next delimiter |
1010 | | // brace_pos points to the next position after the matching '}' |
1011 | 0 | pos = brace_pos + 1; |
1012 | 0 | while (pos < opts.size() && isspace(opts[pos])) { |
1013 | 0 | ++pos; |
1014 | 0 | } |
1015 | 0 | if (pos < opts.size() && opts[pos] != delimiter) { |
1016 | 0 | return Status::InvalidArgument("Unexpected chars after nested options"); |
1017 | 0 | } |
1018 | 0 | *end = pos; |
1019 | 0 | } else { |
1020 | 0 | return Status::InvalidArgument( |
1021 | 0 | "Mismatched curly braces for nested options"); |
1022 | 0 | } |
1023 | 2.64M | } else { |
1024 | 2.64M | *end = opts.find(delimiter, pos); |
1025 | 2.64M | if (*end == std::string::npos) { |
1026 | | // It either ends with a trailing semi-colon or the last key-value pair |
1027 | 55.0k | *token = trim(opts.substr(pos)); |
1028 | 2.58M | } else { |
1029 | 2.58M | *token = trim(opts.substr(pos, *end - pos)); |
1030 | 2.58M | } |
1031 | 2.64M | } |
1032 | 2.64M | return Status::OK(); |
1033 | 2.64M | } |
1034 | | |
1035 | | Status OptionTypeInfo::Parse(const ConfigOptions& config_options, |
1036 | | const std::string& opt_name, |
1037 | 12.5M | const std::string& value, void* opt_ptr) const { |
1038 | 12.5M | if (IsDeprecated()) { |
1039 | 0 | return Status::OK(); |
1040 | 0 | } |
1041 | 12.5M | try { |
1042 | 12.5M | const std::string& opt_value = config_options.input_strings_escaped |
1043 | 12.5M | ? UnescapeOptionString(value) |
1044 | 12.5M | : value; |
1045 | | |
1046 | 12.5M | if (opt_ptr == nullptr) { |
1047 | 0 | return Status::NotFound("Nullptr option", opt_name); |
1048 | 12.5M | } else if (parse_func_ != nullptr) { |
1049 | 1.83M | ConfigOptions copy = config_options; |
1050 | 1.83M | copy.invoke_prepare_options = false; |
1051 | 1.83M | void* opt_addr = GetOffset(opt_ptr); |
1052 | 1.83M | return parse_func_(copy, opt_name, opt_value, opt_addr); |
1053 | 10.7M | } else if (ParseOptionHelper(GetOffset(opt_ptr), type_, opt_value)) { |
1054 | 10.7M | return Status::OK(); |
1055 | 10.7M | } else if (IsConfigurable()) { |
1056 | | // The option is <config>.<name> |
1057 | 0 | Configurable* config = AsRawPointer<Configurable>(opt_ptr); |
1058 | 0 | if (opt_value.empty()) { |
1059 | 0 | return Status::OK(); |
1060 | 0 | } else if (config == nullptr) { |
1061 | 0 | return Status::NotFound("Could not find configurable: ", opt_name); |
1062 | 0 | } else { |
1063 | 0 | ConfigOptions copy = config_options; |
1064 | 0 | copy.ignore_unknown_options = false; |
1065 | 0 | copy.invoke_prepare_options = false; |
1066 | 0 | if (opt_value.find('=') != std::string::npos) { |
1067 | 0 | return config->ConfigureFromString(copy, opt_value); |
1068 | 0 | } else { |
1069 | 0 | return config->ConfigureOption(copy, opt_name, opt_value); |
1070 | 0 | } |
1071 | 0 | } |
1072 | 0 | } else if (IsByName()) { |
1073 | 0 | return Status::NotSupported("Deserializing the option " + opt_name + |
1074 | 0 | " is not supported"); |
1075 | 0 | } else { |
1076 | 0 | return Status::InvalidArgument("Error parsing:", opt_name); |
1077 | 0 | } |
1078 | 12.5M | } catch (std::exception& e) { |
1079 | 0 | return Status::InvalidArgument("Error parsing " + opt_name + ":" + |
1080 | 0 | std::string(e.what())); |
1081 | 0 | } |
1082 | 12.5M | } |
1083 | | |
1084 | | Status OptionTypeInfo::ParseType( |
1085 | | const ConfigOptions& config_options, const std::string& opts_str, |
1086 | | const std::unordered_map<std::string, OptionTypeInfo>& type_map, |
1087 | 275k | void* opt_addr, std::unordered_map<std::string, std::string>* unused) { |
1088 | 275k | std::unordered_map<std::string, std::string> opts_map; |
1089 | 275k | Status status = StringToMap(opts_str, &opts_map); |
1090 | 275k | if (!status.ok()) { |
1091 | 0 | return status; |
1092 | 275k | } else { |
1093 | 275k | return ParseType(config_options, opts_map, type_map, opt_addr, unused); |
1094 | 275k | } |
1095 | 275k | } |
1096 | | |
1097 | | Status OptionTypeInfo::ParseType( |
1098 | | const ConfigOptions& config_options, |
1099 | | const std::unordered_map<std::string, std::string>& opts_map, |
1100 | | const std::unordered_map<std::string, OptionTypeInfo>& type_map, |
1101 | 275k | void* opt_addr, std::unordered_map<std::string, std::string>* unused) { |
1102 | 2.25M | for (const auto& opts_iter : opts_map) { |
1103 | 2.25M | std::string opt_name; |
1104 | 2.25M | const auto* opt_info = Find(opts_iter.first, type_map, &opt_name); |
1105 | 2.25M | if (opt_info != nullptr) { |
1106 | 2.25M | Status status = |
1107 | 2.25M | opt_info->Parse(config_options, opt_name, opts_iter.second, opt_addr); |
1108 | 2.25M | if (!status.ok()) { |
1109 | 0 | return status; |
1110 | 0 | } |
1111 | 2.25M | } else if (unused != nullptr) { |
1112 | 0 | (*unused)[opts_iter.first] = opts_iter.second; |
1113 | 0 | } else if (!config_options.ignore_unknown_options) { |
1114 | 0 | return Status::NotFound("Unrecognized option", opts_iter.first); |
1115 | 0 | } |
1116 | 2.25M | } |
1117 | 275k | return Status::OK(); |
1118 | 275k | } |
1119 | | |
1120 | | Status OptionTypeInfo::ParseStruct( |
1121 | | const ConfigOptions& config_options, const std::string& struct_name, |
1122 | | const std::unordered_map<std::string, OptionTypeInfo>* struct_map, |
1123 | 275k | const std::string& opt_name, const std::string& opt_value, void* opt_addr) { |
1124 | 275k | assert(struct_map); |
1125 | 275k | Status status; |
1126 | 275k | if (opt_name == struct_name || EndsWith(opt_name, "." + struct_name)) { |
1127 | | // This option represents the entire struct |
1128 | 275k | std::unordered_map<std::string, std::string> unused; |
1129 | 275k | status = |
1130 | 275k | ParseType(config_options, opt_value, *struct_map, opt_addr, &unused); |
1131 | 275k | if (status.ok() && !unused.empty() && |
1132 | 0 | !config_options.ignore_unknown_options) { |
1133 | 0 | status = Status::InvalidArgument( |
1134 | 0 | "Unrecognized option", struct_name + "." + unused.begin()->first); |
1135 | 0 | } |
1136 | 275k | } else if (StartsWith(opt_name, struct_name + ".")) { |
1137 | | // This option represents a nested field in the struct (e.g, struct.field) |
1138 | 0 | std::string elem_name; |
1139 | 0 | const auto opt_info = |
1140 | 0 | Find(opt_name.substr(struct_name.size() + 1), *struct_map, &elem_name); |
1141 | 0 | if (opt_info != nullptr) { |
1142 | 0 | status = opt_info->Parse(config_options, elem_name, opt_value, opt_addr); |
1143 | 0 | } else if (!config_options.ignore_unknown_options) { |
1144 | 0 | status = Status::InvalidArgument("Unrecognized option", opt_name); |
1145 | 0 | } |
1146 | 0 | } else { |
1147 | | // This option represents a field in the struct (e.g. field) |
1148 | 0 | std::string elem_name; |
1149 | 0 | const auto opt_info = Find(opt_name, *struct_map, &elem_name); |
1150 | 0 | if (opt_info != nullptr) { |
1151 | 0 | status = opt_info->Parse(config_options, elem_name, opt_value, opt_addr); |
1152 | 0 | } else if (!config_options.ignore_unknown_options) { |
1153 | 0 | status = Status::InvalidArgument("Unrecognized option", |
1154 | 0 | struct_name + "." + opt_name); |
1155 | 0 | } |
1156 | 0 | } |
1157 | 275k | return status; |
1158 | 275k | } |
1159 | | |
1160 | | Status OptionTypeInfo::Serialize(const ConfigOptions& config_options, |
1161 | | const std::string& opt_name, |
1162 | | const void* const opt_ptr, |
1163 | 27.9M | std::string* opt_value) const { |
1164 | | // If the option is no longer used in rocksdb and marked as deprecated, |
1165 | | // we skip it in the serialization. |
1166 | 27.9M | if (opt_ptr == nullptr || IsDeprecated()) { |
1167 | 0 | return Status::OK(); |
1168 | 27.9M | } else if (IsEnabled(OptionTypeFlags::kDontSerialize)) { |
1169 | 0 | return Status::NotSupported("Cannot serialize option: ", opt_name); |
1170 | 27.9M | } else if (serialize_func_ != nullptr) { |
1171 | 2.88M | const void* opt_addr = GetOffset(opt_ptr); |
1172 | 2.88M | return serialize_func_(config_options, opt_name, opt_addr, opt_value); |
1173 | 25.0M | } else if (IsCustomizable()) { |
1174 | 1.63M | const Customizable* custom = AsRawPointer<Customizable>(opt_ptr); |
1175 | 1.63M | opt_value->clear(); |
1176 | 1.63M | if (custom == nullptr) { |
1177 | | // We do not have a custom object to serialize. |
1178 | | // If the option is not mutable and we are doing only mutable options, |
1179 | | // we return an empty string (which will cause the option not to be |
1180 | | // printed). Otherwise, we return the "nullptr" string, which will result |
1181 | | // in "option=nullptr" being printed. |
1182 | 1.24M | if (IsMutable() || !config_options.mutable_options_only) { |
1183 | 1.24M | *opt_value = kNullptrString; |
1184 | 1.24M | } else { |
1185 | 0 | *opt_value = ""; |
1186 | 0 | } |
1187 | 1.24M | } else if (IsEnabled(OptionTypeFlags::kStringNameOnly) && |
1188 | 110k | !config_options.IsDetailed()) { |
1189 | 55.0k | if (!config_options.mutable_options_only || IsMutable()) { |
1190 | 55.0k | *opt_value = custom->GetId(); |
1191 | 55.0k | } |
1192 | 330k | } else { |
1193 | 330k | ConfigOptions embedded = config_options; |
1194 | 330k | embedded.delimiter = ";"; |
1195 | | // If this option is mutable, everything inside it should be considered |
1196 | | // mutable |
1197 | 330k | if (IsMutable()) { |
1198 | 55.0k | embedded.mutable_options_only = false; |
1199 | 55.0k | } |
1200 | 330k | std::string value = custom->ToString(embedded); |
1201 | 330k | if (!embedded.mutable_options_only || |
1202 | 330k | value.find('=') != std::string::npos) { |
1203 | 330k | *opt_value = value; |
1204 | 330k | } else { |
1205 | 0 | *opt_value = ""; |
1206 | 0 | } |
1207 | 330k | } |
1208 | 1.63M | return Status::OK(); |
1209 | 23.4M | } else if (IsConfigurable()) { |
1210 | 0 | const Configurable* config = AsRawPointer<Configurable>(opt_ptr); |
1211 | 0 | if (config != nullptr) { |
1212 | 0 | ConfigOptions embedded = config_options; |
1213 | 0 | embedded.delimiter = ";"; |
1214 | 0 | *opt_value = config->ToString(embedded); |
1215 | 0 | } |
1216 | 0 | return Status::OK(); |
1217 | 23.4M | } else if (config_options.mutable_options_only && !IsMutable()) { |
1218 | 0 | return Status::OK(); |
1219 | 23.4M | } else if (SerializeSingleOptionHelper(GetOffset(opt_ptr), type_, |
1220 | 23.4M | opt_value)) { |
1221 | 23.4M | return Status::OK(); |
1222 | 23.4M | } else { |
1223 | 0 | return Status::InvalidArgument("Cannot serialize option: ", opt_name); |
1224 | 0 | } |
1225 | 27.9M | } |
1226 | | |
1227 | | Status OptionTypeInfo::SerializeType( |
1228 | | const ConfigOptions& config_options, |
1229 | | const std::unordered_map<std::string, OptionTypeInfo>& type_map, |
1230 | 605k | const void* opt_addr, std::string* result) { |
1231 | 605k | Status status; |
1232 | 4.78M | for (const auto& iter : type_map) { |
1233 | 4.78M | std::string single; |
1234 | 4.78M | const auto& opt_info = iter.second; |
1235 | 4.78M | if (opt_info.ShouldSerialize()) { |
1236 | 4.67M | status = |
1237 | 4.67M | opt_info.Serialize(config_options, iter.first, opt_addr, &single); |
1238 | 4.67M | if (!status.ok()) { |
1239 | 0 | return status; |
1240 | 4.67M | } else { |
1241 | 4.67M | result->append(iter.first + "=" + single + config_options.delimiter); |
1242 | 4.67M | } |
1243 | 4.67M | } |
1244 | 4.78M | } |
1245 | 605k | return status; |
1246 | 605k | } |
1247 | | |
1248 | | Status OptionTypeInfo::SerializeStruct( |
1249 | | const ConfigOptions& config_options, const std::string& struct_name, |
1250 | | const std::unordered_map<std::string, OptionTypeInfo>* struct_map, |
1251 | 605k | const std::string& opt_name, const void* opt_addr, std::string* value) { |
1252 | 605k | assert(struct_map); |
1253 | 605k | Status status; |
1254 | 605k | if (EndsWith(opt_name, struct_name)) { |
1255 | | // We are going to write the struct as "{ prop1=value1; prop2=value2;}. |
1256 | | // Set the delimiter to ";" so that the everything will be on one line. |
1257 | 605k | ConfigOptions embedded = config_options; |
1258 | 605k | embedded.delimiter = ";"; |
1259 | | |
1260 | | // This option represents the entire struct |
1261 | 605k | std::string result; |
1262 | 605k | status = SerializeType(embedded, *struct_map, opt_addr, &result); |
1263 | 605k | if (!status.ok()) { |
1264 | 0 | return status; |
1265 | 605k | } else { |
1266 | 605k | *value = "{" + result + "}"; |
1267 | 605k | } |
1268 | 605k | } else if (StartsWith(opt_name, struct_name + ".")) { |
1269 | | // This option represents a nested field in the struct (e.g, struct.field) |
1270 | 0 | std::string elem_name; |
1271 | 0 | const auto opt_info = |
1272 | 0 | Find(opt_name.substr(struct_name.size() + 1), *struct_map, &elem_name); |
1273 | 0 | if (opt_info != nullptr) { |
1274 | 0 | status = opt_info->Serialize(config_options, elem_name, opt_addr, value); |
1275 | 0 | } else { |
1276 | 0 | status = Status::InvalidArgument("Unrecognized option", opt_name); |
1277 | 0 | } |
1278 | 0 | } else { |
1279 | | // This option represents a field in the struct (e.g. field) |
1280 | 0 | std::string elem_name; |
1281 | 0 | const auto opt_info = Find(opt_name, *struct_map, &elem_name); |
1282 | 0 | if (opt_info == nullptr) { |
1283 | 0 | status = Status::InvalidArgument("Unrecognized option", opt_name); |
1284 | 0 | } else if (opt_info->ShouldSerialize()) { |
1285 | 0 | status = opt_info->Serialize(config_options, opt_name + "." + elem_name, |
1286 | 0 | opt_addr, value); |
1287 | 0 | } |
1288 | 0 | } |
1289 | 605k | return status; |
1290 | 605k | } |
1291 | | |
1292 | | template <typename T> |
1293 | 6.69M | bool IsOptionEqual(const void* offset1, const void* offset2) { |
1294 | 6.69M | return (*static_cast<const T*>(offset1) == *static_cast<const T*>(offset2)); |
1295 | 6.69M | } bool rocksdb::IsOptionEqual<bool>(void const*, void const*) Line | Count | Source | 1293 | 3.64M | bool IsOptionEqual(const void* offset1, const void* offset2) { | 1294 | 3.64M | return (*static_cast<const T*>(offset1) == *static_cast<const T*>(offset2)); | 1295 | 3.64M | } |
bool rocksdb::IsOptionEqual<int>(void const*, void const*) Line | Count | Source | 1293 | 1.39M | bool IsOptionEqual(const void* offset1, const void* offset2) { | 1294 | 1.39M | return (*static_cast<const T*>(offset1) == *static_cast<const T*>(offset2)); | 1295 | 1.39M | } |
bool rocksdb::IsOptionEqual<unsigned int>(void const*, void const*) Line | Count | Source | 1293 | 882k | bool IsOptionEqual(const void* offset1, const void* offset2) { | 1294 | 882k | return (*static_cast<const T*>(offset1) == *static_cast<const T*>(offset2)); | 1295 | 882k | } |
bool rocksdb::IsOptionEqual<unsigned char>(void const*, void const*) Line | Count | Source | 1293 | 55.0k | bool IsOptionEqual(const void* offset1, const void* offset2) { | 1294 | 55.0k | return (*static_cast<const T*>(offset1) == *static_cast<const T*>(offset2)); | 1295 | 55.0k | } |
Unexecuted instantiation: bool rocksdb::IsOptionEqual<std::__1::atomic<int> >(void const*, void const*) bool rocksdb::IsOptionEqual<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(void const*, void const*) Line | Count | Source | 1293 | 112k | bool IsOptionEqual(const void* offset1, const void* offset2) { | 1294 | 112k | return (*static_cast<const T*>(offset1) == *static_cast<const T*>(offset2)); | 1295 | 112k | } |
bool rocksdb::IsOptionEqual<rocksdb::CompactionStyle>(void const*, void const*) Line | Count | Source | 1293 | 55.0k | bool IsOptionEqual(const void* offset1, const void* offset2) { | 1294 | 55.0k | return (*static_cast<const T*>(offset1) == *static_cast<const T*>(offset2)); | 1295 | 55.0k | } |
bool rocksdb::IsOptionEqual<rocksdb::CompactionStopStyle>(void const*, void const*) Line | Count | Source | 1293 | 55.0k | bool IsOptionEqual(const void* offset1, const void* offset2) { | 1294 | 55.0k | return (*static_cast<const T*>(offset1) == *static_cast<const T*>(offset2)); | 1295 | 55.0k | } |
bool rocksdb::IsOptionEqual<rocksdb::CompactionPri>(void const*, void const*) Line | Count | Source | 1293 | 55.0k | bool IsOptionEqual(const void* offset1, const void* offset2) { | 1294 | 55.0k | return (*static_cast<const T*>(offset1) == *static_cast<const T*>(offset2)); | 1295 | 55.0k | } |
bool rocksdb::IsOptionEqual<rocksdb::CompressionType>(void const*, void const*) Line | Count | Source | 1293 | 202k | bool IsOptionEqual(const void* offset1, const void* offset2) { | 1294 | 202k | return (*static_cast<const T*>(offset1) == *static_cast<const T*>(offset2)); | 1295 | 202k | } |
bool rocksdb::IsOptionEqual<rocksdb::ChecksumType>(void const*, void const*) Line | Count | Source | 1293 | 55.0k | bool IsOptionEqual(const void* offset1, const void* offset2) { | 1294 | 55.0k | return (*static_cast<const T*>(offset1) == *static_cast<const T*>(offset2)); | 1295 | 55.0k | } |
Unexecuted instantiation: bool rocksdb::IsOptionEqual<rocksdb::EncodingType>(void const*, void const*) bool rocksdb::IsOptionEqual<rocksdb::Temperature>(void const*, void const*) Line | Count | Source | 1293 | 184k | bool IsOptionEqual(const void* offset1, const void* offset2) { | 1294 | 184k | return (*static_cast<const T*>(offset1) == *static_cast<const T*>(offset2)); | 1295 | 184k | } |
|
1296 | | |
1297 | 330k | static bool AreEqualDoubles(const double a, const double b) { |
1298 | 330k | return (fabs(a - b) < 0.00001); |
1299 | 330k | } |
1300 | | |
1301 | | static bool AreOptionsEqual(OptionType type, const void* this_offset, |
1302 | 10.3M | const void* that_offset) { |
1303 | 10.3M | switch (type) { |
1304 | 3.64M | case OptionType::kBoolean: |
1305 | 3.64M | return IsOptionEqual<bool>(this_offset, that_offset); |
1306 | 1.39M | case OptionType::kInt: |
1307 | 1.39M | return IsOptionEqual<int>(this_offset, that_offset); |
1308 | 294k | case OptionType::kUInt: |
1309 | 294k | return IsOptionEqual<unsigned int>(this_offset, that_offset); |
1310 | 0 | case OptionType::kInt32T: |
1311 | 0 | return IsOptionEqual<int32_t>(this_offset, that_offset); |
1312 | 55.0k | case OptionType::kInt64T: { |
1313 | 55.0k | int64_t v1, v2; |
1314 | 55.0k | GetUnaligned(static_cast<const int64_t*>(this_offset), &v1); |
1315 | 55.0k | GetUnaligned(static_cast<const int64_t*>(that_offset), &v2); |
1316 | 55.0k | return (v1 == v2); |
1317 | 0 | } |
1318 | 55.0k | case OptionType::kUInt8T: |
1319 | 55.0k | return IsOptionEqual<uint8_t>(this_offset, that_offset); |
1320 | 587k | case OptionType::kUInt32T: |
1321 | 587k | return IsOptionEqual<uint32_t>(this_offset, that_offset); |
1322 | 1.60M | case OptionType::kUInt64T: { |
1323 | 1.60M | uint64_t v1, v2; |
1324 | 1.60M | GetUnaligned(static_cast<const uint64_t*>(this_offset), &v1); |
1325 | 1.60M | GetUnaligned(static_cast<const uint64_t*>(that_offset), &v2); |
1326 | 1.60M | return (v1 == v2); |
1327 | 0 | } |
1328 | 978k | case OptionType::kSizeT: { |
1329 | 978k | size_t v1, v2; |
1330 | 978k | GetUnaligned(static_cast<const size_t*>(this_offset), &v1); |
1331 | 978k | GetUnaligned(static_cast<const size_t*>(that_offset), &v2); |
1332 | 978k | return (v1 == v2); |
1333 | 0 | } |
1334 | 0 | case OptionType::kAtomicInt: |
1335 | 0 | return IsOptionEqual<std::atomic<int>>(this_offset, that_offset); |
1336 | 112k | case OptionType::kString: |
1337 | 112k | return IsOptionEqual<std::string>(this_offset, that_offset); |
1338 | 330k | case OptionType::kDouble: |
1339 | 330k | return AreEqualDoubles(*static_cast<const double*>(this_offset), |
1340 | 330k | *static_cast<const double*>(that_offset)); |
1341 | 55.0k | case OptionType::kCompactionStyle: |
1342 | 55.0k | return IsOptionEqual<CompactionStyle>(this_offset, that_offset); |
1343 | 55.0k | case OptionType::kCompactionStopStyle: |
1344 | 55.0k | return IsOptionEqual<CompactionStopStyle>(this_offset, that_offset); |
1345 | 55.0k | case OptionType::kCompactionPri: |
1346 | 55.0k | return IsOptionEqual<CompactionPri>(this_offset, that_offset); |
1347 | 202k | case OptionType::kCompressionType: |
1348 | 202k | return IsOptionEqual<CompressionType>(this_offset, that_offset); |
1349 | 55.0k | case OptionType::kChecksumType: |
1350 | 55.0k | return IsOptionEqual<ChecksumType>(this_offset, that_offset); |
1351 | 0 | case OptionType::kEncodingType: |
1352 | 0 | return IsOptionEqual<EncodingType>(this_offset, that_offset); |
1353 | 0 | case OptionType::kEncodedString: |
1354 | 0 | return IsOptionEqual<std::string>(this_offset, that_offset); |
1355 | 184k | case OptionType::kTemperature: |
1356 | 184k | return IsOptionEqual<Temperature>(this_offset, that_offset); |
1357 | 697k | default: |
1358 | 697k | return false; |
1359 | 10.3M | } // End switch |
1360 | 10.3M | } |
1361 | | |
1362 | | bool OptionTypeInfo::AreEqual(const ConfigOptions& config_options, |
1363 | | const std::string& opt_name, |
1364 | | const void* const this_ptr, |
1365 | | const void* const that_ptr, |
1366 | 11.4M | std::string* mismatch) const { |
1367 | 11.4M | auto level = GetSanityLevel(); |
1368 | 11.4M | if (!config_options.IsCheckEnabled(level)) { |
1369 | 55.0k | return true; // If the sanity level is not being checked, skip it |
1370 | 55.0k | } |
1371 | 11.3M | if (this_ptr == nullptr || that_ptr == nullptr) { |
1372 | 0 | if (this_ptr == that_ptr) { |
1373 | 0 | return true; |
1374 | 0 | } |
1375 | 11.3M | } else if (equals_func_ != nullptr) { |
1376 | 992k | const void* this_addr = GetOffset(this_ptr); |
1377 | 992k | const void* that_addr = GetOffset(that_ptr); |
1378 | 992k | if (equals_func_(config_options, opt_name, this_addr, that_addr, |
1379 | 992k | mismatch)) { |
1380 | 992k | return true; |
1381 | 992k | } |
1382 | 10.3M | } else { |
1383 | 10.3M | const void* this_addr = GetOffset(this_ptr); |
1384 | 10.3M | const void* that_addr = GetOffset(that_ptr); |
1385 | 10.3M | if (AreOptionsEqual(type_, this_addr, that_addr)) { |
1386 | 9.66M | return true; |
1387 | 9.66M | } else if (IsConfigurable()) { |
1388 | 697k | const auto* this_config = AsRawPointer<Configurable>(this_ptr); |
1389 | 697k | const auto* that_config = AsRawPointer<Configurable>(that_ptr); |
1390 | 697k | if (this_config == that_config) { |
1391 | 587k | return true; |
1392 | 587k | } else if (this_config != nullptr && that_config != nullptr) { |
1393 | 110k | std::string bad_name; |
1394 | 110k | bool matches; |
1395 | 110k | if (level < config_options.sanity_level) { |
1396 | 55.0k | ConfigOptions copy = config_options; |
1397 | 55.0k | copy.sanity_level = level; |
1398 | 55.0k | matches = this_config->AreEquivalent(copy, that_config, &bad_name); |
1399 | 55.0k | } else { |
1400 | 55.0k | matches = this_config->AreEquivalent(config_options, that_config, |
1401 | 55.0k | &bad_name); |
1402 | 55.0k | } |
1403 | 110k | if (!matches) { |
1404 | 0 | *mismatch = opt_name + "." + bad_name; |
1405 | 0 | } |
1406 | 110k | return matches; |
1407 | 110k | } |
1408 | 697k | } |
1409 | 10.3M | } |
1410 | 0 | if (mismatch->empty()) { |
1411 | 0 | *mismatch = opt_name; |
1412 | 0 | } |
1413 | 0 | return false; |
1414 | 11.3M | } |
1415 | | |
1416 | | bool OptionTypeInfo::TypesAreEqual( |
1417 | | const ConfigOptions& config_options, |
1418 | | const std::unordered_map<std::string, OptionTypeInfo>& type_map, |
1419 | 165k | const void* this_addr, const void* that_addr, std::string* mismatch) { |
1420 | 1.10M | for (const auto& iter : type_map) { |
1421 | 1.10M | const auto& opt_info = iter.second; |
1422 | 1.10M | if (!opt_info.AreEqual(config_options, iter.first, this_addr, that_addr, |
1423 | 1.10M | mismatch)) { |
1424 | 0 | return false; |
1425 | 0 | } |
1426 | 1.10M | } |
1427 | 165k | return true; |
1428 | 165k | } |
1429 | | |
1430 | | bool OptionTypeInfo::StructsAreEqual( |
1431 | | const ConfigOptions& config_options, const std::string& struct_name, |
1432 | | const std::unordered_map<std::string, OptionTypeInfo>* struct_map, |
1433 | | const std::string& opt_name, const void* this_addr, const void* that_addr, |
1434 | 165k | std::string* mismatch) { |
1435 | 165k | assert(struct_map); |
1436 | 165k | bool matches = true; |
1437 | 165k | std::string result; |
1438 | 165k | if (EndsWith(opt_name, struct_name)) { |
1439 | | // This option represents the entire struct |
1440 | 165k | matches = TypesAreEqual(config_options, *struct_map, this_addr, that_addr, |
1441 | 165k | &result); |
1442 | 165k | if (!matches) { |
1443 | 0 | *mismatch = struct_name + "." + result; |
1444 | 0 | return false; |
1445 | 0 | } |
1446 | 165k | } else if (StartsWith(opt_name, struct_name + ".")) { |
1447 | | // This option represents a nested field in the struct (e.g, struct.field) |
1448 | 0 | std::string elem_name; |
1449 | 0 | const auto opt_info = |
1450 | 0 | Find(opt_name.substr(struct_name.size() + 1), *struct_map, &elem_name); |
1451 | 0 | assert(opt_info); |
1452 | 0 | if (opt_info == nullptr) { |
1453 | 0 | *mismatch = opt_name; |
1454 | 0 | matches = false; |
1455 | 0 | } else if (!opt_info->AreEqual(config_options, elem_name, this_addr, |
1456 | 0 | that_addr, &result)) { |
1457 | 0 | matches = false; |
1458 | 0 | *mismatch = struct_name + "." + result; |
1459 | 0 | } |
1460 | 0 | } else { |
1461 | | // This option represents a field in the struct (e.g. field) |
1462 | 0 | std::string elem_name; |
1463 | 0 | const auto opt_info = Find(opt_name, *struct_map, &elem_name); |
1464 | 0 | assert(opt_info); |
1465 | 0 | if (opt_info == nullptr) { |
1466 | 0 | *mismatch = struct_name + "." + opt_name; |
1467 | 0 | matches = false; |
1468 | 0 | } else if (!opt_info->AreEqual(config_options, elem_name, this_addr, |
1469 | 0 | that_addr, &result)) { |
1470 | 0 | matches = false; |
1471 | 0 | *mismatch = struct_name + "." + result; |
1472 | 0 | } |
1473 | 0 | } |
1474 | 165k | return matches; |
1475 | 165k | } |
1476 | | |
1477 | | bool MatchesOptionsTypeFromMap( |
1478 | | const ConfigOptions& config_options, |
1479 | | const std::unordered_map<std::string, OptionTypeInfo>& type_map, |
1480 | | const void* const this_ptr, const void* const that_ptr, |
1481 | 0 | std::string* mismatch) { |
1482 | 0 | for (auto& pair : type_map) { |
1483 | | // We skip checking deprecated variables as they might |
1484 | | // contain random values since they might not be initialized |
1485 | 0 | if (config_options.IsCheckEnabled(pair.second.GetSanityLevel())) { |
1486 | 0 | if (!pair.second.AreEqual(config_options, pair.first, this_ptr, that_ptr, |
1487 | 0 | mismatch) && |
1488 | 0 | !pair.second.AreEqualByName(config_options, pair.first, this_ptr, |
1489 | 0 | that_ptr)) { |
1490 | 0 | return false; |
1491 | 0 | } |
1492 | 0 | } |
1493 | 0 | } |
1494 | 0 | return true; |
1495 | 0 | } |
1496 | | |
1497 | | bool OptionTypeInfo::AreEqualByName(const ConfigOptions& config_options, |
1498 | | const std::string& opt_name, |
1499 | | const void* const this_ptr, |
1500 | 0 | const void* const that_ptr) const { |
1501 | 0 | if (IsByName()) { |
1502 | 0 | std::string that_value; |
1503 | 0 | if (Serialize(config_options, opt_name, that_ptr, &that_value).ok()) { |
1504 | 0 | return AreEqualByName(config_options, opt_name, this_ptr, that_value); |
1505 | 0 | } |
1506 | 0 | } |
1507 | 0 | return false; |
1508 | 0 | } |
1509 | | |
1510 | | bool OptionTypeInfo::AreEqualByName(const ConfigOptions& config_options, |
1511 | | const std::string& opt_name, |
1512 | | const void* const opt_ptr, |
1513 | 0 | const std::string& that_value) const { |
1514 | 0 | std::string this_value; |
1515 | 0 | if (!IsByName()) { |
1516 | 0 | return false; |
1517 | 0 | } else if (!Serialize(config_options, opt_name, opt_ptr, &this_value).ok()) { |
1518 | 0 | return false; |
1519 | 0 | } else if (IsEnabled(OptionVerificationType::kByNameAllowFromNull)) { |
1520 | 0 | if (that_value == kNullptrString) { |
1521 | 0 | return true; |
1522 | 0 | } |
1523 | 0 | } else if (IsEnabled(OptionVerificationType::kByNameAllowNull)) { |
1524 | 0 | if (that_value == kNullptrString) { |
1525 | 0 | return true; |
1526 | 0 | } |
1527 | 0 | } |
1528 | 0 | return (this_value == that_value); |
1529 | 0 | } |
1530 | | |
1531 | | Status OptionTypeInfo::Prepare(const ConfigOptions& config_options, |
1532 | 644k | const std::string& name, void* opt_ptr) const { |
1533 | 644k | if (ShouldPrepare()) { |
1534 | 644k | if (prepare_func_ != nullptr) { |
1535 | 37.3k | void* opt_addr = GetOffset(opt_ptr); |
1536 | 37.3k | return prepare_func_(config_options, name, opt_addr); |
1537 | 607k | } else if (IsConfigurable()) { |
1538 | 607k | Configurable* config = AsRawPointer<Configurable>(opt_ptr); |
1539 | 607k | if (config != nullptr) { |
1540 | 110k | return config->PrepareOptions(config_options); |
1541 | 497k | } else if (!CanBeNull()) { |
1542 | 0 | return Status::NotFound("Missing configurable object", name); |
1543 | 0 | } |
1544 | 607k | } |
1545 | 644k | } |
1546 | 497k | return Status::OK(); |
1547 | 644k | } |
1548 | | |
1549 | | Status OptionTypeInfo::Validate(const DBOptions& db_opts, |
1550 | | const ColumnFamilyOptions& cf_opts, |
1551 | | const std::string& name, |
1552 | 485k | const void* opt_ptr) const { |
1553 | 485k | if (ShouldValidate()) { |
1554 | 485k | if (validate_func_ != nullptr) { |
1555 | 28.5k | const void* opt_addr = GetOffset(opt_ptr); |
1556 | 28.5k | return validate_func_(db_opts, cf_opts, name, opt_addr); |
1557 | 456k | } else if (IsConfigurable()) { |
1558 | 456k | const Configurable* config = AsRawPointer<Configurable>(opt_ptr); |
1559 | 456k | if (config != nullptr) { |
1560 | 114k | return config->ValidateOptions(db_opts, cf_opts); |
1561 | 342k | } else if (!CanBeNull()) { |
1562 | 0 | return Status::NotFound("Missing configurable object", name); |
1563 | 0 | } |
1564 | 456k | } |
1565 | 485k | } |
1566 | 342k | return Status::OK(); |
1567 | 485k | } |
1568 | | |
1569 | | const OptionTypeInfo* OptionTypeInfo::Find( |
1570 | | const std::string& opt_name, |
1571 | | const std::unordered_map<std::string, OptionTypeInfo>& opt_map, |
1572 | 19.5M | std::string* elem_name) { |
1573 | 19.5M | const auto iter = opt_map.find(opt_name); // Look up the value in the map |
1574 | 19.5M | if (iter != opt_map.end()) { // Found the option in the map |
1575 | 12.2M | *elem_name = opt_name; // Return the name |
1576 | 12.2M | return &(iter->second); // Return the contents of the iterator |
1577 | 12.2M | } else { |
1578 | 7.39M | auto idx = opt_name.find('.'); // Look for a separator |
1579 | 7.39M | if (idx > 0 && idx != std::string::npos) { // We found a separator |
1580 | 0 | auto siter = |
1581 | 0 | opt_map.find(opt_name.substr(0, idx)); // Look for the short name |
1582 | 0 | if (siter != opt_map.end()) { // We found the short name |
1583 | 0 | if (siter->second.IsStruct() || // If the object is a struct |
1584 | 0 | siter->second.IsConfigurable()) { // or a Configurable |
1585 | 0 | *elem_name = opt_name.substr(idx + 1); // Return the rest |
1586 | 0 | return &(siter->second); // Return the contents of the iterator |
1587 | 0 | } |
1588 | 0 | } |
1589 | 0 | } |
1590 | 7.39M | } |
1591 | 7.39M | return nullptr; |
1592 | 19.5M | } |
1593 | | |
1594 | | } // namespace ROCKSDB_NAMESPACE |