summaryrefslogtreecommitdiffstats
path: root/src/rocksdb/options/cf_options.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/rocksdb/options/cf_options.cc1166
1 files changed, 1166 insertions, 0 deletions
diff --git a/src/rocksdb/options/cf_options.cc b/src/rocksdb/options/cf_options.cc
new file mode 100644
index 000000000..dbf0bf9b0
--- /dev/null
+++ b/src/rocksdb/options/cf_options.cc
@@ -0,0 +1,1166 @@
+// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
+// This source code is licensed under both the GPLv2 (found in the
+// COPYING file in the root directory) and Apache 2.0 License
+// (found in the LICENSE.Apache file in the root directory).
+
+#include "options/cf_options.h"
+
+#include <cassert>
+#include <cinttypes>
+#include <limits>
+#include <string>
+
+#include "logging/logging.h"
+#include "options/configurable_helper.h"
+#include "options/db_options.h"
+#include "options/options_helper.h"
+#include "options/options_parser.h"
+#include "port/port.h"
+#include "rocksdb/compaction_filter.h"
+#include "rocksdb/concurrent_task_limiter.h"
+#include "rocksdb/configurable.h"
+#include "rocksdb/convenience.h"
+#include "rocksdb/env.h"
+#include "rocksdb/file_system.h"
+#include "rocksdb/merge_operator.h"
+#include "rocksdb/options.h"
+#include "rocksdb/table.h"
+#include "rocksdb/utilities/object_registry.h"
+#include "rocksdb/utilities/options_type.h"
+#include "util/cast_util.h"
+
+// NOTE: in this file, many option flags that were deprecated
+// and removed from the rest of the code have to be kept here
+// and marked as kDeprecated in order to be able to read old
+// OPTIONS files.
+
+namespace ROCKSDB_NAMESPACE {
+
+#ifndef ROCKSDB_LITE
+static Status ParseCompressionOptions(const std::string& value,
+ const std::string& name,
+ CompressionOptions& compression_opts) {
+ const char kDelimiter = ':';
+ std::istringstream field_stream(value);
+ std::string field;
+
+ if (!std::getline(field_stream, field, kDelimiter)) {
+ return Status::InvalidArgument("unable to parse the specified CF option " +
+ name);
+ }
+ compression_opts.window_bits = ParseInt(field);
+
+ if (!std::getline(field_stream, field, kDelimiter)) {
+ return Status::InvalidArgument("unable to parse the specified CF option " +
+ name);
+ }
+ compression_opts.level = ParseInt(field);
+
+ if (!std::getline(field_stream, field, kDelimiter)) {
+ return Status::InvalidArgument("unable to parse the specified CF option " +
+ name);
+ }
+ compression_opts.strategy = ParseInt(field);
+
+ // max_dict_bytes is optional for backwards compatibility
+ if (!field_stream.eof()) {
+ if (!std::getline(field_stream, field, kDelimiter)) {
+ return Status::InvalidArgument(
+ "unable to parse the specified CF option " + name);
+ }
+ compression_opts.max_dict_bytes = ParseInt(field);
+ }
+
+ // zstd_max_train_bytes is optional for backwards compatibility
+ if (!field_stream.eof()) {
+ if (!std::getline(field_stream, field, kDelimiter)) {
+ return Status::InvalidArgument(
+ "unable to parse the specified CF option " + name);
+ }
+ compression_opts.zstd_max_train_bytes = ParseInt(field);
+ }
+
+ // parallel_threads is optional for backwards compatibility
+ if (!field_stream.eof()) {
+ if (!std::getline(field_stream, field, kDelimiter)) {
+ return Status::InvalidArgument(
+ "unable to parse the specified CF option " + name);
+ }
+ // Since parallel_threads comes before enabled but was added optionally
+ // later, we need to check if this is the final token (meaning it is the
+ // enabled bit), or if there are more tokens (meaning this one is
+ // parallel_threads).
+ if (!field_stream.eof()) {
+ compression_opts.parallel_threads = ParseInt(field);
+ } else {
+ // parallel_threads is not serialized with this format, but enabled is
+ compression_opts.enabled = ParseBoolean("", field);
+ }
+ }
+
+ // enabled is optional for backwards compatibility
+ if (!field_stream.eof()) {
+ if (!std::getline(field_stream, field, kDelimiter)) {
+ return Status::InvalidArgument(
+ "unable to parse the specified CF option " + name);
+ }
+ compression_opts.enabled = ParseBoolean("", field);
+ }
+
+ // max_dict_buffer_bytes is optional for backwards compatibility
+ if (!field_stream.eof()) {
+ if (!std::getline(field_stream, field, kDelimiter)) {
+ return Status::InvalidArgument(
+ "unable to parse the specified CF option " + name);
+ }
+ compression_opts.max_dict_buffer_bytes = ParseUint64(field);
+ }
+
+ // use_zstd_dict_trainer is optional for backwards compatibility
+ if (!field_stream.eof()) {
+ if (!std::getline(field_stream, field, kDelimiter)) {
+ return Status::InvalidArgument(
+ "unable to parse the specified CF option " + name);
+ }
+ compression_opts.use_zstd_dict_trainer = ParseBoolean("", field);
+ }
+
+ if (!field_stream.eof()) {
+ return Status::InvalidArgument("unable to parse the specified CF option " +
+ name);
+ }
+ return Status::OK();
+}
+
+const std::string kOptNameBMCompOpts = "bottommost_compression_opts";
+const std::string kOptNameCompOpts = "compression_opts";
+
+// OptionTypeInfo map for CompressionOptions
+static std::unordered_map<std::string, OptionTypeInfo>
+ compression_options_type_info = {
+ {"window_bits",
+ {offsetof(struct CompressionOptions, window_bits), OptionType::kInt,
+ OptionVerificationType::kNormal, OptionTypeFlags::kMutable}},
+ {"level",
+ {offsetof(struct CompressionOptions, level), OptionType::kInt,
+ OptionVerificationType::kNormal, OptionTypeFlags::kMutable}},
+ {"strategy",
+ {offsetof(struct CompressionOptions, strategy), OptionType::kInt,
+ OptionVerificationType::kNormal, OptionTypeFlags::kMutable}},
+ {"max_dict_bytes",
+ {offsetof(struct CompressionOptions, max_dict_bytes), OptionType::kInt,
+ OptionVerificationType::kNormal, OptionTypeFlags::kMutable}},
+ {"zstd_max_train_bytes",
+ {offsetof(struct CompressionOptions, zstd_max_train_bytes),
+ OptionType::kUInt32T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"parallel_threads",
+ {offsetof(struct CompressionOptions, parallel_threads),
+ OptionType::kUInt32T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"enabled",
+ {offsetof(struct CompressionOptions, enabled), OptionType::kBoolean,
+ OptionVerificationType::kNormal, OptionTypeFlags::kMutable}},
+ {"max_dict_buffer_bytes",
+ {offsetof(struct CompressionOptions, max_dict_buffer_bytes),
+ OptionType::kUInt64T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"use_zstd_dict_trainer",
+ {offsetof(struct CompressionOptions, use_zstd_dict_trainer),
+ OptionType::kBoolean, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+};
+
+static std::unordered_map<std::string, OptionTypeInfo>
+ fifo_compaction_options_type_info = {
+ {"max_table_files_size",
+ {offsetof(struct CompactionOptionsFIFO, max_table_files_size),
+ OptionType::kUInt64T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"age_for_warm",
+ {offsetof(struct CompactionOptionsFIFO, age_for_warm),
+ OptionType::kUInt64T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"ttl",
+ {0, OptionType::kUInt64T, OptionVerificationType::kDeprecated,
+ OptionTypeFlags::kNone}},
+ {"allow_compaction",
+ {offsetof(struct CompactionOptionsFIFO, allow_compaction),
+ OptionType::kBoolean, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+};
+
+static std::unordered_map<std::string, OptionTypeInfo>
+ universal_compaction_options_type_info = {
+ {"size_ratio",
+ {offsetof(class CompactionOptionsUniversal, size_ratio),
+ OptionType::kUInt, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"min_merge_width",
+ {offsetof(class CompactionOptionsUniversal, min_merge_width),
+ OptionType::kUInt, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"max_merge_width",
+ {offsetof(class CompactionOptionsUniversal, max_merge_width),
+ OptionType::kUInt, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"max_size_amplification_percent",
+ {offsetof(class CompactionOptionsUniversal,
+ max_size_amplification_percent),
+ OptionType::kUInt, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"compression_size_percent",
+ {offsetof(class CompactionOptionsUniversal, compression_size_percent),
+ OptionType::kInt, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"stop_style",
+ {offsetof(class CompactionOptionsUniversal, stop_style),
+ OptionType::kCompactionStopStyle, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"incremental",
+ {offsetof(class CompactionOptionsUniversal, incremental),
+ OptionType::kBoolean, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"allow_trivial_move",
+ {offsetof(class CompactionOptionsUniversal, allow_trivial_move),
+ OptionType::kBoolean, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}}};
+
+static std::unordered_map<std::string, OptionTypeInfo>
+ cf_mutable_options_type_info = {
+ {"report_bg_io_stats",
+ {offsetof(struct MutableCFOptions, report_bg_io_stats),
+ OptionType::kBoolean, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"disable_auto_compactions",
+ {offsetof(struct MutableCFOptions, disable_auto_compactions),
+ OptionType::kBoolean, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"filter_deletes",
+ {0, OptionType::kBoolean, OptionVerificationType::kDeprecated,
+ OptionTypeFlags::kMutable}},
+ {"check_flush_compaction_key_order",
+ {offsetof(struct MutableCFOptions, check_flush_compaction_key_order),
+ OptionType::kBoolean, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"paranoid_file_checks",
+ {offsetof(struct MutableCFOptions, paranoid_file_checks),
+ OptionType::kBoolean, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"verify_checksums_in_compaction",
+ {0, OptionType::kBoolean, OptionVerificationType::kDeprecated,
+ OptionTypeFlags::kMutable}},
+ {"soft_pending_compaction_bytes_limit",
+ {offsetof(struct MutableCFOptions,
+ soft_pending_compaction_bytes_limit),
+ OptionType::kUInt64T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"hard_pending_compaction_bytes_limit",
+ {offsetof(struct MutableCFOptions,
+ hard_pending_compaction_bytes_limit),
+ OptionType::kUInt64T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"hard_rate_limit",
+ {0, OptionType::kDouble, OptionVerificationType::kDeprecated,
+ OptionTypeFlags::kMutable}},
+ {"soft_rate_limit",
+ {0, OptionType::kDouble, OptionVerificationType::kDeprecated,
+ OptionTypeFlags::kMutable}},
+ {"max_compaction_bytes",
+ {offsetof(struct MutableCFOptions, max_compaction_bytes),
+ OptionType::kUInt64T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"ignore_max_compaction_bytes_for_input",
+ {offsetof(struct MutableCFOptions,
+ ignore_max_compaction_bytes_for_input),
+ OptionType::kBoolean, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"expanded_compaction_factor",
+ {0, OptionType::kInt, OptionVerificationType::kDeprecated,
+ OptionTypeFlags::kMutable}},
+ {"level0_file_num_compaction_trigger",
+ {offsetof(struct MutableCFOptions, level0_file_num_compaction_trigger),
+ OptionType::kInt, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"level0_slowdown_writes_trigger",
+ {offsetof(struct MutableCFOptions, level0_slowdown_writes_trigger),
+ OptionType::kInt, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"level0_stop_writes_trigger",
+ {offsetof(struct MutableCFOptions, level0_stop_writes_trigger),
+ OptionType::kInt, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"max_grandparent_overlap_factor",
+ {0, OptionType::kInt, OptionVerificationType::kDeprecated,
+ OptionTypeFlags::kMutable}},
+ {"max_write_buffer_number",
+ {offsetof(struct MutableCFOptions, max_write_buffer_number),
+ OptionType::kInt, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"source_compaction_factor",
+ {0, OptionType::kInt, OptionVerificationType::kDeprecated,
+ OptionTypeFlags::kMutable}},
+ {"target_file_size_multiplier",
+ {offsetof(struct MutableCFOptions, target_file_size_multiplier),
+ OptionType::kInt, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"arena_block_size",
+ {offsetof(struct MutableCFOptions, arena_block_size),
+ OptionType::kSizeT, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"inplace_update_num_locks",
+ {offsetof(struct MutableCFOptions, inplace_update_num_locks),
+ OptionType::kSizeT, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"max_successive_merges",
+ {offsetof(struct MutableCFOptions, max_successive_merges),
+ OptionType::kSizeT, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"memtable_huge_page_size",
+ {offsetof(struct MutableCFOptions, memtable_huge_page_size),
+ OptionType::kSizeT, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"memtable_prefix_bloom_huge_page_tlb_size",
+ {0, OptionType::kSizeT, OptionVerificationType::kDeprecated,
+ OptionTypeFlags::kMutable}},
+ {"write_buffer_size",
+ {offsetof(struct MutableCFOptions, write_buffer_size),
+ OptionType::kSizeT, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"memtable_prefix_bloom_bits",
+ {0, OptionType::kUInt32T, OptionVerificationType::kDeprecated,
+ OptionTypeFlags::kMutable}},
+ {"memtable_prefix_bloom_size_ratio",
+ {offsetof(struct MutableCFOptions, memtable_prefix_bloom_size_ratio),
+ OptionType::kDouble, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"memtable_prefix_bloom_probes",
+ {0, OptionType::kUInt32T, OptionVerificationType::kDeprecated,
+ OptionTypeFlags::kMutable}},
+ {"memtable_whole_key_filtering",
+ {offsetof(struct MutableCFOptions, memtable_whole_key_filtering),
+ OptionType::kBoolean, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"min_partial_merge_operands",
+ {0, OptionType::kUInt32T, OptionVerificationType::kDeprecated,
+ OptionTypeFlags::kMutable}},
+ {"max_bytes_for_level_base",
+ {offsetof(struct MutableCFOptions, max_bytes_for_level_base),
+ OptionType::kUInt64T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"snap_refresh_nanos",
+ {0, OptionType::kUInt64T, OptionVerificationType::kDeprecated,
+ OptionTypeFlags::kMutable}},
+ {"max_bytes_for_level_multiplier",
+ {offsetof(struct MutableCFOptions, max_bytes_for_level_multiplier),
+ OptionType::kDouble, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"max_bytes_for_level_multiplier_additional",
+ OptionTypeInfo::Vector<int>(
+ offsetof(struct MutableCFOptions,
+ max_bytes_for_level_multiplier_additional),
+ OptionVerificationType::kNormal, OptionTypeFlags::kMutable,
+ {0, OptionType::kInt})},
+ {"max_sequential_skip_in_iterations",
+ {offsetof(struct MutableCFOptions, max_sequential_skip_in_iterations),
+ OptionType::kUInt64T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"target_file_size_base",
+ {offsetof(struct MutableCFOptions, target_file_size_base),
+ OptionType::kUInt64T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"compression",
+ {offsetof(struct MutableCFOptions, compression),
+ OptionType::kCompressionType, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"prefix_extractor",
+ OptionTypeInfo::AsCustomSharedPtr<const SliceTransform>(
+ offsetof(struct MutableCFOptions, prefix_extractor),
+ OptionVerificationType::kByNameAllowNull,
+ (OptionTypeFlags::kMutable | OptionTypeFlags::kAllowNull))},
+ {"compaction_options_fifo",
+ OptionTypeInfo::Struct(
+ "compaction_options_fifo", &fifo_compaction_options_type_info,
+ offsetof(struct MutableCFOptions, compaction_options_fifo),
+ OptionVerificationType::kNormal, OptionTypeFlags::kMutable)
+ .SetParseFunc([](const ConfigOptions& opts,
+ const std::string& name, const std::string& value,
+ void* addr) {
+ // This is to handle backward compatibility, where
+ // compaction_options_fifo could be assigned a single scalar
+ // value, say, like "23", which would be assigned to
+ // max_table_files_size.
+ if (name == "compaction_options_fifo" &&
+ value.find("=") == std::string::npos) {
+ // Old format. Parse just a single uint64_t value.
+ auto options = static_cast<CompactionOptionsFIFO*>(addr);
+ options->max_table_files_size = ParseUint64(value);
+ return Status::OK();
+ } else {
+ return OptionTypeInfo::ParseStruct(
+ opts, "compaction_options_fifo",
+ &fifo_compaction_options_type_info, name, value, addr);
+ }
+ })},
+ {"compaction_options_universal",
+ OptionTypeInfo::Struct(
+ "compaction_options_universal",
+ &universal_compaction_options_type_info,
+ offsetof(struct MutableCFOptions, compaction_options_universal),
+ OptionVerificationType::kNormal, OptionTypeFlags::kMutable)},
+ {"ttl",
+ {offsetof(struct MutableCFOptions, ttl), OptionType::kUInt64T,
+ OptionVerificationType::kNormal, OptionTypeFlags::kMutable}},
+ {"periodic_compaction_seconds",
+ {offsetof(struct MutableCFOptions, periodic_compaction_seconds),
+ OptionType::kUInt64T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"bottommost_temperature",
+ {0, OptionType::kTemperature, OptionVerificationType::kDeprecated,
+ OptionTypeFlags::kMutable}},
+ {"last_level_temperature",
+ {offsetof(struct MutableCFOptions, last_level_temperature),
+ OptionType::kTemperature, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"enable_blob_files",
+ {offsetof(struct MutableCFOptions, enable_blob_files),
+ OptionType::kBoolean, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"min_blob_size",
+ {offsetof(struct MutableCFOptions, min_blob_size),
+ OptionType::kUInt64T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"blob_file_size",
+ {offsetof(struct MutableCFOptions, blob_file_size),
+ OptionType::kUInt64T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"blob_compression_type",
+ {offsetof(struct MutableCFOptions, blob_compression_type),
+ OptionType::kCompressionType, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"enable_blob_garbage_collection",
+ {offsetof(struct MutableCFOptions, enable_blob_garbage_collection),
+ OptionType::kBoolean, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"blob_garbage_collection_age_cutoff",
+ {offsetof(struct MutableCFOptions, blob_garbage_collection_age_cutoff),
+ OptionType::kDouble, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"blob_garbage_collection_force_threshold",
+ {offsetof(struct MutableCFOptions,
+ blob_garbage_collection_force_threshold),
+ OptionType::kDouble, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"blob_compaction_readahead_size",
+ {offsetof(struct MutableCFOptions, blob_compaction_readahead_size),
+ OptionType::kUInt64T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"blob_file_starting_level",
+ {offsetof(struct MutableCFOptions, blob_file_starting_level),
+ OptionType::kInt, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"prepopulate_blob_cache",
+ OptionTypeInfo::Enum<PrepopulateBlobCache>(
+ offsetof(struct MutableCFOptions, prepopulate_blob_cache),
+ &prepopulate_blob_cache_string_map, OptionTypeFlags::kMutable)},
+ {"sample_for_compression",
+ {offsetof(struct MutableCFOptions, sample_for_compression),
+ OptionType::kUInt64T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"bottommost_compression",
+ {offsetof(struct MutableCFOptions, bottommost_compression),
+ OptionType::kCompressionType, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"compression_per_level",
+ OptionTypeInfo::Vector<CompressionType>(
+ offsetof(struct MutableCFOptions, compression_per_level),
+ OptionVerificationType::kNormal, OptionTypeFlags::kMutable,
+ {0, OptionType::kCompressionType})},
+ {"experimental_mempurge_threshold",
+ {offsetof(struct MutableCFOptions, experimental_mempurge_threshold),
+ OptionType::kDouble, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {"memtable_protection_bytes_per_key",
+ {offsetof(struct MutableCFOptions, memtable_protection_bytes_per_key),
+ OptionType::kUInt32T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kMutable}},
+ {kOptNameCompOpts,
+ OptionTypeInfo::Struct(
+ kOptNameCompOpts, &compression_options_type_info,
+ offsetof(struct MutableCFOptions, compression_opts),
+ OptionVerificationType::kNormal,
+ (OptionTypeFlags::kMutable | OptionTypeFlags::kCompareNever),
+ [](const ConfigOptions& opts, const std::string& name,
+ const std::string& value, void* addr) {
+ // This is to handle backward compatibility, where
+ // compression_options was a ":" separated list.
+ if (name == kOptNameCompOpts &&
+ value.find("=") == std::string::npos) {
+ auto* compression = static_cast<CompressionOptions*>(addr);
+ return ParseCompressionOptions(value, name, *compression);
+ } else {
+ return OptionTypeInfo::ParseStruct(
+ opts, kOptNameCompOpts, &compression_options_type_info,
+ name, value, addr);
+ }
+ })},
+ {kOptNameBMCompOpts,
+ OptionTypeInfo::Struct(
+ kOptNameBMCompOpts, &compression_options_type_info,
+ offsetof(struct MutableCFOptions, bottommost_compression_opts),
+ OptionVerificationType::kNormal,
+ (OptionTypeFlags::kMutable | OptionTypeFlags::kCompareNever),
+ [](const ConfigOptions& opts, const std::string& name,
+ const std::string& value, void* addr) {
+ // This is to handle backward compatibility, where
+ // compression_options was a ":" separated list.
+ if (name == kOptNameBMCompOpts &&
+ value.find("=") == std::string::npos) {
+ auto* compression = static_cast<CompressionOptions*>(addr);
+ return ParseCompressionOptions(value, name, *compression);
+ } else {
+ return OptionTypeInfo::ParseStruct(
+ opts, kOptNameBMCompOpts, &compression_options_type_info,
+ name, value, addr);
+ }
+ })},
+ // End special case properties
+};
+
+static std::unordered_map<std::string, OptionTypeInfo>
+ cf_immutable_options_type_info = {
+ /* not yet supported
+ CompressionOptions compression_opts;
+ TablePropertiesCollectorFactories table_properties_collector_factories;
+ using TablePropertiesCollectorFactories =
+ std::vector<std::shared_ptr<TablePropertiesCollectorFactory>>;
+ UpdateStatus (*inplace_callback)(char* existing_value,
+ uint34_t* existing_value_size,
+ Slice delta_value,
+ std::string* merged_value);
+ std::vector<DbPath> cf_paths;
+ */
+ {"compaction_measure_io_stats",
+ {0, OptionType::kBoolean, OptionVerificationType::kDeprecated,
+ OptionTypeFlags::kNone}},
+ {"purge_redundant_kvs_while_flush",
+ {0, OptionType::kBoolean, OptionVerificationType::kDeprecated,
+ OptionTypeFlags::kNone}},
+ {"inplace_update_support",
+ {offsetof(struct ImmutableCFOptions, inplace_update_support),
+ OptionType::kBoolean, OptionVerificationType::kNormal,
+ OptionTypeFlags::kNone}},
+ {"level_compaction_dynamic_level_bytes",
+ {offsetof(struct ImmutableCFOptions,
+ level_compaction_dynamic_level_bytes),
+ OptionType::kBoolean, OptionVerificationType::kNormal,
+ OptionTypeFlags::kNone}},
+ {"level_compaction_dynamic_file_size",
+ {offsetof(struct ImmutableCFOptions,
+ level_compaction_dynamic_file_size),
+ OptionType::kBoolean, OptionVerificationType::kNormal,
+ OptionTypeFlags::kNone}},
+ {"optimize_filters_for_hits",
+ {offsetof(struct ImmutableCFOptions, optimize_filters_for_hits),
+ OptionType::kBoolean, OptionVerificationType::kNormal,
+ OptionTypeFlags::kNone}},
+ {"force_consistency_checks",
+ {offsetof(struct ImmutableCFOptions, force_consistency_checks),
+ OptionType::kBoolean, OptionVerificationType::kNormal,
+ OptionTypeFlags::kNone}},
+ {"preclude_last_level_data_seconds",
+ {offsetof(struct ImmutableCFOptions, preclude_last_level_data_seconds),
+ OptionType::kUInt64T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kNone}},
+ {"preserve_internal_time_seconds",
+ {offsetof(struct ImmutableCFOptions, preserve_internal_time_seconds),
+ OptionType::kUInt64T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kNone}},
+ // Need to keep this around to be able to read old OPTIONS files.
+ {"max_mem_compaction_level",
+ {0, OptionType::kInt, OptionVerificationType::kDeprecated,
+ OptionTypeFlags::kNone}},
+ {"max_write_buffer_number_to_maintain",
+ {offsetof(struct ImmutableCFOptions,
+ max_write_buffer_number_to_maintain),
+ OptionType::kInt, OptionVerificationType::kNormal,
+ OptionTypeFlags::kNone, 0}},
+ {"max_write_buffer_size_to_maintain",
+ {offsetof(struct ImmutableCFOptions,
+ max_write_buffer_size_to_maintain),
+ OptionType::kInt64T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kNone}},
+ {"min_write_buffer_number_to_merge",
+ {offsetof(struct ImmutableCFOptions, min_write_buffer_number_to_merge),
+ OptionType::kInt, OptionVerificationType::kNormal,
+ OptionTypeFlags::kNone, 0}},
+ {"num_levels",
+ {offsetof(struct ImmutableCFOptions, num_levels), OptionType::kInt,
+ OptionVerificationType::kNormal, OptionTypeFlags::kNone}},
+ {"bloom_locality",
+ {offsetof(struct ImmutableCFOptions, bloom_locality),
+ OptionType::kUInt32T, OptionVerificationType::kNormal,
+ OptionTypeFlags::kNone}},
+ {"rate_limit_delay_max_milliseconds",
+ {0, OptionType::kUInt, OptionVerificationType::kDeprecated,
+ OptionTypeFlags::kNone}},
+ {"comparator",
+ OptionTypeInfo::AsCustomRawPtr<const Comparator>(
+ offsetof(struct ImmutableCFOptions, user_comparator),
+ OptionVerificationType::kByName, OptionTypeFlags::kCompareLoose)
+ .SetSerializeFunc(
+ // Serializes a Comparator
+ [](const ConfigOptions& opts, const std::string&,
+ const void* addr, std::string* value) {
+ // it's a const pointer of const Comparator*
+ const auto* ptr =
+ static_cast<const Comparator* const*>(addr);
+ // Since the user-specified comparator will be wrapped by
+ // InternalKeyComparator, we should persist the
+ // user-specified one instead of InternalKeyComparator.
+ if (*ptr == nullptr) {
+ *value = kNullptrString;
+ } else if (opts.mutable_options_only) {
+ *value = "";
+ } else {
+ const Comparator* root_comp = (*ptr)->GetRootComparator();
+ if (root_comp == nullptr) {
+ root_comp = (*ptr);
+ }
+ *value = root_comp->ToString(opts);
+ }
+ return Status::OK();
+ })},
+ {"memtable_insert_with_hint_prefix_extractor",
+ OptionTypeInfo::AsCustomSharedPtr<const SliceTransform>(
+ offsetof(struct ImmutableCFOptions,
+ memtable_insert_with_hint_prefix_extractor),
+ OptionVerificationType::kByNameAllowNull, OptionTypeFlags::kNone)},
+ {"memtable_factory",
+ {offsetof(struct ImmutableCFOptions, memtable_factory),
+ OptionType::kCustomizable, OptionVerificationType::kByName,
+ OptionTypeFlags::kShared,
+ [](const ConfigOptions& opts, const std::string&,
+ const std::string& value, void* addr) {
+ std::unique_ptr<MemTableRepFactory> factory;
+ auto* shared =
+ static_cast<std::shared_ptr<MemTableRepFactory>*>(addr);
+ Status s =
+ MemTableRepFactory::CreateFromString(opts, value, shared);
+ return s;
+ }}},
+ {"memtable",
+ {offsetof(struct ImmutableCFOptions, memtable_factory),
+ OptionType::kCustomizable, OptionVerificationType::kAlias,
+ OptionTypeFlags::kShared,
+ [](const ConfigOptions& opts, const std::string&,
+ const std::string& value, void* addr) {
+ std::unique_ptr<MemTableRepFactory> factory;
+ auto* shared =
+ static_cast<std::shared_ptr<MemTableRepFactory>*>(addr);
+ Status s =
+ MemTableRepFactory::CreateFromString(opts, value, shared);
+ return s;
+ }}},
+ {"table_factory",
+ OptionTypeInfo::AsCustomSharedPtr<TableFactory>(
+ offsetof(struct ImmutableCFOptions, table_factory),
+ OptionVerificationType::kByName,
+ (OptionTypeFlags::kCompareLoose |
+ OptionTypeFlags::kStringNameOnly |
+ OptionTypeFlags::kDontPrepare))},
+ {"block_based_table_factory",
+ {offsetof(struct ImmutableCFOptions, table_factory),
+ OptionType::kCustomizable, OptionVerificationType::kAlias,
+ OptionTypeFlags::kShared | OptionTypeFlags::kCompareLoose,
+ // Parses the input value and creates a BlockBasedTableFactory
+ [](const ConfigOptions& opts, const std::string& name,
+ const std::string& value, void* addr) {
+ BlockBasedTableOptions* old_opts = nullptr;
+ auto table_factory =
+ static_cast<std::shared_ptr<TableFactory>*>(addr);
+ if (table_factory->get() != nullptr) {
+ old_opts =
+ table_factory->get()->GetOptions<BlockBasedTableOptions>();
+ }
+ if (name == "block_based_table_factory") {
+ std::unique_ptr<TableFactory> new_factory;
+ if (old_opts != nullptr) {
+ new_factory.reset(NewBlockBasedTableFactory(*old_opts));
+ } else {
+ new_factory.reset(NewBlockBasedTableFactory());
+ }
+ Status s = new_factory->ConfigureFromString(opts, value);
+ if (s.ok()) {
+ table_factory->reset(new_factory.release());
+ }
+ return s;
+ } else if (old_opts != nullptr) {
+ return table_factory->get()->ConfigureOption(opts, name, value);
+ } else {
+ return Status::NotFound("Mismatched table option: ", name);
+ }
+ }}},
+ {"plain_table_factory",
+ {offsetof(struct ImmutableCFOptions, table_factory),
+ OptionType::kCustomizable, OptionVerificationType::kAlias,
+ OptionTypeFlags::kShared | OptionTypeFlags::kCompareLoose,
+ // Parses the input value and creates a PlainTableFactory
+ [](const ConfigOptions& opts, const std::string& name,
+ const std::string& value, void* addr) {
+ PlainTableOptions* old_opts = nullptr;
+ auto table_factory =
+ static_cast<std::shared_ptr<TableFactory>*>(addr);
+ if (table_factory->get() != nullptr) {
+ old_opts = table_factory->get()->GetOptions<PlainTableOptions>();
+ }
+ if (name == "plain_table_factory") {
+ std::unique_ptr<TableFactory> new_factory;
+ if (old_opts != nullptr) {
+ new_factory.reset(NewPlainTableFactory(*old_opts));
+ } else {
+ new_factory.reset(NewPlainTableFactory());
+ }
+ Status s = new_factory->ConfigureFromString(opts, value);
+ if (s.ok()) {
+ table_factory->reset(new_factory.release());
+ }
+ return s;
+ } else if (old_opts != nullptr) {
+ return table_factory->get()->ConfigureOption(opts, name, value);
+ } else {
+ return Status::NotFound("Mismatched table option: ", name);
+ }
+ }}},
+ {"table_properties_collectors",
+ OptionTypeInfo::Vector<
+ std::shared_ptr<TablePropertiesCollectorFactory>>(
+ offsetof(struct ImmutableCFOptions,
+ table_properties_collector_factories),
+ OptionVerificationType::kByName, OptionTypeFlags::kNone,
+ OptionTypeInfo::AsCustomSharedPtr<TablePropertiesCollectorFactory>(
+ 0, OptionVerificationType::kByName, OptionTypeFlags::kNone))},
+ {"compaction_filter",
+ OptionTypeInfo::AsCustomRawPtr<const CompactionFilter>(
+ offsetof(struct ImmutableCFOptions, compaction_filter),
+ OptionVerificationType::kByName, OptionTypeFlags::kAllowNull)},
+ {"compaction_filter_factory",
+ OptionTypeInfo::AsCustomSharedPtr<CompactionFilterFactory>(
+ offsetof(struct ImmutableCFOptions, compaction_filter_factory),
+ OptionVerificationType::kByName, OptionTypeFlags::kAllowNull)},
+ {"merge_operator",
+ OptionTypeInfo::AsCustomSharedPtr<MergeOperator>(
+ offsetof(struct ImmutableCFOptions, merge_operator),
+ OptionVerificationType::kByNameAllowFromNull,
+ OptionTypeFlags::kCompareLoose | OptionTypeFlags::kAllowNull)},
+ {"compaction_style",
+ {offsetof(struct ImmutableCFOptions, compaction_style),
+ OptionType::kCompactionStyle, OptionVerificationType::kNormal,
+ OptionTypeFlags::kNone}},
+ {"compaction_pri",
+ {offsetof(struct ImmutableCFOptions, compaction_pri),
+ OptionType::kCompactionPri, OptionVerificationType::kNormal,
+ OptionTypeFlags::kNone}},
+ {"sst_partitioner_factory",
+ OptionTypeInfo::AsCustomSharedPtr<SstPartitionerFactory>(
+ offsetof(struct ImmutableCFOptions, sst_partitioner_factory),
+ OptionVerificationType::kByName, OptionTypeFlags::kAllowNull)},
+ {"blob_cache",
+ {offsetof(struct ImmutableCFOptions, blob_cache), OptionType::kUnknown,
+ OptionVerificationType::kNormal,
+ (OptionTypeFlags::kCompareNever | OptionTypeFlags::kDontSerialize),
+ // Parses the input value as a Cache
+ [](const ConfigOptions& opts, const std::string&,
+ const std::string& value, void* addr) {
+ auto* cache = static_cast<std::shared_ptr<Cache>*>(addr);
+ return Cache::CreateFromString(opts, value, cache);
+ }}},
+};
+
+const std::string OptionsHelper::kCFOptionsName = "ColumnFamilyOptions";
+
+class ConfigurableMutableCFOptions : public Configurable {
+ public:
+ explicit ConfigurableMutableCFOptions(const MutableCFOptions& mcf) {
+ mutable_ = mcf;
+ RegisterOptions(&mutable_, &cf_mutable_options_type_info);
+ }
+
+ protected:
+ MutableCFOptions mutable_;
+};
+
+class ConfigurableCFOptions : public ConfigurableMutableCFOptions {
+ public:
+ ConfigurableCFOptions(const ColumnFamilyOptions& opts,
+ const std::unordered_map<std::string, std::string>* map)
+ : ConfigurableMutableCFOptions(MutableCFOptions(opts)),
+ immutable_(opts),
+ cf_options_(opts),
+ opt_map_(map) {
+ RegisterOptions(&immutable_, &cf_immutable_options_type_info);
+ }
+
+ protected:
+ Status ConfigureOptions(
+ const ConfigOptions& config_options,
+ const std::unordered_map<std::string, std::string>& opts_map,
+ std::unordered_map<std::string, std::string>* unused) override {
+ Status s = Configurable::ConfigureOptions(config_options, opts_map, unused);
+ if (s.ok()) {
+ UpdateColumnFamilyOptions(mutable_, &cf_options_);
+ UpdateColumnFamilyOptions(immutable_, &cf_options_);
+ s = PrepareOptions(config_options);
+ }
+ return s;
+ }
+
+ virtual const void* GetOptionsPtr(const std::string& name) const override {
+ if (name == OptionsHelper::kCFOptionsName) {
+ return &cf_options_;
+ } else {
+ return ConfigurableMutableCFOptions::GetOptionsPtr(name);
+ }
+ }
+
+ bool OptionsAreEqual(const ConfigOptions& config_options,
+ const OptionTypeInfo& opt_info,
+ const std::string& opt_name, const void* const this_ptr,
+ const void* const that_ptr,
+ std::string* mismatch) const override {
+ bool equals = opt_info.AreEqual(config_options, opt_name, this_ptr,
+ that_ptr, mismatch);
+ if (!equals && opt_info.IsByName()) {
+ if (opt_map_ == nullptr) {
+ equals = true;
+ } else {
+ const auto& iter = opt_map_->find(opt_name);
+ if (iter == opt_map_->end()) {
+ equals = true;
+ } else {
+ equals = opt_info.AreEqualByName(config_options, opt_name, this_ptr,
+ iter->second);
+ }
+ }
+ if (equals) { // False alarm, clear mismatch
+ *mismatch = "";
+ }
+ }
+ if (equals && opt_info.IsConfigurable() && opt_map_ != nullptr) {
+ const auto* this_config = opt_info.AsRawPointer<Configurable>(this_ptr);
+ if (this_config == nullptr) {
+ const auto& iter = opt_map_->find(opt_name);
+ // If the name exists in the map and is not empty/null,
+ // then the this_config should be set.
+ if (iter != opt_map_->end() && !iter->second.empty() &&
+ iter->second != kNullptrString) {
+ *mismatch = opt_name;
+ equals = false;
+ }
+ }
+ }
+ return equals;
+ }
+
+ private:
+ ImmutableCFOptions immutable_;
+ ColumnFamilyOptions cf_options_;
+ const std::unordered_map<std::string, std::string>* opt_map_;
+};
+
+std::unique_ptr<Configurable> CFOptionsAsConfigurable(
+ const MutableCFOptions& opts) {
+ std::unique_ptr<Configurable> ptr(new ConfigurableMutableCFOptions(opts));
+ return ptr;
+}
+std::unique_ptr<Configurable> CFOptionsAsConfigurable(
+ const ColumnFamilyOptions& opts,
+ const std::unordered_map<std::string, std::string>* opt_map) {
+ std::unique_ptr<Configurable> ptr(new ConfigurableCFOptions(opts, opt_map));
+ return ptr;
+}
+#endif // ROCKSDB_LITE
+
+ImmutableCFOptions::ImmutableCFOptions() : ImmutableCFOptions(Options()) {}
+
+ImmutableCFOptions::ImmutableCFOptions(const ColumnFamilyOptions& cf_options)
+ : compaction_style(cf_options.compaction_style),
+ compaction_pri(cf_options.compaction_pri),
+ user_comparator(cf_options.comparator),
+ internal_comparator(InternalKeyComparator(cf_options.comparator)),
+ merge_operator(cf_options.merge_operator),
+ compaction_filter(cf_options.compaction_filter),
+ compaction_filter_factory(cf_options.compaction_filter_factory),
+ min_write_buffer_number_to_merge(
+ cf_options.min_write_buffer_number_to_merge),
+ max_write_buffer_number_to_maintain(
+ cf_options.max_write_buffer_number_to_maintain),
+ max_write_buffer_size_to_maintain(
+ cf_options.max_write_buffer_size_to_maintain),
+ inplace_update_support(cf_options.inplace_update_support),
+ inplace_callback(cf_options.inplace_callback),
+ memtable_factory(cf_options.memtable_factory),
+ table_factory(cf_options.table_factory),
+ table_properties_collector_factories(
+ cf_options.table_properties_collector_factories),
+ bloom_locality(cf_options.bloom_locality),
+ level_compaction_dynamic_level_bytes(
+ cf_options.level_compaction_dynamic_level_bytes),
+ level_compaction_dynamic_file_size(
+ cf_options.level_compaction_dynamic_file_size),
+ num_levels(cf_options.num_levels),
+ optimize_filters_for_hits(cf_options.optimize_filters_for_hits),
+ force_consistency_checks(cf_options.force_consistency_checks),
+ preclude_last_level_data_seconds(
+ cf_options.preclude_last_level_data_seconds),
+ preserve_internal_time_seconds(cf_options.preserve_internal_time_seconds),
+ memtable_insert_with_hint_prefix_extractor(
+ cf_options.memtable_insert_with_hint_prefix_extractor),
+ cf_paths(cf_options.cf_paths),
+ compaction_thread_limiter(cf_options.compaction_thread_limiter),
+ sst_partitioner_factory(cf_options.sst_partitioner_factory),
+ blob_cache(cf_options.blob_cache) {}
+
+ImmutableOptions::ImmutableOptions() : ImmutableOptions(Options()) {}
+
+ImmutableOptions::ImmutableOptions(const Options& options)
+ : ImmutableOptions(options, options) {}
+
+ImmutableOptions::ImmutableOptions(const DBOptions& db_options,
+ const ColumnFamilyOptions& cf_options)
+ : ImmutableDBOptions(db_options), ImmutableCFOptions(cf_options) {}
+
+ImmutableOptions::ImmutableOptions(const DBOptions& db_options,
+ const ImmutableCFOptions& cf_options)
+ : ImmutableDBOptions(db_options), ImmutableCFOptions(cf_options) {}
+
+ImmutableOptions::ImmutableOptions(const ImmutableDBOptions& db_options,
+ const ColumnFamilyOptions& cf_options)
+ : ImmutableDBOptions(db_options), ImmutableCFOptions(cf_options) {}
+
+ImmutableOptions::ImmutableOptions(const ImmutableDBOptions& db_options,
+ const ImmutableCFOptions& cf_options)
+ : ImmutableDBOptions(db_options), ImmutableCFOptions(cf_options) {}
+
+// Multiple two operands. If they overflow, return op1.
+uint64_t MultiplyCheckOverflow(uint64_t op1, double op2) {
+ if (op1 == 0 || op2 <= 0) {
+ return 0;
+ }
+ if (std::numeric_limits<uint64_t>::max() / op1 < op2) {
+ return op1;
+ }
+ return static_cast<uint64_t>(op1 * op2);
+}
+
+// when level_compaction_dynamic_level_bytes is true and leveled compaction
+// is used, the base level is not always L1, so precomupted max_file_size can
+// no longer be used. Recompute file_size_for_level from base level.
+uint64_t MaxFileSizeForLevel(const MutableCFOptions& cf_options,
+ int level, CompactionStyle compaction_style, int base_level,
+ bool level_compaction_dynamic_level_bytes) {
+ if (!level_compaction_dynamic_level_bytes || level < base_level ||
+ compaction_style != kCompactionStyleLevel) {
+ assert(level >= 0);
+ assert(level < (int)cf_options.max_file_size.size());
+ return cf_options.max_file_size[level];
+ } else {
+ assert(level >= 0 && base_level >= 0);
+ assert(level - base_level < (int)cf_options.max_file_size.size());
+ return cf_options.max_file_size[level - base_level];
+ }
+}
+
+size_t MaxFileSizeForL0MetaPin(const MutableCFOptions& cf_options) {
+ // We do not want to pin meta-blocks that almost certainly came from intra-L0
+ // or a former larger `write_buffer_size` value to avoid surprising users with
+ // pinned memory usage. We use a factor of 1.5 to account for overhead
+ // introduced during flush in most cases.
+ if (std::numeric_limits<size_t>::max() / 3 <
+ cf_options.write_buffer_size / 2) {
+ return std::numeric_limits<size_t>::max();
+ }
+ return cf_options.write_buffer_size / 2 * 3;
+}
+
+void MutableCFOptions::RefreshDerivedOptions(int num_levels,
+ CompactionStyle compaction_style) {
+ max_file_size.resize(num_levels);
+ for (int i = 0; i < num_levels; ++i) {
+ if (i == 0 && compaction_style == kCompactionStyleUniversal) {
+ max_file_size[i] = ULLONG_MAX;
+ } else if (i > 1) {
+ max_file_size[i] = MultiplyCheckOverflow(max_file_size[i - 1],
+ target_file_size_multiplier);
+ } else {
+ max_file_size[i] = target_file_size_base;
+ }
+ }
+}
+
+void MutableCFOptions::Dump(Logger* log) const {
+ // Memtable related options
+ ROCKS_LOG_INFO(log,
+ " write_buffer_size: %" ROCKSDB_PRIszt,
+ write_buffer_size);
+ ROCKS_LOG_INFO(log, " max_write_buffer_number: %d",
+ max_write_buffer_number);
+ ROCKS_LOG_INFO(log,
+ " arena_block_size: %" ROCKSDB_PRIszt,
+ arena_block_size);
+ ROCKS_LOG_INFO(log, " memtable_prefix_bloom_ratio: %f",
+ memtable_prefix_bloom_size_ratio);
+ ROCKS_LOG_INFO(log, " memtable_whole_key_filtering: %d",
+ memtable_whole_key_filtering);
+ ROCKS_LOG_INFO(log,
+ " memtable_huge_page_size: %" ROCKSDB_PRIszt,
+ memtable_huge_page_size);
+ ROCKS_LOG_INFO(log,
+ " max_successive_merges: %" ROCKSDB_PRIszt,
+ max_successive_merges);
+ ROCKS_LOG_INFO(log,
+ " inplace_update_num_locks: %" ROCKSDB_PRIszt,
+ inplace_update_num_locks);
+ ROCKS_LOG_INFO(log, " prefix_extractor: %s",
+ prefix_extractor == nullptr
+ ? "nullptr"
+ : prefix_extractor->GetId().c_str());
+ ROCKS_LOG_INFO(log, " disable_auto_compactions: %d",
+ disable_auto_compactions);
+ ROCKS_LOG_INFO(log, " soft_pending_compaction_bytes_limit: %" PRIu64,
+ soft_pending_compaction_bytes_limit);
+ ROCKS_LOG_INFO(log, " hard_pending_compaction_bytes_limit: %" PRIu64,
+ hard_pending_compaction_bytes_limit);
+ ROCKS_LOG_INFO(log, " level0_file_num_compaction_trigger: %d",
+ level0_file_num_compaction_trigger);
+ ROCKS_LOG_INFO(log, " level0_slowdown_writes_trigger: %d",
+ level0_slowdown_writes_trigger);
+ ROCKS_LOG_INFO(log, " level0_stop_writes_trigger: %d",
+ level0_stop_writes_trigger);
+ ROCKS_LOG_INFO(log, " max_compaction_bytes: %" PRIu64,
+ max_compaction_bytes);
+ ROCKS_LOG_INFO(log, " ignore_max_compaction_bytes_for_input: %s",
+ ignore_max_compaction_bytes_for_input ? "true" : "false");
+ ROCKS_LOG_INFO(log, " target_file_size_base: %" PRIu64,
+ target_file_size_base);
+ ROCKS_LOG_INFO(log, " target_file_size_multiplier: %d",
+ target_file_size_multiplier);
+ ROCKS_LOG_INFO(log, " max_bytes_for_level_base: %" PRIu64,
+ max_bytes_for_level_base);
+ ROCKS_LOG_INFO(log, " max_bytes_for_level_multiplier: %f",
+ max_bytes_for_level_multiplier);
+ ROCKS_LOG_INFO(log, " ttl: %" PRIu64,
+ ttl);
+ ROCKS_LOG_INFO(log, " periodic_compaction_seconds: %" PRIu64,
+ periodic_compaction_seconds);
+ std::string result;
+ char buf[10];
+ for (const auto m : max_bytes_for_level_multiplier_additional) {
+ snprintf(buf, sizeof(buf), "%d, ", m);
+ result += buf;
+ }
+ if (result.size() >= 2) {
+ result.resize(result.size() - 2);
+ } else {
+ result = "";
+ }
+
+ ROCKS_LOG_INFO(log, "max_bytes_for_level_multiplier_additional: %s",
+ result.c_str());
+ ROCKS_LOG_INFO(log, " max_sequential_skip_in_iterations: %" PRIu64,
+ max_sequential_skip_in_iterations);
+ ROCKS_LOG_INFO(log, " check_flush_compaction_key_order: %d",
+ check_flush_compaction_key_order);
+ ROCKS_LOG_INFO(log, " paranoid_file_checks: %d",
+ paranoid_file_checks);
+ ROCKS_LOG_INFO(log, " report_bg_io_stats: %d",
+ report_bg_io_stats);
+ ROCKS_LOG_INFO(log, " compression: %d",
+ static_cast<int>(compression));
+ ROCKS_LOG_INFO(log,
+ " experimental_mempurge_threshold: %f",
+ experimental_mempurge_threshold);
+
+ // Universal Compaction Options
+ ROCKS_LOG_INFO(log, "compaction_options_universal.size_ratio : %d",
+ compaction_options_universal.size_ratio);
+ ROCKS_LOG_INFO(log, "compaction_options_universal.min_merge_width : %d",
+ compaction_options_universal.min_merge_width);
+ ROCKS_LOG_INFO(log, "compaction_options_universal.max_merge_width : %d",
+ compaction_options_universal.max_merge_width);
+ ROCKS_LOG_INFO(
+ log, "compaction_options_universal.max_size_amplification_percent : %d",
+ compaction_options_universal.max_size_amplification_percent);
+ ROCKS_LOG_INFO(log,
+ "compaction_options_universal.compression_size_percent : %d",
+ compaction_options_universal.compression_size_percent);
+ ROCKS_LOG_INFO(log, "compaction_options_universal.stop_style : %d",
+ compaction_options_universal.stop_style);
+ ROCKS_LOG_INFO(
+ log, "compaction_options_universal.allow_trivial_move : %d",
+ static_cast<int>(compaction_options_universal.allow_trivial_move));
+ ROCKS_LOG_INFO(log, "compaction_options_universal.incremental : %d",
+ static_cast<int>(compaction_options_universal.incremental));
+
+ // FIFO Compaction Options
+ ROCKS_LOG_INFO(log, "compaction_options_fifo.max_table_files_size : %" PRIu64,
+ compaction_options_fifo.max_table_files_size);
+ ROCKS_LOG_INFO(log, "compaction_options_fifo.allow_compaction : %d",
+ compaction_options_fifo.allow_compaction);
+
+ // Blob file related options
+ ROCKS_LOG_INFO(log, " enable_blob_files: %s",
+ enable_blob_files ? "true" : "false");
+ ROCKS_LOG_INFO(log, " min_blob_size: %" PRIu64,
+ min_blob_size);
+ ROCKS_LOG_INFO(log, " blob_file_size: %" PRIu64,
+ blob_file_size);
+ ROCKS_LOG_INFO(log, " blob_compression_type: %s",
+ CompressionTypeToString(blob_compression_type).c_str());
+ ROCKS_LOG_INFO(log, " enable_blob_garbage_collection: %s",
+ enable_blob_garbage_collection ? "true" : "false");
+ ROCKS_LOG_INFO(log, " blob_garbage_collection_age_cutoff: %f",
+ blob_garbage_collection_age_cutoff);
+ ROCKS_LOG_INFO(log, " blob_garbage_collection_force_threshold: %f",
+ blob_garbage_collection_force_threshold);
+ ROCKS_LOG_INFO(log, " blob_compaction_readahead_size: %" PRIu64,
+ blob_compaction_readahead_size);
+ ROCKS_LOG_INFO(log, " blob_file_starting_level: %d",
+ blob_file_starting_level);
+ ROCKS_LOG_INFO(log, " prepopulate_blob_cache: %s",
+ prepopulate_blob_cache == PrepopulateBlobCache::kFlushOnly
+ ? "flush only"
+ : "disable");
+ ROCKS_LOG_INFO(log, " last_level_temperature: %d",
+ static_cast<int>(last_level_temperature));
+}
+
+MutableCFOptions::MutableCFOptions(const Options& options)
+ : MutableCFOptions(ColumnFamilyOptions(options)) {}
+
+#ifndef ROCKSDB_LITE
+Status GetMutableOptionsFromStrings(
+ const MutableCFOptions& base_options,
+ const std::unordered_map<std::string, std::string>& options_map,
+ Logger* /*info_log*/, MutableCFOptions* new_options) {
+ assert(new_options);
+ *new_options = base_options;
+ ConfigOptions config_options;
+ Status s = OptionTypeInfo::ParseType(
+ config_options, options_map, cf_mutable_options_type_info, new_options);
+ if (!s.ok()) {
+ *new_options = base_options;
+ }
+ return s;
+}
+
+Status GetStringFromMutableCFOptions(const ConfigOptions& config_options,
+ const MutableCFOptions& mutable_opts,
+ std::string* opt_string) {
+ assert(opt_string);
+ opt_string->clear();
+ return OptionTypeInfo::SerializeType(
+ config_options, cf_mutable_options_type_info, &mutable_opts, opt_string);
+}
+#endif // ROCKSDB_LITE
+} // namespace ROCKSDB_NAMESPACE