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