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