~ubuntu-branches/ubuntu/quantal/ceph/quantal

« back to all changes in this revision

Viewing changes to src/leveldb/db/db_iter.cc

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2012-07-16 09:56:24 UTC
  • mfrom: (0.3.11)
  • mto: This revision was merged to the branch mainline in revision 17.
  • Revision ID: package-import@ubuntu.com-20120716095624-azr2w4hbhei1rxmx
Tags: upstream-0.48
ImportĀ upstreamĀ versionĀ 0.48

Show diffs side-by-side

added added

removed removed

Lines of Context:
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