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 //
6 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7 // Use of this source code is governed by a BSD-style license that can be
8 // found in the LICENSE file. See the AUTHORS file for names of contributors.
9 
10 #pragma once
11 #include <stdint.h>
12 #include <string>
13 #include "db/db_impl/db_impl.h"
14 #include "db/dbformat.h"
15 #include "db/range_del_aggregator.h"
16 #include "memory/arena.h"
17 #include "options/cf_options.h"
18 #include "rocksdb/db.h"
19 #include "rocksdb/iterator.h"
20 #include "table/iterator_wrapper.h"
21 #include "util/autovector.h"
22 
23 namespace ROCKSDB_NAMESPACE {
24 
25 // This file declares the factory functions of DBIter, in its original form
26 // or a wrapped form with class ArenaWrappedDBIter, which is defined here.
27 // Class DBIter, which is declared and implemented inside db_iter.cc, is
28 // an iterator that converts internal keys (yielded by an InternalIterator)
29 // that were live at the specified sequence number into appropriate user
30 // keys.
31 // Each internal key consists of a user key, a sequence number, and a value
32 // type. DBIter deals with multiple key versions, tombstones, merge operands,
33 // etc, and exposes an Iterator.
34 // For example, DBIter may wrap following InternalIterator:
35 //    user key: AAA  value: v3   seqno: 100    type: Put
36 //    user key: AAA  value: v2   seqno: 97     type: Put
37 //    user key: AAA  value: v1   seqno: 95     type: Put
38 //    user key: BBB  value: v1   seqno: 90     type: Put
39 //    user key: BBC  value: N/A  seqno: 98     type: Delete
40 //    user key: BBC  value: v1   seqno: 95     type: Put
41 // If the snapshot passed in is 102, then the DBIter is expected to
42 // expose the following iterator:
43 //    key: AAA  value: v3
44 //    key: BBB  value: v1
45 // If the snapshot passed in is 96, then it should expose:
46 //    key: AAA  value: v1
47 //    key: BBB  value: v1
48 //    key: BBC  value: v1
49 //
50 
51 // Memtables and sstables that make the DB representation contain
52 // (userkey,seq,type) => uservalue entries.  DBIter
53 // combines multiple entries for the same userkey found in the DB
54 // representation into a single entry while accounting for sequence
55 // numbers, deletion markers, overwrites, etc.
56 class DBIter final : public Iterator {
57  public:
58   // The following is grossly complicated. TODO: clean it up
59   // Which direction is the iterator currently moving?
60   // (1) When moving forward:
61   //   (1a) if current_entry_is_merged_ = false, the internal iterator is
62   //        positioned at the exact entry that yields this->key(), this->value()
63   //   (1b) if current_entry_is_merged_ = true, the internal iterator is
64   //        positioned immediately after the last entry that contributed to the
65   //        current this->value(). That entry may or may not have key equal to
66   //        this->key().
67   // (2) When moving backwards, the internal iterator is positioned
68   //     just before all entries whose user key == this->key().
69   enum Direction { kForward, kReverse };
70 
71   // LocalStatistics contain Statistics counters that will be aggregated per
72   // each iterator instance and then will be sent to the global statistics when
73   // the iterator is destroyed.
74   //
75   // The purpose of this approach is to avoid perf regression happening
76   // when multiple threads bump the atomic counters from a DBIter::Next().
77   struct LocalStatistics {
LocalStatisticsLocalStatistics78     explicit LocalStatistics() { ResetCounters(); }
79 
ResetCountersLocalStatistics80     void ResetCounters() {
81       next_count_ = 0;
82       next_found_count_ = 0;
83       prev_count_ = 0;
84       prev_found_count_ = 0;
85       bytes_read_ = 0;
86       skip_count_ = 0;
87     }
88 
BumpGlobalStatisticsLocalStatistics89     void BumpGlobalStatistics(Statistics* global_statistics) {
90       RecordTick(global_statistics, NUMBER_DB_NEXT, next_count_);
91       RecordTick(global_statistics, NUMBER_DB_NEXT_FOUND, next_found_count_);
92       RecordTick(global_statistics, NUMBER_DB_PREV, prev_count_);
93       RecordTick(global_statistics, NUMBER_DB_PREV_FOUND, prev_found_count_);
94       RecordTick(global_statistics, ITER_BYTES_READ, bytes_read_);
95       RecordTick(global_statistics, NUMBER_ITER_SKIP, skip_count_);
96       PERF_COUNTER_ADD(iter_read_bytes, bytes_read_);
97       ResetCounters();
98     }
99 
100     // Map to Tickers::NUMBER_DB_NEXT
101     uint64_t next_count_;
102     // Map to Tickers::NUMBER_DB_NEXT_FOUND
103     uint64_t next_found_count_;
104     // Map to Tickers::NUMBER_DB_PREV
105     uint64_t prev_count_;
106     // Map to Tickers::NUMBER_DB_PREV_FOUND
107     uint64_t prev_found_count_;
108     // Map to Tickers::ITER_BYTES_READ
109     uint64_t bytes_read_;
110     // Map to Tickers::NUMBER_ITER_SKIP
111     uint64_t skip_count_;
112   };
113 
114   DBIter(Env* _env, const ReadOptions& read_options,
115          const ImmutableCFOptions& cf_options,
116          const MutableCFOptions& mutable_cf_options, const Comparator* cmp,
117          InternalIterator* iter, SequenceNumber s, bool arena_mode,
118          uint64_t max_sequential_skip_in_iterations,
119          ReadCallback* read_callback, DBImpl* db_impl, ColumnFamilyData* cfd,
120          bool allow_blob);
121 
122   // No copying allowed
123   DBIter(const DBIter&) = delete;
124   void operator=(const DBIter&) = delete;
125 
~DBIter()126   ~DBIter() override {
127     // Release pinned data if any
128     if (pinned_iters_mgr_.PinningEnabled()) {
129       pinned_iters_mgr_.ReleasePinnedData();
130     }
131     RecordTick(statistics_, NO_ITERATOR_DELETED);
132     ResetInternalKeysSkippedCounter();
133     local_stats_.BumpGlobalStatistics(statistics_);
134     iter_.DeleteIter(arena_mode_);
135   }
SetIter(InternalIterator * iter)136   void SetIter(InternalIterator* iter) {
137     assert(iter_.iter() == nullptr);
138     iter_.Set(iter);
139     iter_.iter()->SetPinnedItersMgr(&pinned_iters_mgr_);
140   }
GetRangeDelAggregator()141   ReadRangeDelAggregator* GetRangeDelAggregator() { return &range_del_agg_; }
142 
Valid()143   bool Valid() const override { return valid_; }
key()144   Slice key() const override {
145     assert(valid_);
146     if (start_seqnum_ > 0) {
147       return saved_key_.GetInternalKey();
148     } else {
149       const Slice ukey_and_ts = saved_key_.GetUserKey();
150       return Slice(ukey_and_ts.data(), ukey_and_ts.size() - timestamp_size_);
151     }
152   }
value()153   Slice value() const override {
154     assert(valid_);
155     if (current_entry_is_merged_) {
156       // If pinned_value_ is set then the result of merge operator is one of
157       // the merge operands and we should return it.
158       return pinned_value_.data() ? pinned_value_ : saved_value_;
159     } else if (direction_ == kReverse) {
160       return pinned_value_;
161     } else {
162       return iter_.value();
163     }
164   }
status()165   Status status() const override {
166     if (status_.ok()) {
167       return iter_.status();
168     } else {
169       assert(!valid_);
170       return status_;
171     }
172   }
timestamp()173   Slice timestamp() const override {
174     assert(valid_);
175     assert(timestamp_size_ > 0);
176     const Slice ukey_and_ts = saved_key_.GetUserKey();
177     assert(timestamp_size_ < ukey_and_ts.size());
178     return ExtractTimestampFromUserKey(ukey_and_ts, timestamp_size_);
179   }
IsBlob()180   bool IsBlob() const {
181     assert(valid_ && (allow_blob_ || !is_blob_));
182     return is_blob_;
183   }
184 
185   Status GetProperty(std::string prop_name, std::string* prop) override;
186 
187   void Next() final override;
188   void Prev() final override;
189   // 'target' does not contain timestamp, even if user timestamp feature is
190   // enabled.
191   void Seek(const Slice& target) final override;
192   void SeekForPrev(const Slice& target) final override;
193   void SeekToFirst() final override;
194   void SeekToLast() final override;
env()195   Env* env() const { return env_; }
set_sequence(uint64_t s)196   void set_sequence(uint64_t s) {
197     sequence_ = s;
198     if (read_callback_) {
199       read_callback_->Refresh(s);
200     }
201   }
set_valid(bool v)202   void set_valid(bool v) { valid_ = v; }
203 
204  private:
205   // For all methods in this block:
206   // PRE: iter_->Valid() && status_.ok()
207   // Return false if there was an error, and status() is non-ok, valid_ = false;
208   // in this case callers would usually stop what they were doing and return.
209   bool ReverseToForward();
210   bool ReverseToBackward();
211   // Set saved_key_ to the seek key to target, with proper sequence number set.
212   // It might get adjusted if the seek key is smaller than iterator lower bound.
213   void SetSavedKeyToSeekTarget(const Slice& target);
214   // Set saved_key_ to the seek key to target, with proper sequence number set.
215   // It might get adjusted if the seek key is larger than iterator upper bound.
216   void SetSavedKeyToSeekForPrevTarget(const Slice& target);
217   bool FindValueForCurrentKey();
218   bool FindValueForCurrentKeyUsingSeek();
219   bool FindUserKeyBeforeSavedKey();
220   // If `skipping_saved_key` is true, the function will keep iterating until it
221   // finds a user key that is larger than `saved_key_`.
222   // If `prefix` is not null, the iterator needs to stop when all keys for the
223   // prefix are exhausted and the interator is set to invalid.
224   bool FindNextUserEntry(bool skipping_saved_key, const Slice* prefix);
225   // Internal implementation of FindNextUserEntry().
226   bool FindNextUserEntryInternal(bool skipping_saved_key, const Slice* prefix);
227   bool ParseKey(ParsedInternalKey* key);
228   bool MergeValuesNewToOld();
229 
230   // If prefix is not null, we need to set the iterator to invalid if no more
231   // entry can be found within the prefix.
232   void PrevInternal(const Slice* prefix);
233   bool TooManyInternalKeysSkipped(bool increment = true);
234   bool IsVisible(SequenceNumber sequence, const Slice& ts);
235 
236   // Temporarily pin the blocks that we encounter until ReleaseTempPinnedData()
237   // is called
TempPinData()238   void TempPinData() {
239     if (!pin_thru_lifetime_) {
240       pinned_iters_mgr_.StartPinning();
241     }
242   }
243 
244   // Release blocks pinned by TempPinData()
ReleaseTempPinnedData()245   void ReleaseTempPinnedData() {
246     if (!pin_thru_lifetime_ && pinned_iters_mgr_.PinningEnabled()) {
247       pinned_iters_mgr_.ReleasePinnedData();
248     }
249   }
250 
ClearSavedValue()251   inline void ClearSavedValue() {
252     if (saved_value_.capacity() > 1048576) {
253       std::string empty;
254       swap(empty, saved_value_);
255     } else {
256       saved_value_.clear();
257     }
258   }
259 
ResetInternalKeysSkippedCounter()260   inline void ResetInternalKeysSkippedCounter() {
261     local_stats_.skip_count_ += num_internal_keys_skipped_;
262     if (valid_) {
263       local_stats_.skip_count_--;
264     }
265     num_internal_keys_skipped_ = 0;
266   }
267 
expect_total_order_inner_iter()268   bool expect_total_order_inner_iter() {
269     assert(expect_total_order_inner_iter_ || prefix_extractor_ != nullptr);
270     return expect_total_order_inner_iter_;
271   }
272 
273   const SliceTransform* prefix_extractor_;
274   Env* const env_;
275   Logger* logger_;
276   UserComparatorWrapper user_comparator_;
277   const MergeOperator* const merge_operator_;
278   IteratorWrapper iter_;
279   ReadCallback* read_callback_;
280   // Max visible sequence number. It is normally the snapshot seq unless we have
281   // uncommitted data in db as in WriteUnCommitted.
282   SequenceNumber sequence_;
283 
284   IterKey saved_key_;
285   // Reusable internal key data structure. This is only used inside one function
286   // and should not be used across functions. Reusing this object can reduce
287   // overhead of calling construction of the function if creating it each time.
288   ParsedInternalKey ikey_;
289   std::string saved_value_;
290   Slice pinned_value_;
291   // for prefix seek mode to support prev()
292   Statistics* statistics_;
293   uint64_t max_skip_;
294   uint64_t max_skippable_internal_keys_;
295   uint64_t num_internal_keys_skipped_;
296   const Slice* iterate_lower_bound_;
297   const Slice* iterate_upper_bound_;
298 
299   // The prefix of the seek key. It is only used when prefix_same_as_start_
300   // is true and prefix extractor is not null. In Next() or Prev(), current keys
301   // will be checked against this prefix, so that the iterator can be
302   // invalidated if the keys in this prefix has been exhausted. Set it using
303   // SetUserKey() and use it using GetUserKey().
304   IterKey prefix_;
305 
306   Status status_;
307   Direction direction_;
308   bool valid_;
309   bool current_entry_is_merged_;
310   // True if we know that the current entry's seqnum is 0.
311   // This information is used as that the next entry will be for another
312   // user key.
313   bool is_key_seqnum_zero_;
314   const bool prefix_same_as_start_;
315   // Means that we will pin all data blocks we read as long the Iterator
316   // is not deleted, will be true if ReadOptions::pin_data is true
317   const bool pin_thru_lifetime_;
318   // Expect the inner iterator to maintain a total order.
319   // prefix_extractor_ must be non-NULL if the value is false.
320   const bool expect_total_order_inner_iter_;
321   bool allow_blob_;
322   bool is_blob_;
323   bool arena_mode_;
324   // List of operands for merge operator.
325   MergeContext merge_context_;
326   ReadRangeDelAggregator range_del_agg_;
327   LocalStatistics local_stats_;
328   PinnedIteratorsManager pinned_iters_mgr_;
329 #ifdef ROCKSDB_LITE
330   ROCKSDB_FIELD_UNUSED
331 #endif
332   DBImpl* db_impl_;
333 #ifdef ROCKSDB_LITE
334   ROCKSDB_FIELD_UNUSED
335 #endif
336   ColumnFamilyData* cfd_;
337   // for diff snapshots we want the lower bound on the seqnum;
338   // if this value > 0 iterator will return internal keys
339   SequenceNumber start_seqnum_;
340   const Slice* const timestamp_ub_;
341   const size_t timestamp_size_;
342 };
343 
344 // Return a new iterator that converts internal keys (yielded by
345 // "*internal_iter") that were live at the specified `sequence` number
346 // into appropriate user keys.
347 extern Iterator* NewDBIterator(
348     Env* env, const ReadOptions& read_options,
349     const ImmutableCFOptions& cf_options,
350     const MutableCFOptions& mutable_cf_options,
351     const Comparator* user_key_comparator, InternalIterator* internal_iter,
352     const SequenceNumber& sequence, uint64_t max_sequential_skip_in_iterations,
353     ReadCallback* read_callback, DBImpl* db_impl = nullptr,
354     ColumnFamilyData* cfd = nullptr, bool allow_blob = false);
355 
356 }  // namespace ROCKSDB_NAMESPACE
357