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.
5
#include "db/db_iter.h"
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"
18
static void DumpInternalIter(Iterator* iter) {
19
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
21
if (!ParseInternalKey(iter->key(), &k)) {
22
fprintf(stderr, "Corrupt '%s'\n", EscapeString(iter->key()).c_str());
24
fprintf(stderr, "@ '%s'\n", k.DebugString().c_str());
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 {
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().
49
DBIter(const std::string* dbname, Env* env,
50
const Comparator* cmp, Iterator* iter, SequenceNumber s)
53
user_comparator_(cmp),
62
virtual bool Valid() const { return valid_; }
63
virtual Slice key() const {
65
return (direction_ == kForward) ? ExtractUserKey(iter_->key()) : saved_key_;
67
virtual Slice value() const {
69
return (direction_ == kForward) ? iter_->value() : saved_value_;
71
virtual Status status() const {
73
return iter_->status();
81
virtual void Seek(const Slice& target);
82
virtual void SeekToFirst();
83
virtual void SeekToLast();
86
void FindNextUserEntry(bool skipping, std::string* skip);
87
void FindPrevUserEntry();
88
bool ParseKey(ParsedInternalKey* key);
90
inline void SaveKey(const Slice& k, std::string* dst) {
91
dst->assign(k.data(), k.size());
94
inline void ClearSavedValue() {
95
if (saved_value_.capacity() > 1048576) {
97
swap(empty, saved_value_);
103
const std::string* const dbname_;
105
const Comparator* const user_comparator_;
106
Iterator* const iter_;
107
SequenceNumber const sequence_;
110
std::string saved_key_; // == current key when direction_==kReverse
111
std::string saved_value_; // == current raw value when direction_==kReverse
112
Direction direction_;
115
// No copying allowed
116
DBIter(const DBIter&);
117
void operator=(const DBIter&);
120
inline bool DBIter::ParseKey(ParsedInternalKey* ikey) {
121
if (!ParseInternalKey(iter_->key(), ikey)) {
122
status_ = Status::Corruption("corrupted internal key in DBIter");
129
void DBIter::Next() {
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();
142
if (!iter_->Valid()) {
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);
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);
160
ParsedInternalKey ikey;
161
if (ParseKey(&ikey) && ikey.sequence <= sequence_) {
164
// Arrange to skip all upcoming entries for this key since
165
// they are hidden by this deletion.
166
SaveKey(ikey.user_key, skip);
171
user_comparator_->Compare(ikey.user_key, *skip) <= 0) {
182
} while (iter_->Valid());
187
void DBIter::Prev() {
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_);
197
if (!iter_->Valid()) {
203
if (user_comparator_->Compare(ExtractUserKey(iter_->key()),
208
direction_ = kReverse;
214
void DBIter::FindPrevUserEntry() {
215
assert(direction_ == kReverse);
217
ValueType value_type = kTypeDeletion;
218
if (iter_->Valid()) {
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,
227
value_type = ikey.type;
228
if (value_type == kTypeDeletion) {
232
Slice raw_value = iter_->value();
233
if (saved_value_.capacity() > raw_value.size() + 1048576) {
235
swap(empty, saved_value_);
237
SaveKey(ExtractUserKey(iter_->key()), &saved_key_);
238
saved_value_.assign(raw_value.data(), raw_value.size());
242
} while (iter_->Valid());
245
if (value_type == kTypeDeletion) {
250
direction_ = kForward;
256
void DBIter::Seek(const Slice& target) {
257
direction_ = kForward;
261
&saved_key_, ParsedInternalKey(target, sequence_, kValueTypeForSeek));
262
iter_->Seek(saved_key_);
263
if (iter_->Valid()) {
264
FindNextUserEntry(false, &saved_key_ /* temporary storage */);
270
void DBIter::SeekToFirst() {
271
direction_ = kForward;
273
iter_->SeekToFirst();
274
if (iter_->Valid()) {
275
FindNextUserEntry(false, &saved_key_ /* temporary storage */);
281
void DBIter::SeekToLast() {
282
direction_ = kReverse;
288
} // anonymous namespace
290
Iterator* NewDBIterator(
291
const std::string* dbname,
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);
299
} // namespace leveldb