xref: /aosp_15_r20/external/leveldb/db/db_iter.cc (revision 9507f98c5f32dee4b5f9e4a38cd499f3ff5c4490)
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