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