]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/rocksdb/table/get_context.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / rocksdb / table / get_context.h
index d7d0e9808b177bdda4466a2a1bf84a1a7e8bdc8f..79bae221467c7dffa0d0960dbcd75572a69a6326 100644 (file)
@@ -5,17 +5,21 @@
 
 #pragma once
 #include <string>
+#include "db/dbformat.h"
 #include "db/merge_context.h"
 #include "db/read_callback.h"
 #include "rocksdb/env.h"
 #include "rocksdb/statistics.h"
 #include "rocksdb/types.h"
-#include "table/block.h"
+#include "table/block_based/block.h"
 
-namespace rocksdb {
+namespace ROCKSDB_NAMESPACE {
 class MergeContext;
 class PinnedIteratorsManager;
 
+// Data structure for accumulating statistics during a point lookup. At the
+// end of the point lookup, the corresponding ticker stats are updated. This
+// avoids the overhead of frequent ticker stats updates
 struct GetContextStats {
   uint64_t num_cache_hit = 0;
   uint64_t num_cache_index_hit = 0;
@@ -40,8 +44,17 @@ struct GetContextStats {
   uint64_t num_cache_compression_dict_bytes_insert = 0;
 };
 
+// A class to hold context about a point lookup, such as pointer to value
+// slice, key, merge context etc, as well as the current state of the
+// lookup. Any user using GetContext to track the lookup result must call
+// SaveValue() whenever the internal key is found. This can happen
+// repeatedly in case of merge operands. In case the key may exist with
+// high probability, but IO is required to confirm and the user doesn't allow
+// it, MarkKeyMayExist() must be called instead of SaveValue().
 class GetContext {
  public:
+  // Current state of the point lookup. All except kNotFound and kMerge are
+  // terminal states
   enum GetState {
     kNotFound,
     kFound,
@@ -52,22 +65,47 @@ class GetContext {
   };
   GetContextStats get_context_stats_;
 
+  // Constructor
+  // @param value Holds the value corresponding to user_key. If its nullptr
+  //              then return all merge operands corresponding to user_key
+  //              via merge_context
+  // @param value_found If non-nullptr, set to false if key may be present
+  //                    but we can't be certain because we cannot do IO
+  // @param max_covering_tombstone_seq Pointer to highest sequence number of
+  //                    range deletion covering the key. When an internal key
+  //                    is found with smaller sequence number, the lookup
+  //                    terminates
+  // @param seq If non-nullptr, the sequence number of the found key will be
+  //            saved here
+  // @param callback Pointer to ReadCallback to perform additional checks
+  //                 for visibility of a key
+  // @param is_blob_index If non-nullptr, will be used to indicate if a found
+  //                      key is of type blob index
+  // @param do_merge True if value associated with user_key has to be returned
+  // and false if all the merge operands associated with user_key has to be
+  // returned. Id do_merge=false then all the merge operands are stored in
+  // merge_context and they are never merged. The value pointer is untouched.
   GetContext(const Comparator* ucmp, const MergeOperator* merge_operator,
              Logger* logger, Statistics* statistics, GetState init_state,
              const Slice& user_key, PinnableSlice* value, bool* value_found,
-             MergeContext* merge_context,
+             MergeContext* merge_context, bool do_merge,
              SequenceNumber* max_covering_tombstone_seq, Env* env,
              SequenceNumber* seq = nullptr,
              PinnedIteratorsManager* _pinned_iters_mgr = nullptr,
-             ReadCallback* callback = nullptr, bool* is_blob_index = nullptr);
+             ReadCallback* callback = nullptr, bool* is_blob_index = nullptr,
+             uint64_t tracing_get_id = 0);
 
+  GetContext() = delete;
+
+  // This can be called to indicate that a key may be present, but cannot be
+  // confirmed due to IO not allowed
   void MarkKeyMayExist();
 
   // Records this key, value, and any meta-data (such as sequence number and
   // state) into this GetContext.
   //
   // If the parsed_key matches the user key that we are looking for, sets
-  // mathced to true.
+  // matched to true.
   //
   // Returns True if more keys need to be read (due to merges) or
   //         False if the complete value has been found.
@@ -105,6 +143,12 @@ class GetContext {
 
   void ReportCounters();
 
+  bool has_callback() const { return callback_ != nullptr; }
+
+  uint64_t get_tracing_get_id() const { return tracing_get_id_; }
+
+  void push_operand(const Slice& value, Cleanable* value_pinner);
+
  private:
   const Comparator* ucmp_;
   const MergeOperator* merge_operator_;
@@ -127,11 +171,21 @@ class GetContext {
   PinnedIteratorsManager* pinned_iters_mgr_;
   ReadCallback* callback_;
   bool sample_;
+  // Value is true if it's called as part of DB Get API and false if it's
+  // called as part of DB GetMergeOperands API. When it's false merge operators
+  // are never merged.
+  bool do_merge_;
   bool* is_blob_index_;
+  // Used for block cache tracing only. A tracing get id uniquely identifies a
+  // Get or a MultiGet.
+  const uint64_t tracing_get_id_;
 };
 
+// Call this to replay a log and bring the get_context up to date. The replay
+// log must have been created by another GetContext object, whose replay log
+// must have been set by calling GetContext::SetReplayLog().
 void replayGetContextLog(const Slice& replay_log, const Slice& user_key,
                          GetContext* get_context,
                          Cleanable* value_pinner = nullptr);
 
-}  // namespace rocksdb
+}  // namespace ROCKSDB_NAMESPACE