| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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(); |
| 255 if (!s.ok()) |
| 256 return s; |
| 240 } | 257 } |
| 241 DCHECK(!non_current->IsValid() || | 258 DCHECK(!non_current->IsValid() || |
| 242 comparator_->Compare(non_current->Key(), Key()) > 0); | 259 comparator_->Compare(non_current->Key(), Key()) > 0); |
| 243 | 260 |
| 244 direction_ = FORWARD; | 261 direction_ = FORWARD; |
| 245 } | 262 } |
| 246 | 263 |
| 247 current_->Next(); | 264 s = current_->Next(); |
| 265 if (!s.ok()) |
| 266 return s; |
| 248 HandleConflictsAndDeletes(); | 267 HandleConflictsAndDeletes(); |
| 249 SetCurrentIteratorToSmallestKey(); | 268 SetCurrentIteratorToSmallestKey(); |
| 269 return leveldb::Status::OK(); |
| 250 } | 270 } |
| 251 | 271 |
| 252 void LevelDBTransaction::TransactionIterator::Prev() { | 272 leveldb::Status LevelDBTransaction::TransactionIterator::Prev() { |
| 253 DCHECK(IsValid()); | 273 DCHECK(IsValid()); |
| 274 leveldb::Status s; |
| 254 if (data_changed_) | 275 if (data_changed_) |
| 255 RefreshDataIterator(); | 276 RefreshDataIterator(); |
| 256 | 277 |
| 257 if (direction_ != REVERSE) { | 278 if (direction_ != REVERSE) { |
| 258 // Ensure the non-current iterator is positioned before Key(). | 279 // Ensure the non-current iterator is positioned before Key(). |
| 259 | 280 |
| 260 LevelDBIterator* non_current = (current_ == db_iterator_.get()) | 281 LevelDBIterator* non_current = (current_ == db_iterator_.get()) |
| 261 ? data_iterator_.get() | 282 ? data_iterator_.get() |
| 262 : db_iterator_.get(); | 283 : db_iterator_.get(); |
| 263 | 284 |
| 264 non_current->Seek(Key()); | 285 s = non_current->Seek(Key()); |
| 286 if (!s.ok()) |
| 287 return s; |
| 265 if (non_current->IsValid()) { | 288 if (non_current->IsValid()) { |
| 266 // Iterator is at first entry >= Key(). | 289 // Iterator is at first entry >= Key(). |
| 267 // Step back once to entry < key. | 290 // Step back once to entry < key. |
| 268 // This is why we don't check for the keys being the same before | 291 // This is why we don't check for the keys being the same before |
| 269 // stepping, like we do in Next() above. | 292 // stepping, like we do in Next() above. |
| 270 non_current->Prev(); | 293 non_current->Prev(); |
| 271 } else { | 294 } else { |
| 272 // Iterator has no entries >= Key(). Position at last entry. | 295 // Iterator has no entries >= Key(). Position at last entry. |
| 273 non_current->SeekToLast(); | 296 non_current->SeekToLast(); |
| 274 } | 297 } |
| 275 DCHECK(!non_current->IsValid() || | 298 DCHECK(!non_current->IsValid() || |
| 276 comparator_->Compare(non_current->Key(), Key()) < 0); | 299 comparator_->Compare(non_current->Key(), Key()) < 0); |
| 277 | 300 |
| 278 direction_ = REVERSE; | 301 direction_ = REVERSE; |
| 279 } | 302 } |
| 280 | 303 |
| 281 current_->Prev(); | 304 s = current_->Prev(); |
| 305 if (!s.ok()) |
| 306 return s; |
| 282 HandleConflictsAndDeletes(); | 307 HandleConflictsAndDeletes(); |
| 283 SetCurrentIteratorToLargestKey(); | 308 SetCurrentIteratorToLargestKey(); |
| 309 return leveldb::Status::OK(); |
| 284 } | 310 } |
| 285 | 311 |
| 286 StringPiece LevelDBTransaction::TransactionIterator::Key() const { | 312 StringPiece LevelDBTransaction::TransactionIterator::Key() const { |
| 287 DCHECK(IsValid()); | 313 DCHECK(IsValid()); |
| 288 if (data_changed_) | 314 if (data_changed_) |
| 289 RefreshDataIterator(); | 315 RefreshDataIterator(); |
| 290 return current_->Key(); | 316 return current_->Key(); |
| 291 } | 317 } |
| 292 | 318 |
| 293 StringPiece LevelDBTransaction::TransactionIterator::Value() const { | 319 StringPiece LevelDBTransaction::TransactionIterator::Value() const { |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 | 486 |
| 461 leveldb::Status s = db_->Write(*write_batch_); | 487 leveldb::Status s = db_->Write(*write_batch_); |
| 462 if (s.ok()) { | 488 if (s.ok()) { |
| 463 finished_ = true; | 489 finished_ = true; |
| 464 write_batch_->Clear(); | 490 write_batch_->Clear(); |
| 465 } | 491 } |
| 466 return s; | 492 return s; |
| 467 } | 493 } |
| 468 | 494 |
| 469 } // namespace content | 495 } // namespace content |
| OLD | NEW |