Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(194)

Side by Side Diff: content/browser/indexed_db/leveldb/leveldb_transaction.cc

Issue 237143006: Make iterating over a corrupted IndexedDB fail. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed Josh's file set #1 comments Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h" 5 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "content/browser/indexed_db/leveldb/leveldb_database.h" 8 #include "content/browser/indexed_db/leveldb/leveldb_database.h"
9 #include "content/browser/indexed_db/leveldb/leveldb_write_batch.h" 9 #include "content/browser/indexed_db/leveldb/leveldb_write_batch.h"
10 #include "third_party/leveldatabase/src/include/leveldb/db.h" 10 #include "third_party/leveldatabase/src/include/leveldb/db.h"
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 123
124 scoped_ptr<LevelDBTransaction::DataIterator> 124 scoped_ptr<LevelDBTransaction::DataIterator>
125 LevelDBTransaction::DataIterator::Create(LevelDBTransaction* transaction) { 125 LevelDBTransaction::DataIterator::Create(LevelDBTransaction* transaction) {
126 return make_scoped_ptr(new DataIterator(transaction)); 126 return make_scoped_ptr(new DataIterator(transaction));
127 } 127 }
128 128
129 bool LevelDBTransaction::DataIterator::IsValid() const { 129 bool LevelDBTransaction::DataIterator::IsValid() const {
130 return iterator_ != data_->end(); 130 return iterator_ != data_->end();
131 } 131 }
132 132
133 void LevelDBTransaction::DataIterator::SeekToLast() { 133 leveldb::Status LevelDBTransaction::DataIterator::SeekToLast() {
134 iterator_ = data_->end(); 134 iterator_ = data_->end();
135 if (iterator_ != data_->begin()) 135 if (iterator_ != data_->begin())
136 --iterator_; 136 --iterator_;
137 return leveldb::Status::OK();
137 } 138 }
138 139
139 void LevelDBTransaction::DataIterator::Seek(const StringPiece& target) { 140 leveldb::Status LevelDBTransaction::DataIterator::Seek(
141 const StringPiece& target) {
140 iterator_ = data_->lower_bound(target); 142 iterator_ = data_->lower_bound(target);
143 return leveldb::Status::OK();
141 } 144 }
142 145
143 void LevelDBTransaction::DataIterator::Next() { 146 leveldb::Status LevelDBTransaction::DataIterator::Next() {
144 DCHECK(IsValid()); 147 DCHECK(IsValid());
145 ++iterator_; 148 ++iterator_;
149 return leveldb::Status::OK();
146 } 150 }
147 151
148 void LevelDBTransaction::DataIterator::Prev() { 152 leveldb::Status LevelDBTransaction::DataIterator::Prev() {
149 DCHECK(IsValid()); 153 DCHECK(IsValid());
150 if (iterator_ != data_->begin()) 154 if (iterator_ != data_->begin())
151 --iterator_; 155 --iterator_;
152 else 156 else
153 iterator_ = data_->end(); 157 iterator_ = data_->end();
158 return leveldb::Status::OK();
154 } 159 }
155 160
156 StringPiece LevelDBTransaction::DataIterator::Key() const { 161 StringPiece LevelDBTransaction::DataIterator::Key() const {
157 DCHECK(IsValid()); 162 DCHECK(IsValid());
158 return iterator_->first; 163 return iterator_->first;
159 } 164 }
160 165
161 StringPiece LevelDBTransaction::DataIterator::Value() const { 166 StringPiece LevelDBTransaction::DataIterator::Value() const {
162 DCHECK(IsValid()); 167 DCHECK(IsValid());
163 DCHECK(!IsDeleted()); 168 DCHECK(!IsDeleted());
(...skipping 30 matching lines...) Expand all
194 } 199 }
195 200
196 LevelDBTransaction::TransactionIterator::~TransactionIterator() { 201 LevelDBTransaction::TransactionIterator::~TransactionIterator() {
197 transaction_->UnregisterIterator(this); 202 transaction_->UnregisterIterator(this);
198 } 203 }
199 204
200 bool LevelDBTransaction::TransactionIterator::IsValid() const { 205 bool LevelDBTransaction::TransactionIterator::IsValid() const {
201 return !!current_; 206 return !!current_;
202 } 207 }
203 208
204 void LevelDBTransaction::TransactionIterator::SeekToLast() { 209 leveldb::Status LevelDBTransaction::TransactionIterator::SeekToLast() {
205 data_iterator_->SeekToLast(); 210 leveldb::Status s = data_iterator_->SeekToLast();
206 db_iterator_->SeekToLast(); 211 DCHECK(s.ok());
212 s = db_iterator_->SeekToLast();
213 if (!s.ok())
214 return s;
207 direction_ = REVERSE; 215 direction_ = REVERSE;
208 216
209 HandleConflictsAndDeletes(); 217 HandleConflictsAndDeletes();
210 SetCurrentIteratorToLargestKey(); 218 SetCurrentIteratorToLargestKey();
219 return s;
211 } 220 }
212 221
213 void LevelDBTransaction::TransactionIterator::Seek(const StringPiece& target) { 222 leveldb::Status LevelDBTransaction::TransactionIterator::Seek(
214 data_iterator_->Seek(target); 223 const StringPiece& target) {
215 db_iterator_->Seek(target); 224 leveldb::Status s = data_iterator_->Seek(target);
225 DCHECK(s.ok());
226 s = db_iterator_->Seek(target);
227 if (!s.ok())
228 return s;
216 direction_ = FORWARD; 229 direction_ = FORWARD;
217 230
218 HandleConflictsAndDeletes(); 231 HandleConflictsAndDeletes();
219 SetCurrentIteratorToSmallestKey(); 232 SetCurrentIteratorToSmallestKey();
233 return s;
220 } 234 }
221 235
222 void LevelDBTransaction::TransactionIterator::Next() { 236 leveldb::Status LevelDBTransaction::TransactionIterator::Next() {
223 DCHECK(IsValid()); 237 DCHECK(IsValid());
224 if (data_changed_) 238 if (data_changed_)
225 RefreshDataIterator(); 239 RefreshDataIterator();
226 240
241 leveldb::Status s;
227 if (direction_ != FORWARD) { 242 if (direction_ != FORWARD) {
228 // Ensure the non-current iterator is positioned after Key(). 243 // Ensure the non-current iterator is positioned after Key().
229 244
230 LevelDBIterator* non_current = (current_ == db_iterator_.get()) 245 LevelDBIterator* non_current = (current_ == db_iterator_.get())
231 ? data_iterator_.get() 246 ? data_iterator_.get()
232 : db_iterator_.get(); 247 : db_iterator_.get();
233 248
234 non_current->Seek(Key()); 249 non_current->Seek(Key());
235 if (non_current->IsValid() && 250 if (non_current->IsValid() &&
236 !comparator_->Compare(non_current->Key(), Key())) { 251 !comparator_->Compare(non_current->Key(), Key())) {
237 // Take an extra step so the non-current key is 252 // Take an extra step so the non-current key is
238 // strictly greater than Key(). 253 // strictly greater than Key().
239 non_current->Next(); 254 s = non_current->Next();
240 } 255 }
241 DCHECK(!non_current->IsValid() || 256 DCHECK(!non_current->IsValid() ||
242 comparator_->Compare(non_current->Key(), Key()) > 0); 257 comparator_->Compare(non_current->Key(), Key()) > 0);
243 258
244 direction_ = FORWARD; 259 direction_ = FORWARD;
245 } 260 }
246 261
247 current_->Next(); 262 if (s.ok())
jsbell 2014/04/15 16:39:57 Early exit here if !s.ok() ? (as you did below, I
cmumford 2014/04/15 17:34:37 Done.
248 HandleConflictsAndDeletes(); 263 s = current_->Next();
249 SetCurrentIteratorToSmallestKey(); 264 if (s.ok()) {
265 HandleConflictsAndDeletes();
266 SetCurrentIteratorToSmallestKey();
267 }
268 return s;
250 } 269 }
251 270
252 void LevelDBTransaction::TransactionIterator::Prev() { 271 leveldb::Status LevelDBTransaction::TransactionIterator::Prev() {
253 DCHECK(IsValid()); 272 DCHECK(IsValid());
273 leveldb::Status s;
254 if (data_changed_) 274 if (data_changed_)
255 RefreshDataIterator(); 275 RefreshDataIterator();
256 276
257 if (direction_ != REVERSE) { 277 if (direction_ != REVERSE) {
258 // Ensure the non-current iterator is positioned before Key(). 278 // Ensure the non-current iterator is positioned before Key().
259 279
260 LevelDBIterator* non_current = (current_ == db_iterator_.get()) 280 LevelDBIterator* non_current = (current_ == db_iterator_.get())
261 ? data_iterator_.get() 281 ? data_iterator_.get()
262 : db_iterator_.get(); 282 : db_iterator_.get();
263 283
264 non_current->Seek(Key()); 284 s = non_current->Seek(Key());
285 if (!s.ok())
286 return s;
265 if (non_current->IsValid()) { 287 if (non_current->IsValid()) {
266 // Iterator is at first entry >= Key(). 288 // Iterator is at first entry >= Key().
267 // Step back once to entry < key. 289 // Step back once to entry < key.
268 // This is why we don't check for the keys being the same before 290 // This is why we don't check for the keys being the same before
269 // stepping, like we do in Next() above. 291 // stepping, like we do in Next() above.
270 non_current->Prev(); 292 non_current->Prev();
271 } else { 293 } else {
272 // Iterator has no entries >= Key(). Position at last entry. 294 // Iterator has no entries >= Key(). Position at last entry.
273 non_current->SeekToLast(); 295 non_current->SeekToLast();
274 } 296 }
275 DCHECK(!non_current->IsValid() || 297 DCHECK(!non_current->IsValid() ||
276 comparator_->Compare(non_current->Key(), Key()) < 0); 298 comparator_->Compare(non_current->Key(), Key()) < 0);
277 299
278 direction_ = REVERSE; 300 direction_ = REVERSE;
279 } 301 }
280 302
281 current_->Prev(); 303 s = current_->Prev();
304 if (!s.ok())
305 return s;
282 HandleConflictsAndDeletes(); 306 HandleConflictsAndDeletes();
283 SetCurrentIteratorToLargestKey(); 307 SetCurrentIteratorToLargestKey();
308 return leveldb::Status::OK();
284 } 309 }
285 310
286 StringPiece LevelDBTransaction::TransactionIterator::Key() const { 311 StringPiece LevelDBTransaction::TransactionIterator::Key() const {
287 DCHECK(IsValid()); 312 DCHECK(IsValid());
288 if (data_changed_) 313 if (data_changed_)
289 RefreshDataIterator(); 314 RefreshDataIterator();
290 return current_->Key(); 315 return current_->Key();
291 } 316 }
292 317
293 StringPiece LevelDBTransaction::TransactionIterator::Value() const { 318 StringPiece LevelDBTransaction::TransactionIterator::Value() const {
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 485
461 leveldb::Status s = db_->Write(*write_batch_); 486 leveldb::Status s = db_->Write(*write_batch_);
462 if (s.ok()) { 487 if (s.ok()) {
463 finished_ = true; 488 finished_ = true;
464 write_batch_->Clear(); 489 write_batch_->Clear();
465 } 490 }
466 return s; 491 return s;
467 } 492 }
468 493
469 } // namespace content 494 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698