diff --git a/db_stress_tool/db_stress_common.h b/db_stress_tool/db_stress_common.h index 06e69977e..a3b6e80eb 100644 --- a/db_stress_tool/db_stress_common.h +++ b/db_stress_tool/db_stress_common.h @@ -407,17 +407,15 @@ inline bool GetNextPrefix(const ROCKSDB_NAMESPACE::Slice& src, std::string* v) { #pragma warning(pop) #endif -// convert long to a big-endian slice key -extern inline std::string GetStringFromInt(int64_t val) { - std::string little_endian_key; - std::string big_endian_key; - PutFixed64(&little_endian_key, val); - assert(little_endian_key.size() == sizeof(val)); - big_endian_key.resize(sizeof(val)); - for (size_t i = 0; i < sizeof(val); ++i) { - big_endian_key[i] = little_endian_key[sizeof(val) - 1 - i]; +// Append `val` to `*key` in fixed-width big-endian format +extern inline void AppendIntToString(uint64_t val, std::string* key) { + // PutFixed64 uses little endian + PutFixed64(key, val); + // Reverse to get big endian + char* int_data = &((*key)[key->size() - sizeof(uint64_t)]); + for (size_t i = 0; i < sizeof(uint64_t) / 2; ++i) { + std::swap(int_data[i], int_data[sizeof(uint64_t) - 1 - i]); } - return big_endian_key; } // A struct for maintaining the parameters for generating variable length keys @@ -443,13 +441,22 @@ extern inline std::string Key(int64_t val) { uint64_t window = key_gen_ctx.window; size_t levels = key_gen_ctx.weights.size(); std::string key; + // Over-reserve and for now do not bother `shrink_to_fit()` since the key + // strings are transient. + key.reserve(FLAGS_max_key_len * 8); + uint64_t window_idx = static_cast(val) / window; + uint64_t offset = static_cast(val) % window; for (size_t level = 0; level < levels; ++level) { uint64_t weight = key_gen_ctx.weights[level]; - uint64_t offset = static_cast(val) % window; - uint64_t mult = static_cast(val) / window; - uint64_t pfx = mult * weight + (offset >= weight ? weight - 1 : offset); - key.append(GetStringFromInt(pfx)); + uint64_t pfx; + if (level == 0) { + pfx = window_idx * weight; + } else { + pfx = 0; + } + pfx += offset >= weight ? weight - 1 : offset; + AppendIntToString(pfx, &key); if (offset < weight) { // Use the bottom 3 bits of offset as the number of trailing 'x's in the // key. If the next key is going to be of the next level, then skip the @@ -461,8 +468,7 @@ extern inline std::string Key(int64_t val) { } break; } - val = offset - weight; - window -= weight; + offset -= weight; } return key; diff --git a/db_stress_tool/db_stress_shared_state.h b/db_stress_tool/db_stress_shared_state.h index ddfb67261..e7eb4aade 100644 --- a/db_stress_tool/db_stress_shared_state.h +++ b/db_stress_tool/db_stress_shared_state.h @@ -158,10 +158,7 @@ class SharedState { key_locks_.resize(FLAGS_column_families); for (int i = 0; i < FLAGS_column_families; ++i) { - key_locks_[i].resize(num_locks); - for (auto& ptr : key_locks_[i]) { - ptr.reset(new port::Mutex); - } + key_locks_[i].reset(new port::Mutex[num_locks]); } #ifndef NDEBUG if (FLAGS_read_fault_one_in) { @@ -227,20 +224,20 @@ class SharedState { // Returns a lock covering `key` in `cf`. port::Mutex* GetMutexForKey(int cf, int64_t key) { - return key_locks_[cf][key >> log2_keys_per_lock_].get(); + return &key_locks_[cf][key >> log2_keys_per_lock_]; } // Acquires locks for all keys in `cf`. void LockColumnFamily(int cf) { - for (auto& mutex : key_locks_[cf]) { - mutex->Lock(); + for (int i = 0; i < max_key_ >> log2_keys_per_lock_; ++i) { + key_locks_[cf][i].Lock(); } } // Releases locks for all keys in `cf`. void UnlockColumnFamily(int cf) { - for (auto& mutex : key_locks_[cf]) { - mutex->Unlock(); + for (int i = 0; i < max_key_ >> log2_keys_per_lock_; ++i) { + key_locks_[cf][i].Unlock(); } } @@ -361,9 +358,9 @@ class SharedState { std::unordered_set no_overwrite_ids_; std::unique_ptr expected_state_manager_; - // Has to make it owned by a smart ptr as port::Mutex is not copyable + // Cannot store `port::Mutex` directly in vector since it is not copyable // and storing it in the container may require copying depending on the impl. - std::vector>> key_locks_; + std::vector> key_locks_; std::atomic printing_verification_results_; }; diff --git a/db_stress_tool/expected_state.cc b/db_stress_tool/expected_state.cc index c787ff757..487ad193f 100644 --- a/db_stress_tool/expected_state.cc +++ b/db_stress_tool/expected_state.cc @@ -78,7 +78,8 @@ bool ExpectedState::Exists(int cf, int64_t key) { void ExpectedState::Reset() { for (size_t i = 0; i < num_column_families_; ++i) { for (size_t j = 0; j < max_key_; ++j) { - Delete(static_cast(i), j, false /* pending */); + Value(static_cast(i), j) + .store(SharedState::DELETION_SENTINEL, std::memory_order_relaxed); } } }