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 
6 #include "options/cf_options.h"
7 
8 #include <cassert>
9 #include <cinttypes>
10 #include <limits>
11 #include <string>
12 #include "options/db_options.h"
13 #include "port/port.h"
14 #include "rocksdb/concurrent_task_limiter.h"
15 #include "rocksdb/env.h"
16 #include "rocksdb/file_system.h"
17 #include "rocksdb/options.h"
18 
19 namespace ROCKSDB_NAMESPACE {
20 
ImmutableCFOptions(const Options & options)21 ImmutableCFOptions::ImmutableCFOptions(const Options& options)
22     : ImmutableCFOptions(ImmutableDBOptions(options), options) {}
23 
ImmutableCFOptions(const ImmutableDBOptions & db_options,const ColumnFamilyOptions & cf_options)24 ImmutableCFOptions::ImmutableCFOptions(const ImmutableDBOptions& db_options,
25                                        const ColumnFamilyOptions& cf_options)
26     : compaction_style(cf_options.compaction_style),
27       compaction_pri(cf_options.compaction_pri),
28       user_comparator(cf_options.comparator),
29       internal_comparator(InternalKeyComparator(cf_options.comparator)),
30       merge_operator(cf_options.merge_operator.get()),
31       compaction_filter(cf_options.compaction_filter),
32       compaction_filter_factory(cf_options.compaction_filter_factory.get()),
33       min_write_buffer_number_to_merge(
34           cf_options.min_write_buffer_number_to_merge),
35       max_write_buffer_number_to_maintain(
36           cf_options.max_write_buffer_number_to_maintain),
37       max_write_buffer_size_to_maintain(
38           cf_options.max_write_buffer_size_to_maintain),
39       inplace_update_support(cf_options.inplace_update_support),
40       inplace_callback(cf_options.inplace_callback),
41       info_log(db_options.info_log.get()),
42       statistics(db_options.statistics.get()),
43       rate_limiter(db_options.rate_limiter.get()),
44       info_log_level(db_options.info_log_level),
45       env(db_options.env),
46       fs(db_options.fs.get()),
47       allow_mmap_reads(db_options.allow_mmap_reads),
48       allow_mmap_writes(db_options.allow_mmap_writes),
49       db_paths(db_options.db_paths),
50       memtable_factory(cf_options.memtable_factory.get()),
51       table_factory(cf_options.table_factory.get()),
52       table_properties_collector_factories(
53           cf_options.table_properties_collector_factories),
54       advise_random_on_open(db_options.advise_random_on_open),
55       bloom_locality(cf_options.bloom_locality),
56       purge_redundant_kvs_while_flush(
57           cf_options.purge_redundant_kvs_while_flush),
58       use_fsync(db_options.use_fsync),
59       compression_per_level(cf_options.compression_per_level),
60       bottommost_compression(cf_options.bottommost_compression),
61       bottommost_compression_opts(cf_options.bottommost_compression_opts),
62       compression_opts(cf_options.compression_opts),
63       level_compaction_dynamic_level_bytes(
64           cf_options.level_compaction_dynamic_level_bytes),
65       access_hint_on_compaction_start(
66           db_options.access_hint_on_compaction_start),
67       new_table_reader_for_compaction_inputs(
68           db_options.new_table_reader_for_compaction_inputs),
69       num_levels(cf_options.num_levels),
70       optimize_filters_for_hits(cf_options.optimize_filters_for_hits),
71       force_consistency_checks(cf_options.force_consistency_checks),
72       allow_ingest_behind(db_options.allow_ingest_behind),
73       preserve_deletes(db_options.preserve_deletes),
74       listeners(db_options.listeners),
75       row_cache(db_options.row_cache),
76       max_subcompactions(db_options.max_subcompactions),
77       memtable_insert_with_hint_prefix_extractor(
78           cf_options.memtable_insert_with_hint_prefix_extractor.get()),
79       cf_paths(cf_options.cf_paths),
80       compaction_thread_limiter(cf_options.compaction_thread_limiter),
81       file_checksum_gen_factory(db_options.file_checksum_gen_factory.get()) {}
82 
83 // Multiple two operands. If they overflow, return op1.
MultiplyCheckOverflow(uint64_t op1,double op2)84 uint64_t MultiplyCheckOverflow(uint64_t op1, double op2) {
85   if (op1 == 0 || op2 <= 0) {
86     return 0;
87   }
88   if (port::kMaxUint64 / op1 < op2) {
89     return op1;
90   }
91   return static_cast<uint64_t>(op1 * op2);
92 }
93 
94 // when level_compaction_dynamic_level_bytes is true and leveled compaction
95 // is used, the base level is not always L1, so precomupted max_file_size can
96 // no longer be used. Recompute file_size_for_level from base level.
MaxFileSizeForLevel(const MutableCFOptions & cf_options,int level,CompactionStyle compaction_style,int base_level,bool level_compaction_dynamic_level_bytes)97 uint64_t MaxFileSizeForLevel(const MutableCFOptions& cf_options,
98     int level, CompactionStyle compaction_style, int base_level,
99     bool level_compaction_dynamic_level_bytes) {
100   if (!level_compaction_dynamic_level_bytes || level < base_level ||
101       compaction_style != kCompactionStyleLevel) {
102     assert(level >= 0);
103     assert(level < (int)cf_options.max_file_size.size());
104     return cf_options.max_file_size[level];
105   } else {
106     assert(level >= 0 && base_level >= 0);
107     assert(level - base_level < (int)cf_options.max_file_size.size());
108     return cf_options.max_file_size[level - base_level];
109   }
110 }
111 
RefreshDerivedOptions(int num_levels,CompactionStyle compaction_style)112 void MutableCFOptions::RefreshDerivedOptions(int num_levels,
113                                              CompactionStyle compaction_style) {
114   max_file_size.resize(num_levels);
115   for (int i = 0; i < num_levels; ++i) {
116     if (i == 0 && compaction_style == kCompactionStyleUniversal) {
117       max_file_size[i] = ULLONG_MAX;
118     } else if (i > 1) {
119       max_file_size[i] = MultiplyCheckOverflow(max_file_size[i - 1],
120                                                target_file_size_multiplier);
121     } else {
122       max_file_size[i] = target_file_size_base;
123     }
124   }
125 }
126 
Dump(Logger * log) const127 void MutableCFOptions::Dump(Logger* log) const {
128   // Memtable related options
129   ROCKS_LOG_INFO(log,
130                  "                        write_buffer_size: %" ROCKSDB_PRIszt,
131                  write_buffer_size);
132   ROCKS_LOG_INFO(log, "                  max_write_buffer_number: %d",
133                  max_write_buffer_number);
134   ROCKS_LOG_INFO(log,
135                  "                         arena_block_size: %" ROCKSDB_PRIszt,
136                  arena_block_size);
137   ROCKS_LOG_INFO(log, "              memtable_prefix_bloom_ratio: %f",
138                  memtable_prefix_bloom_size_ratio);
139   ROCKS_LOG_INFO(log, "              memtable_whole_key_filtering: %d",
140                  memtable_whole_key_filtering);
141   ROCKS_LOG_INFO(log,
142                  "                  memtable_huge_page_size: %" ROCKSDB_PRIszt,
143                  memtable_huge_page_size);
144   ROCKS_LOG_INFO(log,
145                  "                    max_successive_merges: %" ROCKSDB_PRIszt,
146                  max_successive_merges);
147   ROCKS_LOG_INFO(log,
148                  "                 inplace_update_num_locks: %" ROCKSDB_PRIszt,
149                  inplace_update_num_locks);
150   ROCKS_LOG_INFO(
151       log, "                         prefix_extractor: %s",
152       prefix_extractor == nullptr ? "nullptr" : prefix_extractor->Name());
153   ROCKS_LOG_INFO(log, "                 disable_auto_compactions: %d",
154                  disable_auto_compactions);
155   ROCKS_LOG_INFO(log, "      soft_pending_compaction_bytes_limit: %" PRIu64,
156                  soft_pending_compaction_bytes_limit);
157   ROCKS_LOG_INFO(log, "      hard_pending_compaction_bytes_limit: %" PRIu64,
158                  hard_pending_compaction_bytes_limit);
159   ROCKS_LOG_INFO(log, "       level0_file_num_compaction_trigger: %d",
160                  level0_file_num_compaction_trigger);
161   ROCKS_LOG_INFO(log, "           level0_slowdown_writes_trigger: %d",
162                  level0_slowdown_writes_trigger);
163   ROCKS_LOG_INFO(log, "               level0_stop_writes_trigger: %d",
164                  level0_stop_writes_trigger);
165   ROCKS_LOG_INFO(log, "                     max_compaction_bytes: %" PRIu64,
166                  max_compaction_bytes);
167   ROCKS_LOG_INFO(log, "                    target_file_size_base: %" PRIu64,
168                  target_file_size_base);
169   ROCKS_LOG_INFO(log, "              target_file_size_multiplier: %d",
170                  target_file_size_multiplier);
171   ROCKS_LOG_INFO(log, "                 max_bytes_for_level_base: %" PRIu64,
172                  max_bytes_for_level_base);
173   ROCKS_LOG_INFO(log, "           max_bytes_for_level_multiplier: %f",
174                  max_bytes_for_level_multiplier);
175   ROCKS_LOG_INFO(log, "                                      ttl: %" PRIu64,
176                  ttl);
177   ROCKS_LOG_INFO(log, "              periodic_compaction_seconds: %" PRIu64,
178                  periodic_compaction_seconds);
179   std::string result;
180   char buf[10];
181   for (const auto m : max_bytes_for_level_multiplier_additional) {
182     snprintf(buf, sizeof(buf), "%d, ", m);
183     result += buf;
184   }
185   if (result.size() >= 2) {
186     result.resize(result.size() - 2);
187   } else {
188     result = "";
189   }
190 
191   ROCKS_LOG_INFO(log, "max_bytes_for_level_multiplier_additional: %s",
192                  result.c_str());
193   ROCKS_LOG_INFO(log, "        max_sequential_skip_in_iterations: %" PRIu64,
194                  max_sequential_skip_in_iterations);
195   ROCKS_LOG_INFO(log, "                     paranoid_file_checks: %d",
196                  paranoid_file_checks);
197   ROCKS_LOG_INFO(log, "                       report_bg_io_stats: %d",
198                  report_bg_io_stats);
199   ROCKS_LOG_INFO(log, "                              compression: %d",
200                  static_cast<int>(compression));
201 
202   // Universal Compaction Options
203   ROCKS_LOG_INFO(log, "compaction_options_universal.size_ratio : %d",
204                  compaction_options_universal.size_ratio);
205   ROCKS_LOG_INFO(log, "compaction_options_universal.min_merge_width : %d",
206                  compaction_options_universal.min_merge_width);
207   ROCKS_LOG_INFO(log, "compaction_options_universal.max_merge_width : %d",
208                  compaction_options_universal.max_merge_width);
209   ROCKS_LOG_INFO(
210       log, "compaction_options_universal.max_size_amplification_percent : %d",
211       compaction_options_universal.max_size_amplification_percent);
212   ROCKS_LOG_INFO(log,
213                  "compaction_options_universal.compression_size_percent : %d",
214                  compaction_options_universal.compression_size_percent);
215   ROCKS_LOG_INFO(log, "compaction_options_universal.stop_style : %d",
216                  compaction_options_universal.stop_style);
217   ROCKS_LOG_INFO(
218       log, "compaction_options_universal.allow_trivial_move : %d",
219       static_cast<int>(compaction_options_universal.allow_trivial_move));
220 
221   // FIFO Compaction Options
222   ROCKS_LOG_INFO(log, "compaction_options_fifo.max_table_files_size : %" PRIu64,
223                  compaction_options_fifo.max_table_files_size);
224   ROCKS_LOG_INFO(log, "compaction_options_fifo.allow_compaction : %d",
225                  compaction_options_fifo.allow_compaction);
226 }
227 
MutableCFOptions(const Options & options)228 MutableCFOptions::MutableCFOptions(const Options& options)
229     : MutableCFOptions(ColumnFamilyOptions(options)) {}
230 
231 }  // namespace ROCKSDB_NAMESPACE
232