get_context.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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. #pragma once
  6. #include <string>
  7. #include "db/dbformat.h"
  8. #include "db/merge_context.h"
  9. #include "db/read_callback.h"
  10. #include "rocksdb/env.h"
  11. #include "rocksdb/statistics.h"
  12. #include "rocksdb/types.h"
  13. #include "table/block_based/block.h"
  14. namespace ROCKSDB_NAMESPACE {
  15. class MergeContext;
  16. class PinnedIteratorsManager;
  17. // Data structure for accumulating statistics during a point lookup. At the
  18. // end of the point lookup, the corresponding ticker stats are updated. This
  19. // avoids the overhead of frequent ticker stats updates
  20. struct GetContextStats {
  21. uint64_t num_cache_hit = 0;
  22. uint64_t num_cache_index_hit = 0;
  23. uint64_t num_cache_data_hit = 0;
  24. uint64_t num_cache_filter_hit = 0;
  25. uint64_t num_cache_compression_dict_hit = 0;
  26. uint64_t num_cache_index_miss = 0;
  27. uint64_t num_cache_filter_miss = 0;
  28. uint64_t num_cache_data_miss = 0;
  29. uint64_t num_cache_compression_dict_miss = 0;
  30. uint64_t num_cache_bytes_read = 0;
  31. uint64_t num_cache_miss = 0;
  32. uint64_t num_cache_add = 0;
  33. uint64_t num_cache_bytes_write = 0;
  34. uint64_t num_cache_index_add = 0;
  35. uint64_t num_cache_index_bytes_insert = 0;
  36. uint64_t num_cache_data_add = 0;
  37. uint64_t num_cache_data_bytes_insert = 0;
  38. uint64_t num_cache_filter_add = 0;
  39. uint64_t num_cache_filter_bytes_insert = 0;
  40. uint64_t num_cache_compression_dict_add = 0;
  41. uint64_t num_cache_compression_dict_bytes_insert = 0;
  42. };
  43. // A class to hold context about a point lookup, such as pointer to value
  44. // slice, key, merge context etc, as well as the current state of the
  45. // lookup. Any user using GetContext to track the lookup result must call
  46. // SaveValue() whenever the internal key is found. This can happen
  47. // repeatedly in case of merge operands. In case the key may exist with
  48. // high probability, but IO is required to confirm and the user doesn't allow
  49. // it, MarkKeyMayExist() must be called instead of SaveValue().
  50. class GetContext {
  51. public:
  52. // Current state of the point lookup. All except kNotFound and kMerge are
  53. // terminal states
  54. enum GetState {
  55. kNotFound,
  56. kFound,
  57. kDeleted,
  58. kCorrupt,
  59. kMerge, // saver contains the current merge result (the operands)
  60. kBlobIndex,
  61. };
  62. GetContextStats get_context_stats_;
  63. // Constructor
  64. // @param value Holds the value corresponding to user_key. If its nullptr
  65. // then return all merge operands corresponding to user_key
  66. // via merge_context
  67. // @param value_found If non-nullptr, set to false if key may be present
  68. // but we can't be certain because we cannot do IO
  69. // @param max_covering_tombstone_seq Pointer to highest sequence number of
  70. // range deletion covering the key. When an internal key
  71. // is found with smaller sequence number, the lookup
  72. // terminates
  73. // @param seq If non-nullptr, the sequence number of the found key will be
  74. // saved here
  75. // @param callback Pointer to ReadCallback to perform additional checks
  76. // for visibility of a key
  77. // @param is_blob_index If non-nullptr, will be used to indicate if a found
  78. // key is of type blob index
  79. // @param do_merge True if value associated with user_key has to be returned
  80. // and false if all the merge operands associated with user_key has to be
  81. // returned. Id do_merge=false then all the merge operands are stored in
  82. // merge_context and they are never merged. The value pointer is untouched.
  83. GetContext(const Comparator* ucmp, const MergeOperator* merge_operator,
  84. Logger* logger, Statistics* statistics, GetState init_state,
  85. const Slice& user_key, PinnableSlice* value, bool* value_found,
  86. MergeContext* merge_context, bool do_merge,
  87. SequenceNumber* max_covering_tombstone_seq, Env* env,
  88. SequenceNumber* seq = nullptr,
  89. PinnedIteratorsManager* _pinned_iters_mgr = nullptr,
  90. ReadCallback* callback = nullptr, bool* is_blob_index = nullptr,
  91. uint64_t tracing_get_id = 0);
  92. GetContext() = delete;
  93. // This can be called to indicate that a key may be present, but cannot be
  94. // confirmed due to IO not allowed
  95. void MarkKeyMayExist();
  96. // Records this key, value, and any meta-data (such as sequence number and
  97. // state) into this GetContext.
  98. //
  99. // If the parsed_key matches the user key that we are looking for, sets
  100. // matched to true.
  101. //
  102. // Returns True if more keys need to be read (due to merges) or
  103. // False if the complete value has been found.
  104. bool SaveValue(const ParsedInternalKey& parsed_key, const Slice& value,
  105. bool* matched, Cleanable* value_pinner = nullptr);
  106. // Simplified version of the previous function. Should only be used when we
  107. // know that the operation is a Put.
  108. void SaveValue(const Slice& value, SequenceNumber seq);
  109. GetState State() const { return state_; }
  110. SequenceNumber* max_covering_tombstone_seq() {
  111. return max_covering_tombstone_seq_;
  112. }
  113. PinnedIteratorsManager* pinned_iters_mgr() { return pinned_iters_mgr_; }
  114. // If a non-null string is passed, all the SaveValue calls will be
  115. // logged into the string. The operations can then be replayed on
  116. // another GetContext with replayGetContextLog.
  117. void SetReplayLog(std::string* replay_log) { replay_log_ = replay_log; }
  118. // Do we need to fetch the SequenceNumber for this key?
  119. bool NeedToReadSequence() const { return (seq_ != nullptr); }
  120. bool sample() const { return sample_; }
  121. bool CheckCallback(SequenceNumber seq) {
  122. if (callback_) {
  123. return callback_->IsVisible(seq);
  124. }
  125. return true;
  126. }
  127. void ReportCounters();
  128. bool has_callback() const { return callback_ != nullptr; }
  129. uint64_t get_tracing_get_id() const { return tracing_get_id_; }
  130. void push_operand(const Slice& value, Cleanable* value_pinner);
  131. private:
  132. const Comparator* ucmp_;
  133. const MergeOperator* merge_operator_;
  134. // the merge operations encountered;
  135. Logger* logger_;
  136. Statistics* statistics_;
  137. GetState state_;
  138. Slice user_key_;
  139. PinnableSlice* pinnable_val_;
  140. bool* value_found_; // Is value set correctly? Used by KeyMayExist
  141. MergeContext* merge_context_;
  142. SequenceNumber* max_covering_tombstone_seq_;
  143. Env* env_;
  144. // If a key is found, seq_ will be set to the SequenceNumber of most recent
  145. // write to the key or kMaxSequenceNumber if unknown
  146. SequenceNumber* seq_;
  147. std::string* replay_log_;
  148. // Used to temporarily pin blocks when state_ == GetContext::kMerge
  149. PinnedIteratorsManager* pinned_iters_mgr_;
  150. ReadCallback* callback_;
  151. bool sample_;
  152. // Value is true if it's called as part of DB Get API and false if it's
  153. // called as part of DB GetMergeOperands API. When it's false merge operators
  154. // are never merged.
  155. bool do_merge_;
  156. bool* is_blob_index_;
  157. // Used for block cache tracing only. A tracing get id uniquely identifies a
  158. // Get or a MultiGet.
  159. const uint64_t tracing_get_id_;
  160. };
  161. // Call this to replay a log and bring the get_context up to date. The replay
  162. // log must have been created by another GetContext object, whose replay log
  163. // must have been set by calling GetContext::SetReplayLog().
  164. void replayGetContextLog(const Slice& replay_log, const Slice& user_key,
  165. GetContext* get_context,
  166. Cleanable* value_pinner = nullptr);
  167. } // namespace ROCKSDB_NAMESPACE