Home | History | Annotate | Download | only in db
      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/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"
     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 {
     47     kForward,
     48     kReverse
     49   };
     50 
     51   DBIter(DBImpl* db, const Comparator* cmp, Iterator* iter, SequenceNumber s,
     52          uint32_t seed)
     53       : db_(db),
     54         user_comparator_(cmp),
     55         iter_(iter),
     56         sequence_(s),
     57         direction_(kForward),
     58         valid_(false),
     59         rnd_(seed),
     60         bytes_counter_(RandomPeriod()) {
     61   }
     62   virtual ~DBIter() {
     63     delete iter_;
     64   }
     65   virtual bool Valid() const { return valid_; }
     66   virtual Slice key() const {
     67     assert(valid_);
     68     return (direction_ == kForward) ? ExtractUserKey(iter_->key()) : saved_key_;
     69   }
     70   virtual Slice value() const {
     71     assert(valid_);
     72     return (direction_ == kForward) ? iter_->value() : saved_value_;
     73   }
     74   virtual Status status() const {
     75     if (status_.ok()) {
     76       return iter_->status();
     77     } else {
     78       return status_;
     79     }
     80   }
     81 
     82   virtual void Next();
     83   virtual void Prev();
     84   virtual void Seek(const Slice& target);
     85   virtual void SeekToFirst();
     86   virtual void SeekToLast();
     87 
     88  private:
     89   void FindNextUserEntry(bool skipping, std::string* skip);
     90   void FindPrevUserEntry();
     91   bool ParseKey(ParsedInternalKey* key);
     92 
     93   inline void SaveKey(const Slice& k, std::string* dst) {
     94     dst->assign(k.data(), k.size());
     95   }
     96 
     97   inline void ClearSavedValue() {
     98     if (saved_value_.capacity() > 1048576) {
     99       std::string empty;
    100       swap(empty, saved_value_);
    101     } else {
    102       saved_value_.clear();
    103     }
    104   }
    105 
    106   // Pick next gap with average value of config::kReadBytesPeriod.
    107   ssize_t RandomPeriod() {
    108     return rnd_.Uniform(2*config::kReadBytesPeriod);
    109   }
    110 
    111   DBImpl* db_;
    112   const Comparator* const user_comparator_;
    113   Iterator* const iter_;
    114   SequenceNumber const sequence_;
    115 
    116   Status status_;
    117   std::string saved_key_;     // == current key when direction_==kReverse
    118   std::string saved_value_;   // == current raw value when direction_==kReverse
    119   Direction direction_;
    120   bool valid_;
    121 
    122   Random rnd_;
    123   ssize_t bytes_counter_;
    124 
    125   // No copying allowed
    126   DBIter(const DBIter&);
    127   void operator=(const DBIter&);
    128 };
    129 
    130 inline bool DBIter::ParseKey(ParsedInternalKey* ikey) {
    131   Slice k = iter_->key();
    132   ssize_t n = k.size() + iter_->value().size();
    133   bytes_counter_ -= n;
    134   while (bytes_counter_ < 0) {
    135     bytes_counter_ += RandomPeriod();
    136     db_->RecordReadSample(k);
    137   }
    138   if (!ParseInternalKey(k, ikey)) {
    139     status_ = Status::Corruption("corrupted internal key in DBIter");
    140     return false;
    141   } else {
    142     return true;
    143   }
    144 }
    145 
    146 void DBIter::Next() {
    147   assert(valid_);
    148 
    149   if (direction_ == kReverse) {  // Switch directions?
    150     direction_ = kForward;
    151     // iter_ is pointing just before the entries for this->key(),
    152     // so advance into the range of entries for this->key() and then
    153     // use the normal skipping code below.
    154     if (!iter_->Valid()) {
    155       iter_->SeekToFirst();
    156     } else {
    157       iter_->Next();
    158     }
    159     if (!iter_->Valid()) {
    160       valid_ = false;
    161       saved_key_.clear();
    162       return;
    163     }
    164     // saved_key_ already contains the key to skip past.
    165   } else {
    166     // Store in saved_key_ the current key so we skip it below.
    167     SaveKey(ExtractUserKey(iter_->key()), &saved_key_);
    168   }
    169 
    170   FindNextUserEntry(true, &saved_key_);
    171 }
    172 
    173 void DBIter::FindNextUserEntry(bool skipping, std::string* skip) {
    174   // Loop until we hit an acceptable entry to yield
    175   assert(iter_->Valid());
    176   assert(direction_ == kForward);
    177   do {
    178     ParsedInternalKey ikey;
    179     if (ParseKey(&ikey) && ikey.sequence <= sequence_) {
    180       switch (ikey.type) {
    181         case kTypeDeletion:
    182           // Arrange to skip all upcoming entries for this key since
    183           // they are hidden by this deletion.
    184           SaveKey(ikey.user_key, skip);
    185           skipping = true;
    186           break;
    187         case kTypeValue:
    188           if (skipping &&
    189               user_comparator_->Compare(ikey.user_key, *skip) <= 0) {
    190             // Entry hidden
    191           } else {
    192             valid_ = true;
    193             saved_key_.clear();
    194             return;
    195           }
    196           break;
    197       }
    198     }
    199     iter_->Next();
    200   } while (iter_->Valid());
    201   saved_key_.clear();
    202   valid_ = false;
    203 }
    204 
    205 void DBIter::Prev() {
    206   assert(valid_);
    207 
    208   if (direction_ == kForward) {  // Switch directions?
    209     // iter_ is pointing at the current entry.  Scan backwards until
    210     // the key changes so we can use the normal reverse scanning code.
    211     assert(iter_->Valid());  // Otherwise valid_ would have been false
    212     SaveKey(ExtractUserKey(iter_->key()), &saved_key_);
    213     while (true) {
    214       iter_->Prev();
    215       if (!iter_->Valid()) {
    216         valid_ = false;
    217         saved_key_.clear();
    218         ClearSavedValue();
    219         return;
    220       }
    221       if (user_comparator_->Compare(ExtractUserKey(iter_->key()),
    222                                     saved_key_) < 0) {
    223         break;
    224       }
    225     }
    226     direction_ = kReverse;
    227   }
    228 
    229   FindPrevUserEntry();
    230 }
    231 
    232 void DBIter::FindPrevUserEntry() {
    233   assert(direction_ == kReverse);
    234 
    235   ValueType value_type = kTypeDeletion;
    236   if (iter_->Valid()) {
    237     do {
    238       ParsedInternalKey ikey;
    239       if (ParseKey(&ikey) && ikey.sequence <= sequence_) {
    240         if ((value_type != kTypeDeletion) &&
    241             user_comparator_->Compare(ikey.user_key, saved_key_) < 0) {
    242           // We encountered a non-deleted value in entries for previous keys,
    243           break;
    244         }
    245         value_type = ikey.type;
    246         if (value_type == kTypeDeletion) {
    247           saved_key_.clear();
    248           ClearSavedValue();
    249         } else {
    250           Slice raw_value = iter_->value();
    251           if (saved_value_.capacity() > raw_value.size() + 1048576) {
    252             std::string empty;
    253             swap(empty, saved_value_);
    254           }
    255           SaveKey(ExtractUserKey(iter_->key()), &saved_key_);
    256           saved_value_.assign(raw_value.data(), raw_value.size());
    257         }
    258       }
    259       iter_->Prev();
    260     } while (iter_->Valid());
    261   }
    262 
    263   if (value_type == kTypeDeletion) {
    264     // End
    265     valid_ = false;
    266     saved_key_.clear();
    267     ClearSavedValue();
    268     direction_ = kForward;
    269   } else {
    270     valid_ = true;
    271   }
    272 }
    273 
    274 void DBIter::Seek(const Slice& target) {
    275   direction_ = kForward;
    276   ClearSavedValue();
    277   saved_key_.clear();
    278   AppendInternalKey(
    279       &saved_key_, ParsedInternalKey(target, sequence_, kValueTypeForSeek));
    280   iter_->Seek(saved_key_);
    281   if (iter_->Valid()) {
    282     FindNextUserEntry(false, &saved_key_ /* temporary storage */);
    283   } else {
    284     valid_ = false;
    285   }
    286 }
    287 
    288 void DBIter::SeekToFirst() {
    289   direction_ = kForward;
    290   ClearSavedValue();
    291   iter_->SeekToFirst();
    292   if (iter_->Valid()) {
    293     FindNextUserEntry(false, &saved_key_ /* temporary storage */);
    294   } else {
    295     valid_ = false;
    296   }
    297 }
    298 
    299 void DBIter::SeekToLast() {
    300   direction_ = kReverse;
    301   ClearSavedValue();
    302   iter_->SeekToLast();
    303   FindPrevUserEntry();
    304 }
    305 
    306 }  // anonymous namespace
    307 
    308 Iterator* NewDBIterator(
    309     DBImpl* db,
    310     const Comparator* user_key_comparator,
    311     Iterator* internal_iter,
    312     SequenceNumber sequence,
    313     uint32_t seed) {
    314   return new DBIter(db, user_key_comparator, internal_iter, sequence, seed);
    315 }
    316 
    317 }  // namespace leveldb
    318