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