db_stress_common.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  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. // 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.
  9. //
  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.
  13. // Space is reserved in the array from 0 to FLAGS_max_key and values are
  14. // randomly written/deleted/read from those positions. During verification we
  15. // compare all the positions in the array. To shorten/elongate the running
  16. // time, you could change the settings: FLAGS_max_key, FLAGS_ops_per_thread,
  17. // (sometimes also FLAGS_threads).
  18. //
  19. // NOTE that if FLAGS_test_batches_snapshots is set, the test will have
  20. // different behavior. See comment of the flag for details.
  21. #ifdef GFLAGS
  22. #pragma once
  23. #include <fcntl.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <sys/types.h>
  27. #include <algorithm>
  28. #include <array>
  29. #include <chrono>
  30. #include <cinttypes>
  31. #include <exception>
  32. #include <queue>
  33. #include <thread>
  34. #include "db/db_impl/db_impl.h"
  35. #include "db/version_set.h"
  36. #include "db_stress_tool/db_stress_env_wrapper.h"
  37. #include "db_stress_tool/db_stress_listener.h"
  38. #include "db_stress_tool/db_stress_shared_state.h"
  39. #include "db_stress_tool/db_stress_test_base.h"
  40. #include "hdfs/env_hdfs.h"
  41. #include "logging/logging.h"
  42. #include "monitoring/histogram.h"
  43. #include "options/options_helper.h"
  44. #include "port/port.h"
  45. #include "rocksdb/cache.h"
  46. #include "rocksdb/env.h"
  47. #include "rocksdb/slice.h"
  48. #include "rocksdb/slice_transform.h"
  49. #include "rocksdb/statistics.h"
  50. #include "rocksdb/utilities/backupable_db.h"
  51. #include "rocksdb/utilities/checkpoint.h"
  52. #include "rocksdb/utilities/db_ttl.h"
  53. #include "rocksdb/utilities/debug.h"
  54. #include "rocksdb/utilities/options_util.h"
  55. #include "rocksdb/utilities/transaction.h"
  56. #include "rocksdb/utilities/transaction_db.h"
  57. #include "rocksdb/write_batch.h"
  58. #include "util/coding.h"
  59. #include "util/compression.h"
  60. #include "util/crc32c.h"
  61. #include "util/gflags_compat.h"
  62. #include "util/mutexlock.h"
  63. #include "util/random.h"
  64. #include "util/string_util.h"
  65. #include "utilities/blob_db/blob_db.h"
  66. // SyncPoint is not supported in Released Windows Mode.
  67. #if !(defined NDEBUG) || !defined(OS_WIN)
  68. #include "test_util/sync_point.h"
  69. #endif // !(defined NDEBUG) || !defined(OS_WIN)
  70. #include "test_util/testutil.h"
  71. #include "utilities/merge_operators.h"
  72. using GFLAGS_NAMESPACE::ParseCommandLineFlags;
  73. using GFLAGS_NAMESPACE::RegisterFlagValidator;
  74. using GFLAGS_NAMESPACE::SetUsageMessage;
  75. DECLARE_uint64(seed);
  76. DECLARE_bool(read_only);
  77. DECLARE_int64(max_key);
  78. DECLARE_double(hot_key_alpha);
  79. DECLARE_int32(max_key_len);
  80. DECLARE_string(key_len_percent_dist);
  81. DECLARE_int32(key_window_scale_factor);
  82. DECLARE_int32(column_families);
  83. DECLARE_string(options_file);
  84. DECLARE_int64(active_width);
  85. DECLARE_bool(test_batches_snapshots);
  86. DECLARE_bool(atomic_flush);
  87. DECLARE_bool(test_cf_consistency);
  88. DECLARE_int32(threads);
  89. DECLARE_int32(ttl);
  90. DECLARE_int32(value_size_mult);
  91. DECLARE_int32(compaction_readahead_size);
  92. DECLARE_bool(enable_pipelined_write);
  93. DECLARE_bool(verify_before_write);
  94. DECLARE_bool(histogram);
  95. DECLARE_bool(destroy_db_initially);
  96. DECLARE_bool(verbose);
  97. DECLARE_bool(progress_reports);
  98. DECLARE_uint64(db_write_buffer_size);
  99. DECLARE_int32(write_buffer_size);
  100. DECLARE_int32(max_write_buffer_number);
  101. DECLARE_int32(min_write_buffer_number_to_merge);
  102. DECLARE_int32(max_write_buffer_number_to_maintain);
  103. DECLARE_int64(max_write_buffer_size_to_maintain);
  104. DECLARE_double(memtable_prefix_bloom_size_ratio);
  105. DECLARE_bool(memtable_whole_key_filtering);
  106. DECLARE_int32(open_files);
  107. DECLARE_int64(compressed_cache_size);
  108. DECLARE_int32(compaction_style);
  109. DECLARE_int32(level0_file_num_compaction_trigger);
  110. DECLARE_int32(level0_slowdown_writes_trigger);
  111. DECLARE_int32(level0_stop_writes_trigger);
  112. DECLARE_int32(block_size);
  113. DECLARE_int32(format_version);
  114. DECLARE_int32(index_block_restart_interval);
  115. DECLARE_int32(max_background_compactions);
  116. DECLARE_int32(num_bottom_pri_threads);
  117. DECLARE_int32(compaction_thread_pool_adjust_interval);
  118. DECLARE_int32(compaction_thread_pool_variations);
  119. DECLARE_int32(max_background_flushes);
  120. DECLARE_int32(universal_size_ratio);
  121. DECLARE_int32(universal_min_merge_width);
  122. DECLARE_int32(universal_max_merge_width);
  123. DECLARE_int32(universal_max_size_amplification_percent);
  124. DECLARE_int32(clear_column_family_one_in);
  125. DECLARE_int32(get_live_files_and_wal_files_one_in);
  126. DECLARE_int32(set_options_one_in);
  127. DECLARE_int32(set_in_place_one_in);
  128. DECLARE_int64(cache_size);
  129. DECLARE_bool(cache_index_and_filter_blocks);
  130. DECLARE_bool(use_clock_cache);
  131. DECLARE_uint64(subcompactions);
  132. DECLARE_uint64(periodic_compaction_seconds);
  133. DECLARE_uint64(compaction_ttl);
  134. DECLARE_bool(allow_concurrent_memtable_write);
  135. DECLARE_bool(enable_write_thread_adaptive_yield);
  136. DECLARE_int32(reopen);
  137. DECLARE_double(bloom_bits);
  138. DECLARE_bool(use_block_based_filter);
  139. DECLARE_bool(partition_filters);
  140. DECLARE_int32(index_type);
  141. DECLARE_string(db);
  142. DECLARE_string(secondaries_base);
  143. DECLARE_bool(test_secondary);
  144. DECLARE_string(expected_values_path);
  145. DECLARE_bool(verify_checksum);
  146. DECLARE_bool(mmap_read);
  147. DECLARE_bool(mmap_write);
  148. DECLARE_bool(use_direct_reads);
  149. DECLARE_bool(use_direct_io_for_flush_and_compaction);
  150. DECLARE_bool(statistics);
  151. DECLARE_bool(sync);
  152. DECLARE_bool(use_fsync);
  153. DECLARE_int32(kill_random_test);
  154. DECLARE_string(kill_prefix_blacklist);
  155. DECLARE_bool(disable_wal);
  156. DECLARE_uint64(recycle_log_file_num);
  157. DECLARE_int64(target_file_size_base);
  158. DECLARE_int32(target_file_size_multiplier);
  159. DECLARE_uint64(max_bytes_for_level_base);
  160. DECLARE_double(max_bytes_for_level_multiplier);
  161. DECLARE_int32(range_deletion_width);
  162. DECLARE_uint64(rate_limiter_bytes_per_sec);
  163. DECLARE_bool(rate_limit_bg_reads);
  164. DECLARE_bool(use_txn);
  165. DECLARE_uint64(txn_write_policy);
  166. DECLARE_bool(unordered_write);
  167. DECLARE_int32(backup_one_in);
  168. DECLARE_int32(checkpoint_one_in);
  169. DECLARE_int32(ingest_external_file_one_in);
  170. DECLARE_int32(ingest_external_file_width);
  171. DECLARE_int32(compact_files_one_in);
  172. DECLARE_int32(compact_range_one_in);
  173. DECLARE_int32(flush_one_in);
  174. DECLARE_int32(pause_background_one_in);
  175. DECLARE_int32(compact_range_width);
  176. DECLARE_int32(acquire_snapshot_one_in);
  177. DECLARE_bool(compare_full_db_state_snapshot);
  178. DECLARE_uint64(snapshot_hold_ops);
  179. DECLARE_bool(long_running_snapshots);
  180. DECLARE_bool(use_multiget);
  181. DECLARE_int32(readpercent);
  182. DECLARE_int32(prefixpercent);
  183. DECLARE_int32(writepercent);
  184. DECLARE_int32(delpercent);
  185. DECLARE_int32(delrangepercent);
  186. DECLARE_int32(nooverwritepercent);
  187. DECLARE_int32(iterpercent);
  188. DECLARE_uint64(num_iterations);
  189. DECLARE_string(compression_type);
  190. DECLARE_string(bottommost_compression_type);
  191. DECLARE_int32(compression_max_dict_bytes);
  192. DECLARE_int32(compression_zstd_max_train_bytes);
  193. DECLARE_string(checksum_type);
  194. DECLARE_string(hdfs);
  195. DECLARE_string(env_uri);
  196. DECLARE_uint64(ops_per_thread);
  197. DECLARE_uint64(log2_keys_per_lock);
  198. DECLARE_uint64(max_manifest_file_size);
  199. DECLARE_bool(in_place_update);
  200. DECLARE_int32(secondary_catch_up_one_in);
  201. DECLARE_string(memtablerep);
  202. DECLARE_int32(prefix_size);
  203. DECLARE_bool(use_merge);
  204. DECLARE_bool(use_full_merge_v1);
  205. DECLARE_int32(sync_wal_one_in);
  206. DECLARE_bool(avoid_unnecessary_blocking_io);
  207. DECLARE_bool(write_dbid_to_manifest);
  208. DECLARE_uint64(max_write_batch_group_size_bytes);
  209. DECLARE_bool(level_compaction_dynamic_level_bytes);
  210. DECLARE_int32(verify_checksum_one_in);
  211. DECLARE_int32(verify_db_one_in);
  212. DECLARE_int32(continuous_verification_interval);
  213. #ifndef ROCKSDB_LITE
  214. DECLARE_bool(use_blob_db);
  215. DECLARE_uint64(blob_db_min_blob_size);
  216. DECLARE_uint64(blob_db_bytes_per_sync);
  217. DECLARE_uint64(blob_db_file_size);
  218. DECLARE_bool(blob_db_enable_gc);
  219. DECLARE_double(blob_db_gc_cutoff);
  220. #endif // !ROCKSDB_LITE
  221. DECLARE_int32(approximate_size_one_in);
  222. const long KB = 1024;
  223. const int kRandomValueMaxFactor = 3;
  224. const int kValueMaxLen = 100;
  225. // wrapped posix or hdfs environment
  226. extern ROCKSDB_NAMESPACE::DbStressEnvWrapper* db_stress_env;
  227. extern enum ROCKSDB_NAMESPACE::CompressionType compression_type_e;
  228. extern enum ROCKSDB_NAMESPACE::CompressionType bottommost_compression_type_e;
  229. extern enum ROCKSDB_NAMESPACE::ChecksumType checksum_type_e;
  230. enum RepFactory { kSkipList, kHashSkipList, kVectorRep };
  231. inline enum RepFactory StringToRepFactory(const char* ctype) {
  232. assert(ctype);
  233. if (!strcasecmp(ctype, "skip_list"))
  234. return kSkipList;
  235. else if (!strcasecmp(ctype, "prefix_hash"))
  236. return kHashSkipList;
  237. else if (!strcasecmp(ctype, "vector"))
  238. return kVectorRep;
  239. fprintf(stdout, "Cannot parse memreptable %s\n", ctype);
  240. return kSkipList;
  241. }
  242. extern enum RepFactory FLAGS_rep_factory;
  243. namespace ROCKSDB_NAMESPACE {
  244. inline enum ROCKSDB_NAMESPACE::CompressionType StringToCompressionType(
  245. const char* ctype) {
  246. assert(ctype);
  247. ROCKSDB_NAMESPACE::CompressionType ret_compression_type;
  248. if (!strcasecmp(ctype, "disable")) {
  249. ret_compression_type = ROCKSDB_NAMESPACE::kDisableCompressionOption;
  250. } else if (!strcasecmp(ctype, "none")) {
  251. ret_compression_type = ROCKSDB_NAMESPACE::kNoCompression;
  252. } else if (!strcasecmp(ctype, "snappy")) {
  253. ret_compression_type = ROCKSDB_NAMESPACE::kSnappyCompression;
  254. } else if (!strcasecmp(ctype, "zlib")) {
  255. ret_compression_type = ROCKSDB_NAMESPACE::kZlibCompression;
  256. } else if (!strcasecmp(ctype, "bzip2")) {
  257. ret_compression_type = ROCKSDB_NAMESPACE::kBZip2Compression;
  258. } else if (!strcasecmp(ctype, "lz4")) {
  259. ret_compression_type = ROCKSDB_NAMESPACE::kLZ4Compression;
  260. } else if (!strcasecmp(ctype, "lz4hc")) {
  261. ret_compression_type = ROCKSDB_NAMESPACE::kLZ4HCCompression;
  262. } else if (!strcasecmp(ctype, "xpress")) {
  263. ret_compression_type = ROCKSDB_NAMESPACE::kXpressCompression;
  264. } else if (!strcasecmp(ctype, "zstd")) {
  265. ret_compression_type = ROCKSDB_NAMESPACE::kZSTD;
  266. } else {
  267. fprintf(stderr, "Cannot parse compression type '%s'\n", ctype);
  268. ret_compression_type =
  269. ROCKSDB_NAMESPACE::kSnappyCompression; // default value
  270. }
  271. if (ret_compression_type != ROCKSDB_NAMESPACE::kDisableCompressionOption &&
  272. !CompressionTypeSupported(ret_compression_type)) {
  273. // Use no compression will be more portable but considering this is
  274. // only a stress test and snappy is widely available. Use snappy here.
  275. ret_compression_type = ROCKSDB_NAMESPACE::kSnappyCompression;
  276. }
  277. return ret_compression_type;
  278. }
  279. inline enum ROCKSDB_NAMESPACE::ChecksumType StringToChecksumType(
  280. const char* ctype) {
  281. assert(ctype);
  282. auto iter = ROCKSDB_NAMESPACE::checksum_type_string_map.find(ctype);
  283. if (iter != ROCKSDB_NAMESPACE::checksum_type_string_map.end()) {
  284. return iter->second;
  285. }
  286. fprintf(stderr, "Cannot parse checksum type '%s'\n", ctype);
  287. return ROCKSDB_NAMESPACE::kCRC32c;
  288. }
  289. inline std::string ChecksumTypeToString(ROCKSDB_NAMESPACE::ChecksumType ctype) {
  290. auto iter = std::find_if(
  291. ROCKSDB_NAMESPACE::checksum_type_string_map.begin(),
  292. ROCKSDB_NAMESPACE::checksum_type_string_map.end(),
  293. [&](const std::pair<std::string, ROCKSDB_NAMESPACE::ChecksumType>&
  294. name_and_enum_val) { return name_and_enum_val.second == ctype; });
  295. assert(iter != ROCKSDB_NAMESPACE::checksum_type_string_map.end());
  296. return iter->first;
  297. }
  298. inline std::vector<std::string> SplitString(std::string src) {
  299. std::vector<std::string> ret;
  300. if (src.empty()) {
  301. return ret;
  302. }
  303. size_t pos = 0;
  304. size_t pos_comma;
  305. while ((pos_comma = src.find(',', pos)) != std::string::npos) {
  306. ret.push_back(src.substr(pos, pos_comma - pos));
  307. pos = pos_comma + 1;
  308. }
  309. ret.push_back(src.substr(pos, src.length()));
  310. return ret;
  311. }
  312. #ifdef _MSC_VER
  313. #pragma warning(push)
  314. // truncation of constant value on static_cast
  315. #pragma warning(disable : 4309)
  316. #endif
  317. inline bool GetNextPrefix(const ROCKSDB_NAMESPACE::Slice& src, std::string* v) {
  318. std::string ret = src.ToString();
  319. for (int i = static_cast<int>(ret.size()) - 1; i >= 0; i--) {
  320. if (ret[i] != static_cast<char>(255)) {
  321. ret[i] = ret[i] + 1;
  322. break;
  323. } else if (i != 0) {
  324. ret[i] = 0;
  325. } else {
  326. // all FF. No next prefix
  327. return false;
  328. }
  329. }
  330. *v = ret;
  331. return true;
  332. }
  333. #ifdef _MSC_VER
  334. #pragma warning(pop)
  335. #endif
  336. // convert long to a big-endian slice key
  337. extern inline std::string GetStringFromInt(int64_t val) {
  338. std::string little_endian_key;
  339. std::string big_endian_key;
  340. PutFixed64(&little_endian_key, val);
  341. assert(little_endian_key.size() == sizeof(val));
  342. big_endian_key.resize(sizeof(val));
  343. for (size_t i = 0; i < sizeof(val); ++i) {
  344. big_endian_key[i] = little_endian_key[sizeof(val) - 1 - i];
  345. }
  346. return big_endian_key;
  347. }
  348. // A struct for maintaining the parameters for generating variable length keys
  349. struct KeyGenContext {
  350. // Number of adjacent keys in one cycle of key lengths
  351. uint64_t window;
  352. // Number of keys of each possible length in a given window
  353. std::vector<uint64_t> weights;
  354. };
  355. extern KeyGenContext key_gen_ctx;
  356. // Generate a variable length key string from the given int64 val. The
  357. // order of the keys is preserved. The key could be anywhere from 8 to
  358. // max_key_len * 8 bytes.
  359. // The algorithm picks the length based on the
  360. // offset of the val within a configured window and the distribution of the
  361. // number of keys of various lengths in that window. For example, if x, y, x are
  362. // the weights assigned to each possible key length, the keys generated would be
  363. // - {0}...{x-1}
  364. // {(x-1),0}..{(x-1),(y-1)},{(x-1),(y-1),0}..{(x-1),(y-1),(z-1)} and so on.
  365. // Additionally, a trailer of 0-7 bytes could be appended.
  366. extern inline std::string Key(int64_t val) {
  367. uint64_t window = key_gen_ctx.window;
  368. size_t levels = key_gen_ctx.weights.size();
  369. std::string key;
  370. for (size_t level = 0; level < levels; ++level) {
  371. uint64_t weight = key_gen_ctx.weights[level];
  372. uint64_t offset = static_cast<uint64_t>(val) % window;
  373. uint64_t mult = static_cast<uint64_t>(val) / window;
  374. uint64_t pfx = mult * weight + (offset >= weight ? weight - 1 : offset);
  375. key.append(GetStringFromInt(pfx));
  376. if (offset < weight) {
  377. // Use the bottom 3 bits of offset as the number of trailing 'x's in the
  378. // key. If the next key is going to be of the next level, then skip the
  379. // trailer as it would break ordering. If the key length is already at max,
  380. // skip the trailer.
  381. if (offset < weight - 1 && level < levels - 1) {
  382. size_t trailer_len = offset & 0x7;
  383. key.append(trailer_len, 'x');
  384. }
  385. break;
  386. }
  387. val = offset - weight;
  388. window -= weight;
  389. }
  390. return key;
  391. }
  392. // Given a string key, map it to an index into the expected values buffer
  393. extern inline bool GetIntVal(std::string big_endian_key, uint64_t* key_p) {
  394. size_t size_key = big_endian_key.size();
  395. std::vector<uint64_t> prefixes;
  396. assert(size_key <= key_gen_ctx.weights.size() * sizeof(uint64_t));
  397. // Pad with zeros to make it a multiple of 8. This function may be called
  398. // with a prefix, in which case we return the first index that falls
  399. // inside or outside that prefix, dependeing on whether the prefix is
  400. // the start of upper bound of a scan
  401. unsigned int pad = sizeof(uint64_t) - (size_key % sizeof(uint64_t));
  402. if (pad < sizeof(uint64_t)) {
  403. big_endian_key.append(pad, '\0');
  404. size_key += pad;
  405. }
  406. std::string little_endian_key;
  407. little_endian_key.resize(size_key);
  408. for (size_t start = 0; start < size_key; start += sizeof(uint64_t)) {
  409. size_t end = start + sizeof(uint64_t);
  410. for (size_t i = 0; i < sizeof(uint64_t); ++i) {
  411. little_endian_key[start + i] = big_endian_key[end - 1 - i];
  412. }
  413. Slice little_endian_slice =
  414. Slice(&little_endian_key[start], sizeof(uint64_t));
  415. uint64_t pfx;
  416. if (!GetFixed64(&little_endian_slice, &pfx)) {
  417. return false;
  418. }
  419. prefixes.emplace_back(pfx);
  420. }
  421. uint64_t key = 0;
  422. for (size_t i = 0; i < prefixes.size(); ++i) {
  423. uint64_t pfx = prefixes[i];
  424. key += (pfx / key_gen_ctx.weights[i]) * key_gen_ctx.window +
  425. pfx % key_gen_ctx.weights[i];
  426. }
  427. *key_p = key;
  428. return true;
  429. }
  430. extern inline uint64_t GetPrefixKeyCount(const std::string& prefix,
  431. const std::string& ub) {
  432. uint64_t start = 0;
  433. uint64_t end = 0;
  434. if (!GetIntVal(prefix, &start) || !GetIntVal(ub, &end)) {
  435. return 0;
  436. }
  437. return end - start;
  438. }
  439. extern inline std::string StringToHex(const std::string& str) {
  440. std::string result = "0x";
  441. result.append(Slice(str).ToString(true));
  442. return result;
  443. }
  444. // Unified output format for double parameters
  445. extern inline std::string FormatDoubleParam(double param) {
  446. return std::to_string(param);
  447. }
  448. // Make sure that double parameter is a value we can reproduce by
  449. // re-inputting the value printed.
  450. extern inline void SanitizeDoubleParam(double* param) {
  451. *param = std::atof(FormatDoubleParam(*param).c_str());
  452. }
  453. extern void PoolSizeChangeThread(void* v);
  454. extern void DbVerificationThread(void* v);
  455. extern void PrintKeyValue(int cf, uint64_t key, const char* value, size_t sz);
  456. extern int64_t GenerateOneKey(ThreadState* thread, uint64_t iteration);
  457. extern std::vector<int64_t> GenerateNKeys(ThreadState* thread, int num_keys,
  458. uint64_t iteration);
  459. extern size_t GenerateValue(uint32_t rand, char* v, size_t max_sz);
  460. extern StressTest* CreateCfConsistencyStressTest();
  461. extern StressTest* CreateBatchedOpsStressTest();
  462. extern StressTest* CreateNonBatchedOpsStressTest();
  463. extern void InitializeHotKeyGenerator(double alpha);
  464. extern int64_t GetOneHotKeyID(double rand_seed, int64_t max_key);
  465. } // namespace ROCKSDB_NAMESPACE
  466. #endif // GFLAGS