github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/database/leveldb.chai2010/src/db_iter.cc (about)

     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