db_iter.cc
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. 4 5 #include "db/db_iter.h" 6 7 #include "db/db_impl.h" 8 #include "db/dbformat.h" 9 #include "db/filename.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" 16 17 namespace leveldb { 18 19 #if 0 20 static void DumpInternalIter(Iterator* iter) { 21 for (iter->SeekToFirst(); iter->Valid(); iter->Next()) { 22 ParsedInternalKey k; 23 if (!ParseInternalKey(iter->key(), &k)) { 24 fprintf(stderr, "Corrupt '%s'\n", EscapeString(iter->key()).c_str()); 25 } else { 26 fprintf(stderr, "@ '%s'\n", k.DebugString().c_str()); 27 } 28 } 29 } 30 #endif 31 32 namespace { 33 34 // Memtables and sstables that make the DB representation contain 35 // (userkey,seq,type) => uservalue entries. DBIter 36 // combines multiple entries for the same userkey found in the DB 37 // representation into a single entry while accounting for sequence 38 // numbers, deletion markers, overwrites, etc. 39 class DBIter : public Iterator { 40 public: 41 // Which direction is the iterator currently moving? 42 // (1) When moving forward, the internal iterator is positioned at 43 // the exact entry that yields this->key(), this->value() 44 // (2) When moving backwards, the internal iterator is positioned 45 // just before all entries whose user key == this->key(). 46 enum Direction { kForward, kReverse }; 47 48 DBIter(DBImpl* db, const Comparator* cmp, Iterator* iter, SequenceNumber s, 49 uint32_t seed) 50 : db_(db), 51 user_comparator_(cmp), 52 iter_(iter), 53 sequence_(s), 54 direction_(kForward), 55 valid_(false), 56 rnd_(seed), 57 bytes_until_read_sampling_(RandomCompactionPeriod()) {} 58 59 DBIter(const DBIter&) = delete; 60 DBIter& operator=(const DBIter&) = delete; 61 62 ~DBIter() override { delete iter_; } 63 bool Valid() const override { return valid_; } 64 Slice key() const override { 65 assert(valid_); 66 return (direction_ == kForward) ? ExtractUserKey(iter_->key()) : saved_key_; 67 } 68 Slice value() const override { 69 assert(valid_); 70 return (direction_ == kForward) ? iter_->value() : saved_value_; 71 } 72 Status status() const override { 73 if (status_.ok()) { 74 return iter_->status(); 75 } else { 76 return status_; 77 } 78 } 79 80 void Next() override; 81 void Prev() override; 82 void Seek(const Slice& target) override; 83 void SeekToFirst() override; 84 void SeekToLast() override; 85 86 private: 87 void FindNextUserEntry(bool skipping, std::string* skip); 88 void FindPrevUserEntry(); 89 bool ParseKey(ParsedInternalKey* key); 90 91 inline void SaveKey(const Slice& k, std::string* dst) { 92 dst->assign(k.data(), k.size()); 93 } 94 95 inline void ClearSavedValue() { 96 if (saved_value_.capacity() > 1048576) { 97 std::string empty; 98 swap(empty, saved_value_); 99 } else { 100 saved_value_.clear(); 101 } 102 } 103 104 // Picks the number of bytes that can be read until a compaction is scheduled. 105 size_t RandomCompactionPeriod() { 106 return rnd_.Uniform(2 * config::kReadBytesPeriod); 107 } 108 109 DBImpl* db_; 110 const Comparator* const user_comparator_; 111 Iterator* const iter_; 112 SequenceNumber const sequence_; 113 Status status_; 114 std::string saved_key_; // == current key when direction_==kReverse 115 std::string saved_value_; // == current raw value when direction_==kReverse 116 Direction direction_; 117 bool valid_; 118 Random rnd_; 119 size_t bytes_until_read_sampling_; 120 }; 121 122 inline bool DBIter::ParseKey(ParsedInternalKey* ikey) { 123 Slice k = iter_->key(); 124 125 size_t bytes_read = k.size() + iter_->value().size(); 126 while (bytes_until_read_sampling_ < bytes_read) { 127 bytes_until_read_sampling_ += RandomCompactionPeriod(); 128 db_->RecordReadSample(k); 129 } 130 assert(bytes_until_read_sampling_ >= bytes_read); 131 bytes_until_read_sampling_ -= bytes_read; 132 133 if (!ParseInternalKey(k, ikey)) { 134 status_ = Status::Corruption("corrupted internal key in DBIter"); 135 return false; 136 } else { 137 return true; 138 } 139 } 140 141 void DBIter::Next() { 142 assert(valid_); 143 144 if (direction_ == kReverse) { // Switch directions? 145 direction_ = kForward; 146 // iter_ is pointing just before the entries for this->key(), 147 // so advance into the range of entries for this->key() and then 148 // use the normal skipping code below. 149 if (!iter_->Valid()) { 150 iter_->SeekToFirst(); 151 } else { 152 iter_->Next(); 153 } 154 if (!iter_->Valid()) { 155 valid_ = false; 156 saved_key_.clear(); 157 return; 158 } 159 // saved_key_ already contains the key to skip past. 160 } else { 161 // Store in saved_key_ the current key so we skip it below. 162 SaveKey(ExtractUserKey(iter_->key()), &saved_key_); 163 164 // iter_ is pointing to current key. We can now safely move to the next to 165 // avoid checking current key. 166 iter_->Next(); 167 if (!iter_->Valid()) { 168 valid_ = false; 169 saved_key_.clear(); 170 return; 171 } 172 } 173 174 FindNextUserEntry(true, &saved_key_); 175 } 176 177 void DBIter::FindNextUserEntry(bool skipping, std::string* skip) { 178 // Loop until we hit an acceptable entry to yield 179 assert(iter_->Valid()); 180 assert(direction_ == kForward); 181 do { 182 ParsedInternalKey ikey; 183 if (ParseKey(&ikey) && ikey.sequence <= sequence_) { 184 switch (ikey.type) { 185 case kTypeDeletion: 186 // Arrange to skip all upcoming entries for this key since 187 // they are hidden by this deletion. 188 SaveKey(ikey.user_key, skip); 189 skipping = true; 190 break; 191 case kTypeValue: 192 if (skipping && 193 user_comparator_->Compare(ikey.user_key, *skip) <= 0) { 194 // Entry hidden 195 } else { 196 valid_ = true; 197 saved_key_.clear(); 198 return; 199 } 200 break; 201 } 202 } 203 iter_->Next(); 204 } while (iter_->Valid()); 205 saved_key_.clear(); 206 valid_ = false; 207 } 208 209 void DBIter::Prev() { 210 assert(valid_); 211 212 if (direction_ == kForward) { // Switch directions? 213 // iter_ is pointing at the current entry. Scan backwards until 214 // the key changes so we can use the normal reverse scanning code. 215 assert(iter_->Valid()); // Otherwise valid_ would have been false 216 SaveKey(ExtractUserKey(iter_->key()), &saved_key_); 217 while (true) { 218 iter_->Prev(); 219 if (!iter_->Valid()) { 220 valid_ = false; 221 saved_key_.clear(); 222 ClearSavedValue(); 223 return; 224 } 225 if (user_comparator_->Compare(ExtractUserKey(iter_->key()), saved_key_) < 226 0) { 227 break; 228 } 229 } 230 direction_ = kReverse; 231 } 232 233 FindPrevUserEntry(); 234 } 235 236 void DBIter::FindPrevUserEntry() { 237 assert(direction_ == kReverse); 238 239 ValueType value_type = kTypeDeletion; 240 if (iter_->Valid()) { 241 do { 242 ParsedInternalKey ikey; 243 if (ParseKey(&ikey) && ikey.sequence <= sequence_) { 244 if ((value_type != kTypeDeletion) && 245 user_comparator_->Compare(ikey.user_key, saved_key_) < 0) { 246 // We encountered a non-deleted value in entries for previous keys, 247 break; 248 } 249 value_type = ikey.type; 250 if (value_type == kTypeDeletion) { 251 saved_key_.clear(); 252 ClearSavedValue(); 253 } else { 254 Slice raw_value = iter_->value(); 255 if (saved_value_.capacity() > raw_value.size() + 1048576) { 256 std::string empty; 257 swap(empty, saved_value_); 258 } 259 SaveKey(ExtractUserKey(iter_->key()), &saved_key_); 260 saved_value_.assign(raw_value.data(), raw_value.size()); 261 } 262 } 263 iter_->Prev(); 264 } while (iter_->Valid()); 265 } 266 267 if (value_type == kTypeDeletion) { 268 // End 269 valid_ = false; 270 saved_key_.clear(); 271 ClearSavedValue(); 272 direction_ = kForward; 273 } else { 274 valid_ = true; 275 } 276 } 277 278 void DBIter::Seek(const Slice& target) { 279 direction_ = kForward; 280 ClearSavedValue(); 281 saved_key_.clear(); 282 AppendInternalKey(&saved_key_, 283 ParsedInternalKey(target, sequence_, kValueTypeForSeek)); 284 iter_->Seek(saved_key_); 285 if (iter_->Valid()) { 286 FindNextUserEntry(false, &saved_key_ /* temporary storage */); 287 } else { 288 valid_ = false; 289 } 290 } 291 292 void DBIter::SeekToFirst() { 293 direction_ = kForward; 294 ClearSavedValue(); 295 iter_->SeekToFirst(); 296 if (iter_->Valid()) { 297 FindNextUserEntry(false, &saved_key_ /* temporary storage */); 298 } else { 299 valid_ = false; 300 } 301 } 302 303 void DBIter::SeekToLast() { 304 direction_ = kReverse; 305 ClearSavedValue(); 306 iter_->SeekToLast(); 307 FindPrevUserEntry(); 308 } 309 310 } // anonymous namespace 311 312 Iterator* NewDBIterator(DBImpl* db, const Comparator* user_key_comparator, 313 Iterator* internal_iter, SequenceNumber sequence, 314 uint32_t seed) { 315 return new DBIter(db, user_key_comparator, internal_iter, sequence, seed); 316 } 317 318 } // namespace leveldb