expected_value.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. // Copyright (c) 2021-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. #ifdef GFLAGS
  6. #pragma once
  7. #include <stdint.h>
  8. #include <stdio.h>
  9. #include <atomic>
  10. #include <cassert>
  11. #include <memory>
  12. #include "rocksdb/rocksdb_namespace.h"
  13. namespace ROCKSDB_NAMESPACE {
  14. // `ExpectedValue` represents the expected value of a key used in db stress,
  15. // which provides APIs to obtain various information e.g, value base, existence,
  16. // pending operation status and APIs to edit expected value.
  17. //
  18. // This class is not thread-safe.
  19. class ExpectedValue {
  20. public:
  21. static uint32_t GetValueBaseMask() { return VALUE_BASE_MASK; }
  22. static uint32_t GetValueBaseDelta() { return VALUE_BASE_DELTA; }
  23. static uint32_t GetDelCounterDelta() { return DEL_COUNTER_DELTA; }
  24. static uint32_t GetDelMask() { return DEL_MASK; }
  25. static bool IsValueBaseValid(uint32_t value_base) {
  26. return IsValuePartValid(value_base, VALUE_BASE_MASK);
  27. }
  28. ExpectedValue() : expected_value_(DEL_MASK) {}
  29. explicit ExpectedValue(uint32_t expected_value)
  30. : expected_value_(expected_value) {}
  31. bool Exists() const {
  32. assert(!PendingWrite() && !PendingDelete());
  33. return !IsDeleted();
  34. }
  35. uint32_t Read() const { return expected_value_; }
  36. void Put(bool pending);
  37. bool Delete(bool pending);
  38. void SyncPut(uint32_t value_base);
  39. void SyncPendingPut();
  40. void SyncDelete();
  41. uint32_t GetValueBase() const { return GetValuePart(VALUE_BASE_MASK); }
  42. uint32_t NextValueBase() const {
  43. return GetIncrementedValuePart(VALUE_BASE_MASK, VALUE_BASE_DELTA);
  44. }
  45. void SetValueBase(uint32_t new_value_base) {
  46. SetValuePart(VALUE_BASE_MASK, new_value_base);
  47. }
  48. bool PendingWrite() const {
  49. const uint32_t pending_write = GetValuePart(PENDING_WRITE_MASK);
  50. return pending_write != 0;
  51. }
  52. void SetPendingWrite() {
  53. SetValuePart(PENDING_WRITE_MASK, PENDING_WRITE_MASK);
  54. }
  55. void ClearPendingWrite() { ClearValuePart(PENDING_WRITE_MASK); }
  56. uint32_t GetDelCounter() const { return GetValuePart(DEL_COUNTER_MASK); }
  57. uint32_t NextDelCounter() const {
  58. return GetIncrementedValuePart(DEL_COUNTER_MASK, DEL_COUNTER_DELTA);
  59. }
  60. void SetDelCounter(uint32_t new_del_counter) {
  61. SetValuePart(DEL_COUNTER_MASK, new_del_counter);
  62. }
  63. bool PendingDelete() const {
  64. const uint32_t pending_del = GetValuePart(PENDING_DEL_MASK);
  65. return pending_del != 0;
  66. }
  67. void SetPendingDel() { SetValuePart(PENDING_DEL_MASK, PENDING_DEL_MASK); }
  68. void ClearPendingDel() { ClearValuePart(PENDING_DEL_MASK); }
  69. bool IsDeleted() const {
  70. const uint32_t deleted = GetValuePart(DEL_MASK);
  71. return deleted != 0;
  72. }
  73. void SetDeleted() { SetValuePart(DEL_MASK, DEL_MASK); }
  74. void ClearDeleted() { ClearValuePart(DEL_MASK); }
  75. uint32_t GetFinalValueBase() const;
  76. uint32_t GetFinalDelCounter() const;
  77. private:
  78. static bool IsValuePartValid(uint32_t value_part, uint32_t value_part_mask) {
  79. return (value_part & (~value_part_mask)) == 0;
  80. }
  81. // The 32-bit expected_value_ is divided into following parts:
  82. // Bit 0 - 14: value base
  83. static constexpr uint32_t VALUE_BASE_MASK = 0x7fff;
  84. static constexpr uint32_t VALUE_BASE_DELTA = 1;
  85. // Bit 15: whether write to this value base is pending (0 equals `false`)
  86. static constexpr uint32_t PENDING_WRITE_MASK = (uint32_t)1 << 15;
  87. // Bit 16 - 29: deletion counter (i.e, number of times this value base has
  88. // been deleted)
  89. static constexpr uint32_t DEL_COUNTER_MASK = 0x3fff0000;
  90. static constexpr uint32_t DEL_COUNTER_DELTA = (uint32_t)1 << 16;
  91. // Bit 30: whether deletion of this value base is pending (0 equals `false`)
  92. static constexpr uint32_t PENDING_DEL_MASK = (uint32_t)1 << 30;
  93. // Bit 31: whether this value base is deleted (0 equals `false`)
  94. static constexpr uint32_t DEL_MASK = (uint32_t)1 << 31;
  95. uint32_t GetValuePart(uint32_t value_part_mask) const {
  96. return expected_value_ & value_part_mask;
  97. }
  98. uint32_t GetIncrementedValuePart(uint32_t value_part_mask,
  99. uint32_t value_part_delta) const {
  100. uint32_t current_value_part = GetValuePart(value_part_mask);
  101. ExpectedValue temp_expected_value(current_value_part + value_part_delta);
  102. return temp_expected_value.GetValuePart(value_part_mask);
  103. }
  104. void SetValuePart(uint32_t value_part_mask, uint32_t new_value_part) {
  105. assert(IsValuePartValid(new_value_part, value_part_mask));
  106. ClearValuePart(value_part_mask);
  107. expected_value_ |= new_value_part;
  108. }
  109. void ClearValuePart(uint32_t value_part_mask) {
  110. expected_value_ &= (~value_part_mask);
  111. }
  112. uint32_t expected_value_;
  113. };
  114. // `PendingExpectedValue` represents the expected value of a key undergoing a
  115. // pending operation in db stress.
  116. //
  117. // After a `PendingExpectedValue` object is created, either `Rollback` or
  118. // `Commit` should be called to close its pending state before it's destructed.
  119. // In case no pending state was introduced while creating this
  120. // `PendingExpectedValue` and user want to ignore the unclosed pending state,
  121. // `PermitUnclosedPendingState` should be called explicitly.
  122. // This class is not thread-safe.
  123. class PendingExpectedValue {
  124. public:
  125. explicit PendingExpectedValue(std::atomic<uint32_t>* value_ptr,
  126. ExpectedValue orig_value,
  127. ExpectedValue final_value)
  128. : value_ptr_(value_ptr),
  129. orig_value_(orig_value),
  130. final_value_(final_value),
  131. pending_state_closed_(false) {}
  132. PendingExpectedValue(const PendingExpectedValue& other)
  133. : value_ptr_(other.value_ptr_),
  134. orig_value_(other.orig_value_),
  135. final_value_(other.final_value_),
  136. pending_state_closed_(false) {
  137. other.ClosePendingState();
  138. }
  139. PendingExpectedValue(PendingExpectedValue&& other) noexcept
  140. : value_ptr_(std::move(other.value_ptr_)),
  141. orig_value_(std::move(other.orig_value_)),
  142. final_value_(std::move(other.final_value_)),
  143. pending_state_closed_(false) {
  144. other.ClosePendingState();
  145. }
  146. PendingExpectedValue& operator=(const PendingExpectedValue& other) {
  147. if (this != &other) {
  148. other.ClosePendingState();
  149. value_ptr_ = other.value_ptr_;
  150. orig_value_ = other.orig_value_;
  151. final_value_ = other.final_value_;
  152. pending_state_closed_ = false;
  153. }
  154. return *this;
  155. }
  156. PendingExpectedValue& operator=(PendingExpectedValue&& other) {
  157. if (this != &other) {
  158. other.ClosePendingState();
  159. value_ptr_ = std::move(other.value_ptr_);
  160. orig_value_ = std::move(other.orig_value_);
  161. final_value_ = std::move(other.final_value_);
  162. pending_state_closed_ = false;
  163. }
  164. return *this;
  165. }
  166. ~PendingExpectedValue() { assert(pending_state_closed_); }
  167. void Commit() {
  168. assert(!pending_state_closed_);
  169. ClosePendingState();
  170. // To prevent low-level instruction reordering that results
  171. // in setting expected value happens before db write
  172. std::atomic_thread_fence(std::memory_order_release);
  173. value_ptr_->store(final_value_.Read());
  174. }
  175. // Rollbacks the key to its original state.
  176. // This rollbacks the pending state created in `ExpectedState::Precommit`,
  177. // such as pending delete, pending put. If `ExpectedState::Precommit()` is not
  178. // called before creating this `PendingExpectedValue`, this is a no-op.
  179. void Rollback() {
  180. assert(!pending_state_closed_);
  181. ClosePendingState();
  182. // To prevent low-level instruction reordering that results
  183. // in setting expected value happens before db write
  184. std::atomic_thread_fence(std::memory_order_release);
  185. value_ptr_->store(orig_value_.Read());
  186. }
  187. void PermitUnclosedPendingState() const {
  188. assert(!pending_state_closed_);
  189. ClosePendingState();
  190. }
  191. uint32_t GetFinalValueBase() { return final_value_.GetValueBase(); }
  192. private:
  193. inline void ClosePendingState() const { pending_state_closed_ = true; }
  194. std::atomic<uint32_t>* value_ptr_;
  195. ExpectedValue orig_value_;
  196. ExpectedValue final_value_;
  197. mutable bool pending_state_closed_;
  198. };
  199. // `ExpectedValueHelper` provides utils to parse `ExpectedValue` to obtain
  200. // useful info about it in db stress
  201. class ExpectedValueHelper {
  202. public:
  203. // Return whether the key associated with `pre_read_expected_value` and
  204. // `post_read_expected_value` is expected not to exist from beginning till the
  205. // end of the read
  206. //
  207. // The negation of `MustHaveNotExisted()` is "may have not existed".
  208. // To assert some key must have existed, please use `MustHaveExisted()`
  209. static bool MustHaveNotExisted(ExpectedValue pre_read_expected_value,
  210. ExpectedValue post_read_expected_value);
  211. // Return whether the key associated with `pre_read_expected_value` and
  212. // `post_read_expected_value` is expected to exist from beginning till the end
  213. // of the read.
  214. //
  215. // The negation of `MustHaveExisted()` is "may have existed".
  216. // To assert some key must have not existed, please use
  217. // `MustHaveNotExisted()`
  218. static bool MustHaveExisted(ExpectedValue pre_read_expected_value,
  219. ExpectedValue post_read_expected_value);
  220. // Return whether the `value_base` falls within the expected value base
  221. static bool InExpectedValueBaseRange(uint32_t value_base,
  222. ExpectedValue pre_read_expected_value,
  223. ExpectedValue post_read_expected_value);
  224. };
  225. } // namespace ROCKSDB_NAMESPACE
  226. #endif // GFLAGS