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).
6 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7 // Use of this source code is governed by a BSD-style license that can be
8 // found in the LICENSE file. See the AUTHORS file for names of contributors.
10 // The test uses an array to compare against values written to the database.
11 // Keys written to the array are in 1:1 correspondence to the actual values in
12 // the database according to the formula in the function GenerateValue.
14 // Space is reserved in the array from 0 to FLAGS_max_key and values are
15 // randomly written/deleted/read from those positions. During verification we
16 // compare all the positions in the array. To shorten/elongate the running
17 // time, you could change the settings: FLAGS_max_key, FLAGS_ops_per_thread,
18 // (sometimes also FLAGS_threads).
20 // NOTE that if FLAGS_test_batches_snapshots is set, the test will have
21 // different behavior. See comment of the flag for details.
28 #include <sys/types.h>
38 #include "db/db_impl/db_impl.h"
39 #include "db/version_set.h"
40 #include "db_stress_tool/db_stress_env_wrapper.h"
41 #include "db_stress_tool/db_stress_listener.h"
42 #include "db_stress_tool/db_stress_shared_state.h"
43 #include "db_stress_tool/db_stress_test_base.h"
44 #include "logging/logging.h"
45 #include "monitoring/histogram.h"
46 #include "options/options_helper.h"
47 #include "port/port.h"
48 #include "rocksdb/cache.h"
49 #include "rocksdb/env.h"
50 #include "rocksdb/slice.h"
51 #include "rocksdb/slice_transform.h"
52 #include "rocksdb/statistics.h"
53 #include "rocksdb/utilities/backup_engine.h"
54 #include "rocksdb/utilities/checkpoint.h"
55 #include "rocksdb/utilities/db_ttl.h"
56 #include "rocksdb/utilities/debug.h"
57 #include "rocksdb/utilities/options_util.h"
58 #include "rocksdb/utilities/transaction.h"
59 #include "rocksdb/utilities/transaction_db.h"
60 #include "rocksdb/write_batch.h"
61 #include "test_util/testutil.h"
62 #include "util/coding.h"
63 #include "util/compression.h"
64 #include "util/crc32c.h"
65 #include "util/gflags_compat.h"
66 #include "util/mutexlock.h"
67 #include "util/random.h"
68 #include "util/string_util.h"
69 #include "utilities/blob_db/blob_db.h"
70 #include "utilities/fault_injection_fs.h"
71 #include "utilities/merge_operators.h"
73 using GFLAGS_NAMESPACE::ParseCommandLineFlags
;
74 using GFLAGS_NAMESPACE::RegisterFlagValidator
;
75 using GFLAGS_NAMESPACE::SetUsageMessage
;
78 DECLARE_bool(read_only
);
79 DECLARE_int64(max_key
);
80 DECLARE_double(hot_key_alpha
);
81 DECLARE_int32(max_key_len
);
82 DECLARE_string(key_len_percent_dist
);
83 DECLARE_int32(key_window_scale_factor
);
84 DECLARE_int32(column_families
);
85 DECLARE_string(options_file
);
86 DECLARE_int64(active_width
);
87 DECLARE_bool(test_batches_snapshots
);
88 DECLARE_bool(atomic_flush
);
89 DECLARE_int32(manual_wal_flush_one_in
);
90 DECLARE_bool(test_cf_consistency
);
91 DECLARE_bool(test_multi_ops_txns
);
92 DECLARE_int32(threads
);
94 DECLARE_int32(value_size_mult
);
95 DECLARE_int32(compaction_readahead_size
);
96 DECLARE_bool(enable_pipelined_write
);
97 DECLARE_bool(verify_before_write
);
98 DECLARE_bool(histogram
);
99 DECLARE_bool(destroy_db_initially
);
100 DECLARE_bool(verbose
);
101 DECLARE_bool(progress_reports
);
102 DECLARE_uint64(db_write_buffer_size
);
103 DECLARE_int32(write_buffer_size
);
104 DECLARE_int32(max_write_buffer_number
);
105 DECLARE_int32(min_write_buffer_number_to_merge
);
106 DECLARE_int32(max_write_buffer_number_to_maintain
);
107 DECLARE_int64(max_write_buffer_size_to_maintain
);
108 DECLARE_double(memtable_prefix_bloom_size_ratio
);
109 DECLARE_bool(memtable_whole_key_filtering
);
110 DECLARE_int32(open_files
);
111 DECLARE_int64(compressed_cache_size
);
112 DECLARE_int32(compressed_cache_numshardbits
);
113 DECLARE_int32(compaction_style
);
114 DECLARE_int32(compaction_pri
);
115 DECLARE_int32(num_levels
);
116 DECLARE_int32(level0_file_num_compaction_trigger
);
117 DECLARE_int32(level0_slowdown_writes_trigger
);
118 DECLARE_int32(level0_stop_writes_trigger
);
119 DECLARE_int32(block_size
);
120 DECLARE_int32(format_version
);
121 DECLARE_int32(index_block_restart_interval
);
122 DECLARE_bool(disable_auto_compactions
);
123 DECLARE_int32(max_background_compactions
);
124 DECLARE_int32(num_bottom_pri_threads
);
125 DECLARE_int32(compaction_thread_pool_adjust_interval
);
126 DECLARE_int32(compaction_thread_pool_variations
);
127 DECLARE_int32(max_background_flushes
);
128 DECLARE_int32(universal_size_ratio
);
129 DECLARE_int32(universal_min_merge_width
);
130 DECLARE_int32(universal_max_merge_width
);
131 DECLARE_int32(universal_max_size_amplification_percent
);
132 DECLARE_int32(clear_column_family_one_in
);
133 DECLARE_int32(get_live_files_one_in
);
134 DECLARE_int32(get_sorted_wal_files_one_in
);
135 DECLARE_int32(get_current_wal_file_one_in
);
136 DECLARE_int32(set_options_one_in
);
137 DECLARE_int32(set_in_place_one_in
);
138 DECLARE_int64(cache_size
);
139 DECLARE_int32(cache_numshardbits
);
140 DECLARE_bool(cache_index_and_filter_blocks
);
141 DECLARE_bool(charge_compression_dictionary_building_buffer
);
142 DECLARE_bool(charge_filter_construction
);
143 DECLARE_bool(charge_table_reader
);
144 DECLARE_bool(charge_file_metadata
);
145 DECLARE_bool(charge_blob_cache
);
146 DECLARE_int32(top_level_index_pinning
);
147 DECLARE_int32(partition_pinning
);
148 DECLARE_int32(unpartitioned_pinning
);
149 DECLARE_string(cache_type
);
150 DECLARE_uint64(subcompactions
);
151 DECLARE_uint64(periodic_compaction_seconds
);
152 DECLARE_uint64(compaction_ttl
);
153 DECLARE_bool(allow_concurrent_memtable_write
);
154 DECLARE_double(experimental_mempurge_threshold
);
155 DECLARE_bool(enable_write_thread_adaptive_yield
);
156 DECLARE_int32(reopen
);
157 DECLARE_double(bloom_bits
);
158 DECLARE_int32(ribbon_starting_level
);
159 DECLARE_bool(partition_filters
);
160 DECLARE_bool(optimize_filters_for_memory
);
161 DECLARE_bool(detect_filter_construct_corruption
);
162 DECLARE_int32(index_type
);
163 DECLARE_int32(data_block_index_type
);
165 DECLARE_string(secondaries_base
);
166 DECLARE_bool(test_secondary
);
167 DECLARE_string(expected_values_dir
);
168 DECLARE_bool(verify_checksum
);
169 DECLARE_bool(mmap_read
);
170 DECLARE_bool(mmap_write
);
171 DECLARE_bool(use_direct_reads
);
172 DECLARE_bool(use_direct_io_for_flush_and_compaction
);
173 DECLARE_bool(mock_direct_io
);
174 DECLARE_bool(statistics
);
176 DECLARE_bool(use_fsync
);
177 DECLARE_uint64(stats_dump_period_sec
);
178 DECLARE_uint64(bytes_per_sync
);
179 DECLARE_uint64(wal_bytes_per_sync
);
180 DECLARE_int32(kill_random_test
);
181 DECLARE_string(kill_exclude_prefixes
);
182 DECLARE_bool(disable_wal
);
183 DECLARE_uint64(recycle_log_file_num
);
184 DECLARE_int64(target_file_size_base
);
185 DECLARE_int32(target_file_size_multiplier
);
186 DECLARE_uint64(max_bytes_for_level_base
);
187 DECLARE_double(max_bytes_for_level_multiplier
);
188 DECLARE_int32(range_deletion_width
);
189 DECLARE_uint64(rate_limiter_bytes_per_sec
);
190 DECLARE_bool(rate_limit_bg_reads
);
191 DECLARE_bool(rate_limit_user_ops
);
192 DECLARE_bool(rate_limit_auto_wal_flush
);
193 DECLARE_uint64(sst_file_manager_bytes_per_sec
);
194 DECLARE_uint64(sst_file_manager_bytes_per_truncate
);
195 DECLARE_bool(use_txn
);
196 DECLARE_uint64(txn_write_policy
);
197 DECLARE_bool(unordered_write
);
198 DECLARE_int32(backup_one_in
);
199 DECLARE_uint64(backup_max_size
);
200 DECLARE_int32(checkpoint_one_in
);
201 DECLARE_int32(ingest_external_file_one_in
);
202 DECLARE_int32(ingest_external_file_width
);
203 DECLARE_int32(compact_files_one_in
);
204 DECLARE_int32(compact_range_one_in
);
205 DECLARE_int32(mark_for_compaction_one_file_in
);
206 DECLARE_int32(flush_one_in
);
207 DECLARE_int32(pause_background_one_in
);
208 DECLARE_int32(compact_range_width
);
209 DECLARE_int32(acquire_snapshot_one_in
);
210 DECLARE_bool(compare_full_db_state_snapshot
);
211 DECLARE_uint64(snapshot_hold_ops
);
212 DECLARE_bool(long_running_snapshots
);
213 DECLARE_bool(use_multiget
);
214 DECLARE_int32(readpercent
);
215 DECLARE_int32(prefixpercent
);
216 DECLARE_int32(writepercent
);
217 DECLARE_int32(delpercent
);
218 DECLARE_int32(delrangepercent
);
219 DECLARE_int32(nooverwritepercent
);
220 DECLARE_int32(iterpercent
);
221 DECLARE_uint64(num_iterations
);
222 DECLARE_int32(customopspercent
);
223 DECLARE_string(compression_type
);
224 DECLARE_string(bottommost_compression_type
);
225 DECLARE_int32(compression_max_dict_bytes
);
226 DECLARE_int32(compression_zstd_max_train_bytes
);
227 DECLARE_int32(compression_parallel_threads
);
228 DECLARE_uint64(compression_max_dict_buffer_bytes
);
229 DECLARE_bool(compression_use_zstd_dict_trainer
);
230 DECLARE_string(checksum_type
);
231 DECLARE_string(env_uri
);
232 DECLARE_string(fs_uri
);
233 DECLARE_uint64(ops_per_thread
);
234 DECLARE_uint64(log2_keys_per_lock
);
235 DECLARE_uint64(max_manifest_file_size
);
236 DECLARE_bool(in_place_update
);
237 DECLARE_string(memtablerep
);
238 DECLARE_int32(prefix_size
);
239 DECLARE_bool(use_merge
);
240 DECLARE_uint32(use_put_entity_one_in
);
241 DECLARE_bool(use_full_merge_v1
);
242 DECLARE_int32(sync_wal_one_in
);
243 DECLARE_bool(avoid_unnecessary_blocking_io
);
244 DECLARE_bool(write_dbid_to_manifest
);
245 DECLARE_bool(avoid_flush_during_recovery
);
246 DECLARE_uint64(max_write_batch_group_size_bytes
);
247 DECLARE_bool(level_compaction_dynamic_level_bytes
);
248 DECLARE_int32(verify_checksum_one_in
);
249 DECLARE_int32(verify_db_one_in
);
250 DECLARE_int32(continuous_verification_interval
);
251 DECLARE_int32(get_property_one_in
);
252 DECLARE_string(file_checksum_impl
);
255 // Options for StackableDB-based BlobDB
256 DECLARE_bool(use_blob_db
);
257 DECLARE_uint64(blob_db_min_blob_size
);
258 DECLARE_uint64(blob_db_bytes_per_sync
);
259 DECLARE_uint64(blob_db_file_size
);
260 DECLARE_bool(blob_db_enable_gc
);
261 DECLARE_double(blob_db_gc_cutoff
);
262 #endif // !ROCKSDB_LITE
264 // Options for integrated BlobDB
265 DECLARE_bool(allow_setting_blob_options_dynamically
);
266 DECLARE_bool(enable_blob_files
);
267 DECLARE_uint64(min_blob_size
);
268 DECLARE_uint64(blob_file_size
);
269 DECLARE_string(blob_compression_type
);
270 DECLARE_bool(enable_blob_garbage_collection
);
271 DECLARE_double(blob_garbage_collection_age_cutoff
);
272 DECLARE_double(blob_garbage_collection_force_threshold
);
273 DECLARE_uint64(blob_compaction_readahead_size
);
274 DECLARE_int32(blob_file_starting_level
);
275 DECLARE_bool(use_blob_cache
);
276 DECLARE_bool(use_shared_block_and_blob_cache
);
277 DECLARE_uint64(blob_cache_size
);
278 DECLARE_int32(blob_cache_numshardbits
);
279 DECLARE_int32(prepopulate_blob_cache
);
281 DECLARE_int32(approximate_size_one_in
);
282 DECLARE_bool(sync_fault_injection
);
284 DECLARE_bool(best_efforts_recovery
);
285 DECLARE_bool(skip_verifydb
);
286 DECLARE_bool(enable_compaction_filter
);
287 DECLARE_bool(paranoid_file_checks
);
288 DECLARE_bool(fail_if_options_file_error
);
289 DECLARE_uint64(batch_protection_bytes_per_key
);
290 DECLARE_uint32(memtable_protection_bytes_per_key
);
292 DECLARE_uint64(user_timestamp_size
);
293 DECLARE_string(secondary_cache_uri
);
294 DECLARE_int32(secondary_cache_fault_one_in
);
296 DECLARE_int32(prepopulate_block_cache
);
298 DECLARE_bool(two_write_queues
);
300 DECLARE_bool(use_only_the_last_commit_time_batch_for_recovery
);
301 DECLARE_uint64(wp_snapshot_cache_bits
);
302 DECLARE_uint64(wp_commit_cache_bits
);
303 #endif // !ROCKSDB_LITE
305 DECLARE_bool(adaptive_readahead
);
306 DECLARE_bool(async_io
);
307 DECLARE_string(wal_compression
);
308 DECLARE_bool(verify_sst_unique_id_in_manifest
);
310 DECLARE_int32(create_timestamped_snapshot_one_in
);
312 DECLARE_bool(allow_data_in_errors
);
315 DECLARE_bool(enable_tiered_storage
); // set last_level_temperature
316 DECLARE_int64(preclude_last_level_data_seconds
);
317 DECLARE_int64(preserve_internal_time_seconds
);
319 DECLARE_int32(verify_iterator_with_expected_state_one_in
);
320 DECLARE_bool(preserve_unverified_changes
);
322 DECLARE_uint64(readahead_size
);
323 DECLARE_uint64(initial_auto_readahead_size
);
324 DECLARE_uint64(max_auto_readahead_size
);
325 DECLARE_uint64(num_file_reads_for_auto_readahead
);
327 constexpr long KB
= 1024;
328 constexpr int kRandomValueMaxFactor
= 3;
329 constexpr int kValueMaxLen
= 100;
331 // wrapped posix environment
332 extern ROCKSDB_NAMESPACE::Env
* db_stress_env
;
333 extern ROCKSDB_NAMESPACE::Env
* db_stress_listener_env
;
334 extern std::shared_ptr
<ROCKSDB_NAMESPACE::FaultInjectionTestFS
> fault_fs_guard
;
336 extern enum ROCKSDB_NAMESPACE::CompressionType compression_type_e
;
337 extern enum ROCKSDB_NAMESPACE::CompressionType bottommost_compression_type_e
;
338 extern enum ROCKSDB_NAMESPACE::ChecksumType checksum_type_e
;
340 enum RepFactory
{ kSkipList
, kHashSkipList
, kVectorRep
};
342 inline enum RepFactory
StringToRepFactory(const char* ctype
) {
345 if (!strcasecmp(ctype
, "skip_list"))
347 else if (!strcasecmp(ctype
, "prefix_hash"))
348 return kHashSkipList
;
349 else if (!strcasecmp(ctype
, "vector"))
352 fprintf(stdout
, "Cannot parse memreptable %s\n", ctype
);
356 extern enum RepFactory FLAGS_rep_factory
;
358 namespace ROCKSDB_NAMESPACE
{
359 inline enum ROCKSDB_NAMESPACE::CompressionType
StringToCompressionType(
363 ROCKSDB_NAMESPACE::CompressionType ret_compression_type
;
365 if (!strcasecmp(ctype
, "disable")) {
366 ret_compression_type
= ROCKSDB_NAMESPACE::kDisableCompressionOption
;
367 } else if (!strcasecmp(ctype
, "none")) {
368 ret_compression_type
= ROCKSDB_NAMESPACE::kNoCompression
;
369 } else if (!strcasecmp(ctype
, "snappy")) {
370 ret_compression_type
= ROCKSDB_NAMESPACE::kSnappyCompression
;
371 } else if (!strcasecmp(ctype
, "zlib")) {
372 ret_compression_type
= ROCKSDB_NAMESPACE::kZlibCompression
;
373 } else if (!strcasecmp(ctype
, "bzip2")) {
374 ret_compression_type
= ROCKSDB_NAMESPACE::kBZip2Compression
;
375 } else if (!strcasecmp(ctype
, "lz4")) {
376 ret_compression_type
= ROCKSDB_NAMESPACE::kLZ4Compression
;
377 } else if (!strcasecmp(ctype
, "lz4hc")) {
378 ret_compression_type
= ROCKSDB_NAMESPACE::kLZ4HCCompression
;
379 } else if (!strcasecmp(ctype
, "xpress")) {
380 ret_compression_type
= ROCKSDB_NAMESPACE::kXpressCompression
;
381 } else if (!strcasecmp(ctype
, "zstd")) {
382 ret_compression_type
= ROCKSDB_NAMESPACE::kZSTD
;
384 fprintf(stderr
, "Cannot parse compression type '%s'\n", ctype
);
385 ret_compression_type
=
386 ROCKSDB_NAMESPACE::kSnappyCompression
; // default value
388 if (ret_compression_type
!= ROCKSDB_NAMESPACE::kDisableCompressionOption
&&
389 !CompressionTypeSupported(ret_compression_type
)) {
390 // Use no compression will be more portable but considering this is
391 // only a stress test and snappy is widely available. Use snappy here.
392 ret_compression_type
= ROCKSDB_NAMESPACE::kSnappyCompression
;
394 return ret_compression_type
;
397 inline enum ROCKSDB_NAMESPACE::ChecksumType
StringToChecksumType(
400 auto iter
= ROCKSDB_NAMESPACE::checksum_type_string_map
.find(ctype
);
401 if (iter
!= ROCKSDB_NAMESPACE::checksum_type_string_map
.end()) {
404 fprintf(stderr
, "Cannot parse checksum type '%s'\n", ctype
);
405 return ROCKSDB_NAMESPACE::kCRC32c
;
408 inline std::string
ChecksumTypeToString(ROCKSDB_NAMESPACE::ChecksumType ctype
) {
409 auto iter
= std::find_if(
410 ROCKSDB_NAMESPACE::checksum_type_string_map
.begin(),
411 ROCKSDB_NAMESPACE::checksum_type_string_map
.end(),
412 [&](const std::pair
<std::string
, ROCKSDB_NAMESPACE::ChecksumType
>&
413 name_and_enum_val
) { return name_and_enum_val
.second
== ctype
; });
414 assert(iter
!= ROCKSDB_NAMESPACE::checksum_type_string_map
.end());
418 inline std::vector
<std::string
> SplitString(std::string src
) {
419 std::vector
<std::string
> ret
;
425 while ((pos_comma
= src
.find(',', pos
)) != std::string::npos
) {
426 ret
.push_back(src
.substr(pos
, pos_comma
- pos
));
429 ret
.push_back(src
.substr(pos
, src
.length()));
434 #pragma warning(push)
435 // truncation of constant value on static_cast
436 #pragma warning(disable : 4309)
438 inline bool GetNextPrefix(const ROCKSDB_NAMESPACE::Slice
& src
, std::string
* v
) {
439 std::string ret
= src
.ToString();
440 for (int i
= static_cast<int>(ret
.size()) - 1; i
>= 0; i
--) {
441 if (ret
[i
] != static_cast<char>(255)) {
447 // all FF. No next prefix
458 // Append `val` to `*key` in fixed-width big-endian format
459 extern inline void AppendIntToString(uint64_t val
, std::string
* key
) {
460 // PutFixed64 uses little endian
461 PutFixed64(key
, val
);
462 // Reverse to get big endian
463 char* int_data
= &((*key
)[key
->size() - sizeof(uint64_t)]);
464 for (size_t i
= 0; i
< sizeof(uint64_t) / 2; ++i
) {
465 std::swap(int_data
[i
], int_data
[sizeof(uint64_t) - 1 - i
]);
469 // A struct for maintaining the parameters for generating variable length keys
470 struct KeyGenContext
{
471 // Number of adjacent keys in one cycle of key lengths
473 // Number of keys of each possible length in a given window
474 std::vector
<uint64_t> weights
;
476 extern KeyGenContext key_gen_ctx
;
478 // Generate a variable length key string from the given int64 val. The
479 // order of the keys is preserved. The key could be anywhere from 8 to
480 // max_key_len * 8 bytes.
481 // The algorithm picks the length based on the
482 // offset of the val within a configured window and the distribution of the
483 // number of keys of various lengths in that window. For example, if x, y, x are
484 // the weights assigned to each possible key length, the keys generated would be
486 // {(x-1),0}..{(x-1),(y-1)},{(x-1),(y-1),0}..{(x-1),(y-1),(z-1)} and so on.
487 // Additionally, a trailer of 0-7 bytes could be appended.
488 extern inline std::string
Key(int64_t val
) {
489 uint64_t window
= key_gen_ctx
.window
;
490 size_t levels
= key_gen_ctx
.weights
.size();
492 // Over-reserve and for now do not bother `shrink_to_fit()` since the key
493 // strings are transient.
494 key
.reserve(FLAGS_max_key_len
* 8);
496 uint64_t window_idx
= static_cast<uint64_t>(val
) / window
;
497 uint64_t offset
= static_cast<uint64_t>(val
) % window
;
498 for (size_t level
= 0; level
< levels
; ++level
) {
499 uint64_t weight
= key_gen_ctx
.weights
[level
];
502 pfx
= window_idx
* weight
;
506 pfx
+= offset
>= weight
? weight
- 1 : offset
;
507 AppendIntToString(pfx
, &key
);
508 if (offset
< weight
) {
509 // Use the bottom 3 bits of offset as the number of trailing 'x's in the
510 // key. If the next key is going to be of the next level, then skip the
511 // trailer as it would break ordering. If the key length is already at
512 // max, skip the trailer.
513 if (offset
< weight
- 1 && level
< levels
- 1) {
514 size_t trailer_len
= offset
& 0x7;
515 key
.append(trailer_len
, 'x');
525 // Given a string key, map it to an index into the expected values buffer
526 extern inline bool GetIntVal(std::string big_endian_key
, uint64_t* key_p
) {
527 size_t size_key
= big_endian_key
.size();
528 std::vector
<uint64_t> prefixes
;
530 assert(size_key
<= key_gen_ctx
.weights
.size() * sizeof(uint64_t));
532 std::string little_endian_key
;
533 little_endian_key
.resize(size_key
);
534 for (size_t start
= 0; start
+ sizeof(uint64_t) <= size_key
;
535 start
+= sizeof(uint64_t)) {
536 size_t end
= start
+ sizeof(uint64_t);
537 for (size_t i
= 0; i
< sizeof(uint64_t); ++i
) {
538 little_endian_key
[start
+ i
] = big_endian_key
[end
- 1 - i
];
540 Slice little_endian_slice
=
541 Slice(&little_endian_key
[start
], sizeof(uint64_t));
543 if (!GetFixed64(&little_endian_slice
, &pfx
)) {
546 prefixes
.emplace_back(pfx
);
550 for (size_t i
= 0; i
< prefixes
.size(); ++i
) {
551 uint64_t pfx
= prefixes
[i
];
552 key
+= (pfx
/ key_gen_ctx
.weights
[i
]) * key_gen_ctx
.window
+
553 pfx
% key_gen_ctx
.weights
[i
];
554 if (i
< prefixes
.size() - 1) {
555 // The encoding writes a `key_gen_ctx.weights[i] - 1` that counts for
556 // `key_gen_ctx.weights[i]` when there are more prefixes to come. So we
557 // need to add back the one here as we're at a non-last prefix.
565 // Given a string prefix, map it to the first corresponding index in the
566 // expected values buffer.
567 inline bool GetFirstIntValInPrefix(std::string big_endian_prefix
,
569 size_t size_key
= big_endian_prefix
.size();
570 // Pad with zeros to make it a multiple of 8. This function may be called
571 // with a prefix, in which case we return the first index that falls
572 // inside or outside that prefix, dependeing on whether the prefix is
573 // the start of upper bound of a scan
574 unsigned int pad
= sizeof(uint64_t) - (size_key
% sizeof(uint64_t));
575 if (pad
< sizeof(uint64_t)) {
576 big_endian_prefix
.append(pad
, '\0');
578 return GetIntVal(std::move(big_endian_prefix
), key_p
);
581 extern inline uint64_t GetPrefixKeyCount(const std::string
& prefix
,
582 const std::string
& ub
) {
586 if (!GetFirstIntValInPrefix(prefix
, &start
) ||
587 !GetFirstIntValInPrefix(ub
, &end
)) {
594 extern inline std::string
StringToHex(const std::string
& str
) {
595 std::string result
= "0x";
596 result
.append(Slice(str
).ToString(true));
600 // Unified output format for double parameters
601 extern inline std::string
FormatDoubleParam(double param
) {
602 return std::to_string(param
);
605 // Make sure that double parameter is a value we can reproduce by
606 // re-inputting the value printed.
607 extern inline void SanitizeDoubleParam(double* param
) {
608 *param
= std::atof(FormatDoubleParam(*param
).c_str());
611 extern void PoolSizeChangeThread(void* v
);
613 extern void DbVerificationThread(void* v
);
615 extern void TimestampedSnapshotsThread(void* v
);
617 extern void PrintKeyValue(int cf
, uint64_t key
, const char* value
, size_t sz
);
619 extern int64_t GenerateOneKey(ThreadState
* thread
, uint64_t iteration
);
621 extern std::vector
<int64_t> GenerateNKeys(ThreadState
* thread
, int num_keys
,
624 extern size_t GenerateValue(uint32_t rand
, char* v
, size_t max_sz
);
625 extern uint32_t GetValueBase(Slice s
);
627 extern WideColumns
GenerateWideColumns(uint32_t value_base
, const Slice
& slice
);
628 extern WideColumns
GenerateExpectedWideColumns(uint32_t value_base
,
631 extern StressTest
* CreateCfConsistencyStressTest();
632 extern StressTest
* CreateBatchedOpsStressTest();
633 extern StressTest
* CreateNonBatchedOpsStressTest();
634 extern StressTest
* CreateMultiOpsTxnsStressTest();
635 extern void CheckAndSetOptionsForMultiOpsTxnStressTest();
636 extern void InitializeHotKeyGenerator(double alpha
);
637 extern int64_t GetOneHotKeyID(double rand_seed
, int64_t max_key
);
639 extern std::string
GetNowNanos();
641 std::shared_ptr
<FileChecksumGenFactory
> GetFileChecksumImpl(
642 const std::string
& name
);
644 Status
DeleteFilesInDirectory(const std::string
& dirname
);
645 Status
SaveFilesInDirectory(const std::string
& src_dirname
,
646 const std::string
& dst_dirname
);
647 Status
DestroyUnverifiedSubdir(const std::string
& dirname
);
648 Status
InitUnverifiedSubdir(const std::string
& dirname
);
649 } // namespace ROCKSDB_NAMESPACE