| Index: content/browser/indexed_db/leveldb/leveldb_transaction.cc
|
| diff --git a/content/browser/indexed_db/leveldb/leveldb_transaction.cc b/content/browser/indexed_db/leveldb/leveldb_transaction.cc
|
| index 1722549384aeec3bb98b4a0d8afc4ac75507d778..feb6ec3be73358c958c31e6ee2e485ff4366dd40 100644
|
| --- a/content/browser/indexed_db/leveldb/leveldb_transaction.cc
|
| +++ b/content/browser/indexed_db/leveldb/leveldb_transaction.cc
|
| @@ -41,7 +41,11 @@ LevelDBTransaction::LevelDBTransaction(LevelDBDatabase* db)
|
| LevelDBTransaction::Record::Record() {}
|
| LevelDBTransaction::Record::~Record() {}
|
|
|
| -LevelDBTransaction::~LevelDBTransaction() {}
|
| +LevelDBTransaction::~LevelDBTransaction() {
|
| + for (TransactionIterator* iter : iterators_) {
|
| + db_->NotifyIteratorDestroyed(iter);
|
| + }
|
| +}
|
|
|
| void LevelDBTransaction::Set(const StringPiece& key,
|
| std::string* value,
|
| @@ -248,6 +252,7 @@ bool LevelDBTransaction::TransactionIterator::IsValid() const {
|
| }
|
|
|
| leveldb::Status LevelDBTransaction::TransactionIterator::SeekToLast() {
|
| + LoadDBIteratorIfEvicted();
|
| leveldb::Status s = data_iterator_->SeekToLast();
|
| DCHECK(s.ok());
|
| s = db_iterator_->SeekToLast();
|
| @@ -262,6 +267,7 @@ leveldb::Status LevelDBTransaction::TransactionIterator::SeekToLast() {
|
|
|
| leveldb::Status LevelDBTransaction::TransactionIterator::Seek(
|
| const StringPiece& target) {
|
| + LoadDBIteratorIfEvicted();
|
| leveldb::Status s = data_iterator_->Seek(target);
|
| DCHECK(s.ok());
|
| s = db_iterator_->Seek(target);
|
| @@ -275,6 +281,7 @@ leveldb::Status LevelDBTransaction::TransactionIterator::Seek(
|
| }
|
|
|
| leveldb::Status LevelDBTransaction::TransactionIterator::Next() {
|
| + LoadDBIteratorIfEvicted();
|
| DCHECK(IsValid());
|
| if (data_changed_)
|
| RefreshDataIterator();
|
| @@ -311,6 +318,7 @@ leveldb::Status LevelDBTransaction::TransactionIterator::Next() {
|
| }
|
|
|
| leveldb::Status LevelDBTransaction::TransactionIterator::Prev() {
|
| + LoadDBIteratorIfEvicted();
|
| DCHECK(IsValid());
|
| leveldb::Status s;
|
| if (data_changed_)
|
| @@ -354,6 +362,9 @@ StringPiece LevelDBTransaction::TransactionIterator::Key() const {
|
| DCHECK(IsValid());
|
| if (data_changed_)
|
| RefreshDataIterator();
|
| + if (current_ == db_iterator_.get() && is_evicted_) {
|
| + return key_after_eviction_;
|
| + }
|
| return current_->Key();
|
| }
|
|
|
| @@ -361,9 +372,20 @@ StringPiece LevelDBTransaction::TransactionIterator::Value() const {
|
| DCHECK(IsValid());
|
| if (data_changed_)
|
| RefreshDataIterator();
|
| + if (current_ == db_iterator_.get()) {
|
| + const_cast<LevelDBTransaction::TransactionIterator*>(this)
|
| + ->LoadDBIteratorIfEvicted();
|
| + }
|
| return current_->Value();
|
| }
|
|
|
| +void LevelDBTransaction::TransactionIterator::EvictWorkingMemory() {
|
| + DCHECK(!is_evicted_);
|
| + is_evicted_ = true;
|
| + key_after_eviction_ = db_iterator_->Key().as_string();
|
| + db_iterator_.reset();
|
| +}
|
| +
|
| void LevelDBTransaction::TransactionIterator::DataChanged() {
|
| data_changed_ = true;
|
| }
|
| @@ -411,14 +433,28 @@ void LevelDBTransaction::TransactionIterator::RefreshDataIterator() const {
|
| }
|
|
|
| bool LevelDBTransaction::TransactionIterator::DataIteratorIsLower() const {
|
| + DCHECK(!is_evicted_);
|
| return comparator_->Compare(data_iterator_->Key(), db_iterator_->Key()) < 0;
|
| }
|
|
|
| bool LevelDBTransaction::TransactionIterator::DataIteratorIsHigher() const {
|
| + DCHECK(!is_evicted_);
|
| return comparator_->Compare(data_iterator_->Key(), db_iterator_->Key()) > 0;
|
| }
|
|
|
| +void LevelDBTransaction::TransactionIterator::LoadDBIteratorIfEvicted() {
|
| + transaction_->db_->NotifyIteratorUsed(this);
|
| + if (!is_evicted_)
|
| + return;
|
| +
|
| + db_iterator_ = transaction_->db_->CreateIterator(&transaction_->snapshot_);
|
| + db_iterator_->Seek(key_after_eviction_);
|
| + key_after_eviction_.clear();
|
| + is_evicted_ = false;
|
| +}
|
| +
|
| void LevelDBTransaction::TransactionIterator::HandleConflictsAndDeletes() {
|
| + LoadDBIteratorIfEvicted();
|
| bool loop = true;
|
|
|
| while (loop) {
|
| @@ -452,6 +488,7 @@ void LevelDBTransaction::TransactionIterator::HandleConflictsAndDeletes() {
|
|
|
| void
|
| LevelDBTransaction::TransactionIterator::SetCurrentIteratorToSmallestKey() {
|
| + DCHECK(!is_evicted_);
|
| LevelDBIterator* smallest = nullptr;
|
|
|
| if (data_iterator_->IsValid())
|
| @@ -489,6 +526,7 @@ void LevelDBTransaction::RegisterIterator(TransactionIterator* iterator) {
|
| void LevelDBTransaction::UnregisterIterator(TransactionIterator* iterator) {
|
| DCHECK(iterators_.find(iterator) != iterators_.end());
|
| iterators_.erase(iterator);
|
| + db_->NotifyIteratorDestroyed(iterator);
|
| }
|
|
|
| void LevelDBTransaction::NotifyIterators() {
|
|
|