1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. See the AUTHORS file for names of contributors.
5 #include "db/db_iter.h"
7 #include "db/filename.h"
8 #include "db/db_impl.h"
9 #include "db/dbformat.h"
10 #include "leveldb/env.h"
11 #include "leveldb/iterator.h"
12 #include "port/port.h"
13 #include "util/logging.h"
14 #include "util/mutexlock.h"
15 #include "util/random.h"
19 typedef SSIZE_T ssize_t;
25 static void DumpInternalIter(Iterator* iter) {
26 for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
28 if (!ParseInternalKey(iter->key(), &k)) {
29 fprintf(stderr, "Corrupt '%s'\n", EscapeString(iter->key()).c_str());
31 fprintf(stderr, "@ '%s'\n", k.DebugString().c_str());
39 // Memtables and sstables that make the DB representation contain
40 // (userkey,seq,type) => uservalue entries. DBIter
41 // combines multiple entries for the same userkey found in the DB
42 // representation into a single entry while accounting for sequence
43 // numbers, deletion markers, overwrites, etc.
44 class DBIter: public Iterator {
46 // Which direction is the iterator currently moving?
47 // (1) When moving forward, the internal iterator is positioned at
48 // the exact entry that yields this->key(), this->value()
49 // (2) When moving backwards, the internal iterator is positioned
50 // just before all entries whose user key == this->key().
56 DBIter(DBImpl* db, const Comparator* cmp, Iterator* iter, SequenceNumber s,
59 user_comparator_(cmp),
65 bytes_counter_(RandomPeriod()) {
70 virtual bool Valid() const { return valid_; }
71 virtual Slice key() const {
73 return (direction_ == kForward) ? ExtractUserKey(iter_->key()) : saved_key_;
75 virtual Slice value() const {
77 return (direction_ == kForward) ? iter_->value() : saved_value_;
79 virtual Status status() const {
81 return iter_->status();
89 virtual void Seek(const Slice& target);
90 virtual void SeekToFirst();
91 virtual void SeekToLast();
94 void FindNextUserEntry(bool skipping, std::string* skip);
95 void FindPrevUserEntry();
96 bool ParseKey(ParsedInternalKey* key);
98 inline void SaveKey(const Slice& k, std::string* dst) {
99 dst->assign(k.data(), k.size());
102 inline void ClearSavedValue() {
103 if (saved_value_.capacity() > 1048576) {
105 swap(empty, saved_value_);
107 saved_value_.clear();
111 // Pick next gap with average value of config::kReadBytesPeriod.
112 ssize_t RandomPeriod() {
113 return rnd_.Uniform(2*config::kReadBytesPeriod);
117 const Comparator* const user_comparator_;
118 Iterator* const iter_;
119 SequenceNumber const sequence_;
122 std::string saved_key_; // == current key when direction_==kReverse
123 std::string saved_value_; // == current raw value when direction_==kReverse
124 Direction direction_;
128 ssize_t bytes_counter_;
130 // No copying allowed
131 DBIter(const DBIter&);
132 void operator=(const DBIter&);
135 inline bool DBIter::ParseKey(ParsedInternalKey* ikey) {
136 Slice k = iter_->key();
137 ssize_t n = k.size() + iter_->value().size();
139 while (bytes_counter_ < 0) {
140 bytes_counter_ += RandomPeriod();
141 db_->RecordReadSample(k);
143 if (!ParseInternalKey(k, ikey)) {
144 status_ = Status::Corruption("corrupted internal key in DBIter");
151 void DBIter::Next() {
154 if (direction_ == kReverse) { // Switch directions?
155 direction_ = kForward;
156 // iter_ is pointing just before the entries for this->key(),
157 // so advance into the range of entries for this->key() and then
158 // use the normal skipping code below.
159 if (!iter_->Valid()) {
160 iter_->SeekToFirst();
164 if (!iter_->Valid()) {
169 // saved_key_ already contains the key to skip past.
171 // Store in saved_key_ the current key so we skip it below.
172 SaveKey(ExtractUserKey(iter_->key()), &saved_key_);
175 FindNextUserEntry(true, &saved_key_);
178 void DBIter::FindNextUserEntry(bool skipping, std::string* skip) {
179 // Loop until we hit an acceptable entry to yield
180 assert(iter_->Valid());
181 assert(direction_ == kForward);
183 ParsedInternalKey ikey;
184 if (ParseKey(&ikey) && ikey.sequence <= sequence_) {
187 // Arrange to skip all upcoming entries for this key since
188 // they are hidden by this deletion.
189 SaveKey(ikey.user_key, skip);
194 user_comparator_->Compare(ikey.user_key, *skip) <= 0) {
205 } while (iter_->Valid());
210 void DBIter::Prev() {
213 if (direction_ == kForward) { // Switch directions?
214 // iter_ is pointing at the current entry. Scan backwards until
215 // the key changes so we can use the normal reverse scanning code.
216 assert(iter_->Valid()); // Otherwise valid_ would have been false
217 SaveKey(ExtractUserKey(iter_->key()), &saved_key_);
220 if (!iter_->Valid()) {
226 if (user_comparator_->Compare(ExtractUserKey(iter_->key()),
231 direction_ = kReverse;
237 void DBIter::FindPrevUserEntry() {
238 assert(direction_ == kReverse);
240 ValueType value_type = kTypeDeletion;
241 if (iter_->Valid()) {
243 ParsedInternalKey ikey;
244 if (ParseKey(&ikey) && ikey.sequence <= sequence_) {
245 if ((value_type != kTypeDeletion) &&
246 user_comparator_->Compare(ikey.user_key, saved_key_) < 0) {
247 // We encountered a non-deleted value in entries for previous keys,
250 value_type = ikey.type;
251 if (value_type == kTypeDeletion) {
255 Slice raw_value = iter_->value();
256 if (saved_value_.capacity() > raw_value.size() + 1048576) {
258 swap(empty, saved_value_);
260 SaveKey(ExtractUserKey(iter_->key()), &saved_key_);
261 saved_value_.assign(raw_value.data(), raw_value.size());
265 } while (iter_->Valid());
268 if (value_type == kTypeDeletion) {
273 direction_ = kForward;
279 void DBIter::Seek(const Slice& target) {
280 direction_ = kForward;
284 &saved_key_, ParsedInternalKey(target, sequence_, kValueTypeForSeek));
285 iter_->Seek(saved_key_);
286 if (iter_->Valid()) {
287 FindNextUserEntry(false, &saved_key_ /* temporary storage */);
293 void DBIter::SeekToFirst() {
294 direction_ = kForward;
296 iter_->SeekToFirst();
297 if (iter_->Valid()) {
298 FindNextUserEntry(false, &saved_key_ /* temporary storage */);
304 void DBIter::SeekToLast() {
305 direction_ = kReverse;
311 } // anonymous namespace
313 Iterator* NewDBIterator(
315 const Comparator* user_key_comparator,
316 Iterator* internal_iter,
317 SequenceNumber sequence,
319 return new DBIter(db, user_key_comparator, internal_iter, sequence, seed);
322 } // namespace leveldb