xref: /aosp_15_r20/external/leveldb/table/block.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 // Decodes the blocks generated by block_builder.cc.
6*9507f98cSAndroid Build Coastguard Worker 
7*9507f98cSAndroid Build Coastguard Worker #include "table/block.h"
8*9507f98cSAndroid Build Coastguard Worker 
9*9507f98cSAndroid Build Coastguard Worker #include <algorithm>
10*9507f98cSAndroid Build Coastguard Worker #include <cstdint>
11*9507f98cSAndroid Build Coastguard Worker #include <vector>
12*9507f98cSAndroid Build Coastguard Worker 
13*9507f98cSAndroid Build Coastguard Worker #include "leveldb/comparator.h"
14*9507f98cSAndroid Build Coastguard Worker #include "table/format.h"
15*9507f98cSAndroid Build Coastguard Worker #include "util/coding.h"
16*9507f98cSAndroid Build Coastguard Worker #include "util/logging.h"
17*9507f98cSAndroid Build Coastguard Worker 
18*9507f98cSAndroid Build Coastguard Worker namespace leveldb {
19*9507f98cSAndroid Build Coastguard Worker 
NumRestarts() const20*9507f98cSAndroid Build Coastguard Worker inline uint32_t Block::NumRestarts() const {
21*9507f98cSAndroid Build Coastguard Worker   assert(size_ >= sizeof(uint32_t));
22*9507f98cSAndroid Build Coastguard Worker   return DecodeFixed32(data_ + size_ - sizeof(uint32_t));
23*9507f98cSAndroid Build Coastguard Worker }
24*9507f98cSAndroid Build Coastguard Worker 
Block(const BlockContents & contents)25*9507f98cSAndroid Build Coastguard Worker Block::Block(const BlockContents& contents)
26*9507f98cSAndroid Build Coastguard Worker     : data_(contents.data.data()),
27*9507f98cSAndroid Build Coastguard Worker       size_(contents.data.size()),
28*9507f98cSAndroid Build Coastguard Worker       owned_(contents.heap_allocated) {
29*9507f98cSAndroid Build Coastguard Worker   if (size_ < sizeof(uint32_t)) {
30*9507f98cSAndroid Build Coastguard Worker     size_ = 0;  // Error marker
31*9507f98cSAndroid Build Coastguard Worker   } else {
32*9507f98cSAndroid Build Coastguard Worker     size_t max_restarts_allowed = (size_ - sizeof(uint32_t)) / sizeof(uint32_t);
33*9507f98cSAndroid Build Coastguard Worker     if (NumRestarts() > max_restarts_allowed) {
34*9507f98cSAndroid Build Coastguard Worker       // The size is too small for NumRestarts()
35*9507f98cSAndroid Build Coastguard Worker       size_ = 0;
36*9507f98cSAndroid Build Coastguard Worker     } else {
37*9507f98cSAndroid Build Coastguard Worker       restart_offset_ = size_ - (1 + NumRestarts()) * sizeof(uint32_t);
38*9507f98cSAndroid Build Coastguard Worker     }
39*9507f98cSAndroid Build Coastguard Worker   }
40*9507f98cSAndroid Build Coastguard Worker }
41*9507f98cSAndroid Build Coastguard Worker 
~Block()42*9507f98cSAndroid Build Coastguard Worker Block::~Block() {
43*9507f98cSAndroid Build Coastguard Worker   if (owned_) {
44*9507f98cSAndroid Build Coastguard Worker     delete[] data_;
45*9507f98cSAndroid Build Coastguard Worker   }
46*9507f98cSAndroid Build Coastguard Worker }
47*9507f98cSAndroid Build Coastguard Worker 
48*9507f98cSAndroid Build Coastguard Worker // Helper routine: decode the next block entry starting at "p",
49*9507f98cSAndroid Build Coastguard Worker // storing the number of shared key bytes, non_shared key bytes,
50*9507f98cSAndroid Build Coastguard Worker // and the length of the value in "*shared", "*non_shared", and
51*9507f98cSAndroid Build Coastguard Worker // "*value_length", respectively.  Will not dereference past "limit".
52*9507f98cSAndroid Build Coastguard Worker //
53*9507f98cSAndroid Build Coastguard Worker // If any errors are detected, returns nullptr.  Otherwise, returns a
54*9507f98cSAndroid Build Coastguard Worker // pointer to the key delta (just past the three decoded values).
DecodeEntry(const char * p,const char * limit,uint32_t * shared,uint32_t * non_shared,uint32_t * value_length)55*9507f98cSAndroid Build Coastguard Worker static inline const char* DecodeEntry(const char* p, const char* limit,
56*9507f98cSAndroid Build Coastguard Worker                                       uint32_t* shared, uint32_t* non_shared,
57*9507f98cSAndroid Build Coastguard Worker                                       uint32_t* value_length) {
58*9507f98cSAndroid Build Coastguard Worker   if (limit - p < 3) return nullptr;
59*9507f98cSAndroid Build Coastguard Worker   *shared = reinterpret_cast<const uint8_t*>(p)[0];
60*9507f98cSAndroid Build Coastguard Worker   *non_shared = reinterpret_cast<const uint8_t*>(p)[1];
61*9507f98cSAndroid Build Coastguard Worker   *value_length = reinterpret_cast<const uint8_t*>(p)[2];
62*9507f98cSAndroid Build Coastguard Worker   if ((*shared | *non_shared | *value_length) < 128) {
63*9507f98cSAndroid Build Coastguard Worker     // Fast path: all three values are encoded in one byte each
64*9507f98cSAndroid Build Coastguard Worker     p += 3;
65*9507f98cSAndroid Build Coastguard Worker   } else {
66*9507f98cSAndroid Build Coastguard Worker     if ((p = GetVarint32Ptr(p, limit, shared)) == nullptr) return nullptr;
67*9507f98cSAndroid Build Coastguard Worker     if ((p = GetVarint32Ptr(p, limit, non_shared)) == nullptr) return nullptr;
68*9507f98cSAndroid Build Coastguard Worker     if ((p = GetVarint32Ptr(p, limit, value_length)) == nullptr) return nullptr;
69*9507f98cSAndroid Build Coastguard Worker   }
70*9507f98cSAndroid Build Coastguard Worker 
71*9507f98cSAndroid Build Coastguard Worker   if (static_cast<uint32_t>(limit - p) < (*non_shared + *value_length)) {
72*9507f98cSAndroid Build Coastguard Worker     return nullptr;
73*9507f98cSAndroid Build Coastguard Worker   }
74*9507f98cSAndroid Build Coastguard Worker   return p;
75*9507f98cSAndroid Build Coastguard Worker }
76*9507f98cSAndroid Build Coastguard Worker 
77*9507f98cSAndroid Build Coastguard Worker class Block::Iter : public Iterator {
78*9507f98cSAndroid Build Coastguard Worker  private:
79*9507f98cSAndroid Build Coastguard Worker   const Comparator* const comparator_;
80*9507f98cSAndroid Build Coastguard Worker   const char* const data_;       // underlying block contents
81*9507f98cSAndroid Build Coastguard Worker   uint32_t const restarts_;      // Offset of restart array (list of fixed32)
82*9507f98cSAndroid Build Coastguard Worker   uint32_t const num_restarts_;  // Number of uint32_t entries in restart array
83*9507f98cSAndroid Build Coastguard Worker 
84*9507f98cSAndroid Build Coastguard Worker   // current_ is offset in data_ of current entry.  >= restarts_ if !Valid
85*9507f98cSAndroid Build Coastguard Worker   uint32_t current_;
86*9507f98cSAndroid Build Coastguard Worker   uint32_t restart_index_;  // Index of restart block in which current_ falls
87*9507f98cSAndroid Build Coastguard Worker   std::string key_;
88*9507f98cSAndroid Build Coastguard Worker   Slice value_;
89*9507f98cSAndroid Build Coastguard Worker   Status status_;
90*9507f98cSAndroid Build Coastguard Worker 
Compare(const Slice & a,const Slice & b) const91*9507f98cSAndroid Build Coastguard Worker   inline int Compare(const Slice& a, const Slice& b) const {
92*9507f98cSAndroid Build Coastguard Worker     return comparator_->Compare(a, b);
93*9507f98cSAndroid Build Coastguard Worker   }
94*9507f98cSAndroid Build Coastguard Worker 
95*9507f98cSAndroid Build Coastguard Worker   // Return the offset in data_ just past the end of the current entry.
NextEntryOffset() const96*9507f98cSAndroid Build Coastguard Worker   inline uint32_t NextEntryOffset() const {
97*9507f98cSAndroid Build Coastguard Worker     return (value_.data() + value_.size()) - data_;
98*9507f98cSAndroid Build Coastguard Worker   }
99*9507f98cSAndroid Build Coastguard Worker 
GetRestartPoint(uint32_t index)100*9507f98cSAndroid Build Coastguard Worker   uint32_t GetRestartPoint(uint32_t index) {
101*9507f98cSAndroid Build Coastguard Worker     assert(index < num_restarts_);
102*9507f98cSAndroid Build Coastguard Worker     return DecodeFixed32(data_ + restarts_ + index * sizeof(uint32_t));
103*9507f98cSAndroid Build Coastguard Worker   }
104*9507f98cSAndroid Build Coastguard Worker 
SeekToRestartPoint(uint32_t index)105*9507f98cSAndroid Build Coastguard Worker   void SeekToRestartPoint(uint32_t index) {
106*9507f98cSAndroid Build Coastguard Worker     key_.clear();
107*9507f98cSAndroid Build Coastguard Worker     restart_index_ = index;
108*9507f98cSAndroid Build Coastguard Worker     // current_ will be fixed by ParseNextKey();
109*9507f98cSAndroid Build Coastguard Worker 
110*9507f98cSAndroid Build Coastguard Worker     // ParseNextKey() starts at the end of value_, so set value_ accordingly
111*9507f98cSAndroid Build Coastguard Worker     uint32_t offset = GetRestartPoint(index);
112*9507f98cSAndroid Build Coastguard Worker     value_ = Slice(data_ + offset, 0);
113*9507f98cSAndroid Build Coastguard Worker   }
114*9507f98cSAndroid Build Coastguard Worker 
115*9507f98cSAndroid Build Coastguard Worker  public:
Iter(const Comparator * comparator,const char * data,uint32_t restarts,uint32_t num_restarts)116*9507f98cSAndroid Build Coastguard Worker   Iter(const Comparator* comparator, const char* data, uint32_t restarts,
117*9507f98cSAndroid Build Coastguard Worker        uint32_t num_restarts)
118*9507f98cSAndroid Build Coastguard Worker       : comparator_(comparator),
119*9507f98cSAndroid Build Coastguard Worker         data_(data),
120*9507f98cSAndroid Build Coastguard Worker         restarts_(restarts),
121*9507f98cSAndroid Build Coastguard Worker         num_restarts_(num_restarts),
122*9507f98cSAndroid Build Coastguard Worker         current_(restarts_),
123*9507f98cSAndroid Build Coastguard Worker         restart_index_(num_restarts_) {
124*9507f98cSAndroid Build Coastguard Worker     assert(num_restarts_ > 0);
125*9507f98cSAndroid Build Coastguard Worker   }
126*9507f98cSAndroid Build Coastguard Worker 
Valid() const127*9507f98cSAndroid Build Coastguard Worker   bool Valid() const override { return current_ < restarts_; }
status() const128*9507f98cSAndroid Build Coastguard Worker   Status status() const override { return status_; }
key() const129*9507f98cSAndroid Build Coastguard Worker   Slice key() const override {
130*9507f98cSAndroid Build Coastguard Worker     assert(Valid());
131*9507f98cSAndroid Build Coastguard Worker     return key_;
132*9507f98cSAndroid Build Coastguard Worker   }
value() const133*9507f98cSAndroid Build Coastguard Worker   Slice value() const override {
134*9507f98cSAndroid Build Coastguard Worker     assert(Valid());
135*9507f98cSAndroid Build Coastguard Worker     return value_;
136*9507f98cSAndroid Build Coastguard Worker   }
137*9507f98cSAndroid Build Coastguard Worker 
Next()138*9507f98cSAndroid Build Coastguard Worker   void Next() override {
139*9507f98cSAndroid Build Coastguard Worker     assert(Valid());
140*9507f98cSAndroid Build Coastguard Worker     ParseNextKey();
141*9507f98cSAndroid Build Coastguard Worker   }
142*9507f98cSAndroid Build Coastguard Worker 
Prev()143*9507f98cSAndroid Build Coastguard Worker   void Prev() override {
144*9507f98cSAndroid Build Coastguard Worker     assert(Valid());
145*9507f98cSAndroid Build Coastguard Worker 
146*9507f98cSAndroid Build Coastguard Worker     // Scan backwards to a restart point before current_
147*9507f98cSAndroid Build Coastguard Worker     const uint32_t original = current_;
148*9507f98cSAndroid Build Coastguard Worker     while (GetRestartPoint(restart_index_) >= original) {
149*9507f98cSAndroid Build Coastguard Worker       if (restart_index_ == 0) {
150*9507f98cSAndroid Build Coastguard Worker         // No more entries
151*9507f98cSAndroid Build Coastguard Worker         current_ = restarts_;
152*9507f98cSAndroid Build Coastguard Worker         restart_index_ = num_restarts_;
153*9507f98cSAndroid Build Coastguard Worker         return;
154*9507f98cSAndroid Build Coastguard Worker       }
155*9507f98cSAndroid Build Coastguard Worker       restart_index_--;
156*9507f98cSAndroid Build Coastguard Worker     }
157*9507f98cSAndroid Build Coastguard Worker 
158*9507f98cSAndroid Build Coastguard Worker     SeekToRestartPoint(restart_index_);
159*9507f98cSAndroid Build Coastguard Worker     do {
160*9507f98cSAndroid Build Coastguard Worker       // Loop until end of current entry hits the start of original entry
161*9507f98cSAndroid Build Coastguard Worker     } while (ParseNextKey() && NextEntryOffset() < original);
162*9507f98cSAndroid Build Coastguard Worker   }
163*9507f98cSAndroid Build Coastguard Worker 
Seek(const Slice & target)164*9507f98cSAndroid Build Coastguard Worker   void Seek(const Slice& target) override {
165*9507f98cSAndroid Build Coastguard Worker     // Binary search in restart array to find the last restart point
166*9507f98cSAndroid Build Coastguard Worker     // with a key < target
167*9507f98cSAndroid Build Coastguard Worker     uint32_t left = 0;
168*9507f98cSAndroid Build Coastguard Worker     uint32_t right = num_restarts_ - 1;
169*9507f98cSAndroid Build Coastguard Worker     int current_key_compare = 0;
170*9507f98cSAndroid Build Coastguard Worker 
171*9507f98cSAndroid Build Coastguard Worker     if (Valid()) {
172*9507f98cSAndroid Build Coastguard Worker       // If we're already scanning, use the current position as a starting
173*9507f98cSAndroid Build Coastguard Worker       // point. This is beneficial if the key we're seeking to is ahead of the
174*9507f98cSAndroid Build Coastguard Worker       // current position.
175*9507f98cSAndroid Build Coastguard Worker       current_key_compare = Compare(key_, target);
176*9507f98cSAndroid Build Coastguard Worker       if (current_key_compare < 0) {
177*9507f98cSAndroid Build Coastguard Worker         // key_ is smaller than target
178*9507f98cSAndroid Build Coastguard Worker         left = restart_index_;
179*9507f98cSAndroid Build Coastguard Worker       } else if (current_key_compare > 0) {
180*9507f98cSAndroid Build Coastguard Worker         right = restart_index_;
181*9507f98cSAndroid Build Coastguard Worker       } else {
182*9507f98cSAndroid Build Coastguard Worker         // We're seeking to the key we're already at.
183*9507f98cSAndroid Build Coastguard Worker         return;
184*9507f98cSAndroid Build Coastguard Worker       }
185*9507f98cSAndroid Build Coastguard Worker     }
186*9507f98cSAndroid Build Coastguard Worker 
187*9507f98cSAndroid Build Coastguard Worker     while (left < right) {
188*9507f98cSAndroid Build Coastguard Worker       uint32_t mid = (left + right + 1) / 2;
189*9507f98cSAndroid Build Coastguard Worker       uint32_t region_offset = GetRestartPoint(mid);
190*9507f98cSAndroid Build Coastguard Worker       uint32_t shared, non_shared, value_length;
191*9507f98cSAndroid Build Coastguard Worker       const char* key_ptr =
192*9507f98cSAndroid Build Coastguard Worker           DecodeEntry(data_ + region_offset, data_ + restarts_, &shared,
193*9507f98cSAndroid Build Coastguard Worker                       &non_shared, &value_length);
194*9507f98cSAndroid Build Coastguard Worker       if (key_ptr == nullptr || (shared != 0)) {
195*9507f98cSAndroid Build Coastguard Worker         CorruptionError();
196*9507f98cSAndroid Build Coastguard Worker         return;
197*9507f98cSAndroid Build Coastguard Worker       }
198*9507f98cSAndroid Build Coastguard Worker       Slice mid_key(key_ptr, non_shared);
199*9507f98cSAndroid Build Coastguard Worker       if (Compare(mid_key, target) < 0) {
200*9507f98cSAndroid Build Coastguard Worker         // Key at "mid" is smaller than "target".  Therefore all
201*9507f98cSAndroid Build Coastguard Worker         // blocks before "mid" are uninteresting.
202*9507f98cSAndroid Build Coastguard Worker         left = mid;
203*9507f98cSAndroid Build Coastguard Worker       } else {
204*9507f98cSAndroid Build Coastguard Worker         // Key at "mid" is >= "target".  Therefore all blocks at or
205*9507f98cSAndroid Build Coastguard Worker         // after "mid" are uninteresting.
206*9507f98cSAndroid Build Coastguard Worker         right = mid - 1;
207*9507f98cSAndroid Build Coastguard Worker       }
208*9507f98cSAndroid Build Coastguard Worker     }
209*9507f98cSAndroid Build Coastguard Worker 
210*9507f98cSAndroid Build Coastguard Worker     // We might be able to use our current position within the restart block.
211*9507f98cSAndroid Build Coastguard Worker     // This is true if we determined the key we desire is in the current block
212*9507f98cSAndroid Build Coastguard Worker     // and is after than the current key.
213*9507f98cSAndroid Build Coastguard Worker     assert(current_key_compare == 0 || Valid());
214*9507f98cSAndroid Build Coastguard Worker     bool skip_seek = left == restart_index_ && current_key_compare < 0;
215*9507f98cSAndroid Build Coastguard Worker     if (!skip_seek) {
216*9507f98cSAndroid Build Coastguard Worker       SeekToRestartPoint(left);
217*9507f98cSAndroid Build Coastguard Worker     }
218*9507f98cSAndroid Build Coastguard Worker     // Linear search (within restart block) for first key >= target
219*9507f98cSAndroid Build Coastguard Worker     while (true) {
220*9507f98cSAndroid Build Coastguard Worker       if (!ParseNextKey()) {
221*9507f98cSAndroid Build Coastguard Worker         return;
222*9507f98cSAndroid Build Coastguard Worker       }
223*9507f98cSAndroid Build Coastguard Worker       if (Compare(key_, target) >= 0) {
224*9507f98cSAndroid Build Coastguard Worker         return;
225*9507f98cSAndroid Build Coastguard Worker       }
226*9507f98cSAndroid Build Coastguard Worker     }
227*9507f98cSAndroid Build Coastguard Worker   }
228*9507f98cSAndroid Build Coastguard Worker 
SeekToFirst()229*9507f98cSAndroid Build Coastguard Worker   void SeekToFirst() override {
230*9507f98cSAndroid Build Coastguard Worker     SeekToRestartPoint(0);
231*9507f98cSAndroid Build Coastguard Worker     ParseNextKey();
232*9507f98cSAndroid Build Coastguard Worker   }
233*9507f98cSAndroid Build Coastguard Worker 
SeekToLast()234*9507f98cSAndroid Build Coastguard Worker   void SeekToLast() override {
235*9507f98cSAndroid Build Coastguard Worker     SeekToRestartPoint(num_restarts_ - 1);
236*9507f98cSAndroid Build Coastguard Worker     while (ParseNextKey() && NextEntryOffset() < restarts_) {
237*9507f98cSAndroid Build Coastguard Worker       // Keep skipping
238*9507f98cSAndroid Build Coastguard Worker     }
239*9507f98cSAndroid Build Coastguard Worker   }
240*9507f98cSAndroid Build Coastguard Worker 
241*9507f98cSAndroid Build Coastguard Worker  private:
CorruptionError()242*9507f98cSAndroid Build Coastguard Worker   void CorruptionError() {
243*9507f98cSAndroid Build Coastguard Worker     current_ = restarts_;
244*9507f98cSAndroid Build Coastguard Worker     restart_index_ = num_restarts_;
245*9507f98cSAndroid Build Coastguard Worker     status_ = Status::Corruption("bad entry in block");
246*9507f98cSAndroid Build Coastguard Worker     key_.clear();
247*9507f98cSAndroid Build Coastguard Worker     value_.clear();
248*9507f98cSAndroid Build Coastguard Worker   }
249*9507f98cSAndroid Build Coastguard Worker 
ParseNextKey()250*9507f98cSAndroid Build Coastguard Worker   bool ParseNextKey() {
251*9507f98cSAndroid Build Coastguard Worker     current_ = NextEntryOffset();
252*9507f98cSAndroid Build Coastguard Worker     const char* p = data_ + current_;
253*9507f98cSAndroid Build Coastguard Worker     const char* limit = data_ + restarts_;  // Restarts come right after data
254*9507f98cSAndroid Build Coastguard Worker     if (p >= limit) {
255*9507f98cSAndroid Build Coastguard Worker       // No more entries to return.  Mark as invalid.
256*9507f98cSAndroid Build Coastguard Worker       current_ = restarts_;
257*9507f98cSAndroid Build Coastguard Worker       restart_index_ = num_restarts_;
258*9507f98cSAndroid Build Coastguard Worker       return false;
259*9507f98cSAndroid Build Coastguard Worker     }
260*9507f98cSAndroid Build Coastguard Worker 
261*9507f98cSAndroid Build Coastguard Worker     // Decode next entry
262*9507f98cSAndroid Build Coastguard Worker     uint32_t shared, non_shared, value_length;
263*9507f98cSAndroid Build Coastguard Worker     p = DecodeEntry(p, limit, &shared, &non_shared, &value_length);
264*9507f98cSAndroid Build Coastguard Worker     if (p == nullptr || key_.size() < shared) {
265*9507f98cSAndroid Build Coastguard Worker       CorruptionError();
266*9507f98cSAndroid Build Coastguard Worker       return false;
267*9507f98cSAndroid Build Coastguard Worker     } else {
268*9507f98cSAndroid Build Coastguard Worker       key_.resize(shared);
269*9507f98cSAndroid Build Coastguard Worker       key_.append(p, non_shared);
270*9507f98cSAndroid Build Coastguard Worker       value_ = Slice(p + non_shared, value_length);
271*9507f98cSAndroid Build Coastguard Worker       while (restart_index_ + 1 < num_restarts_ &&
272*9507f98cSAndroid Build Coastguard Worker              GetRestartPoint(restart_index_ + 1) < current_) {
273*9507f98cSAndroid Build Coastguard Worker         ++restart_index_;
274*9507f98cSAndroid Build Coastguard Worker       }
275*9507f98cSAndroid Build Coastguard Worker       return true;
276*9507f98cSAndroid Build Coastguard Worker     }
277*9507f98cSAndroid Build Coastguard Worker   }
278*9507f98cSAndroid Build Coastguard Worker };
279*9507f98cSAndroid Build Coastguard Worker 
NewIterator(const Comparator * comparator)280*9507f98cSAndroid Build Coastguard Worker Iterator* Block::NewIterator(const Comparator* comparator) {
281*9507f98cSAndroid Build Coastguard Worker   if (size_ < sizeof(uint32_t)) {
282*9507f98cSAndroid Build Coastguard Worker     return NewErrorIterator(Status::Corruption("bad block contents"));
283*9507f98cSAndroid Build Coastguard Worker   }
284*9507f98cSAndroid Build Coastguard Worker   const uint32_t num_restarts = NumRestarts();
285*9507f98cSAndroid Build Coastguard Worker   if (num_restarts == 0) {
286*9507f98cSAndroid Build Coastguard Worker     return NewEmptyIterator();
287*9507f98cSAndroid Build Coastguard Worker   } else {
288*9507f98cSAndroid Build Coastguard Worker     return new Iter(comparator, data_, restart_offset_, num_restarts);
289*9507f98cSAndroid Build Coastguard Worker   }
290*9507f98cSAndroid Build Coastguard Worker }
291*9507f98cSAndroid Build Coastguard Worker 
292*9507f98cSAndroid Build Coastguard Worker }  // namespace leveldb
293