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