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

Unified Diff: content/browser/indexed_db/leveldb/leveldb_iterator_impl.cc

Issue 2760163002: [IndexedDB] Pool and evict leveldb iterators, to save memory (Closed)
Patch Set: comments Created 3 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/indexed_db/leveldb/leveldb_iterator_impl.cc
diff --git a/content/browser/indexed_db/leveldb/leveldb_iterator_impl.cc b/content/browser/indexed_db/leveldb/leveldb_iterator_impl.cc
index 2052f437168c65e580b49211ec45ff32d97d5384..b94a3d6150bee704eba43cefa3224682b9e08f60 100644
--- a/content/browser/indexed_db/leveldb/leveldb_iterator_impl.cc
+++ b/content/browser/indexed_db/leveldb/leveldb_iterator_impl.cc
@@ -8,6 +8,7 @@
#include <utility>
#include "base/logging.h"
+#include "content/browser/indexed_db/leveldb/leveldb_database.h"
static leveldb::Slice MakeSlice(const base::StringPiece& s) {
return leveldb::Slice(s.begin(), s.size());
@@ -20,55 +21,102 @@ static base::StringPiece MakeStringPiece(const leveldb::Slice& s) {
namespace content {
LevelDBIteratorImpl::~LevelDBIteratorImpl() {
+ db_->OnIteratorDestroyed(this);
}
-LevelDBIteratorImpl::LevelDBIteratorImpl(std::unique_ptr<leveldb::Iterator> it)
- : iterator_(std::move(it)) {}
+LevelDBIteratorImpl::LevelDBIteratorImpl(std::unique_ptr<leveldb::Iterator> it,
+ LevelDBDatabase* db,
+ const leveldb::Snapshot* snapshot)
+ : iterator_(std::move(it)), db_(db), snapshot_(snapshot) {}
-void LevelDBIteratorImpl::CheckStatus() {
+leveldb::Status LevelDBIteratorImpl::CheckStatus() {
+ DCHECK(!IsDetached());
const leveldb::Status& s = iterator_->status();
if (!s.ok())
LOG(ERROR) << "LevelDB iterator error: " << s.ToString();
+ return s;
}
bool LevelDBIteratorImpl::IsValid() const {
- return iterator_->Valid();
+ return iterator_state_ == IteratorState::EVICTED_AND_VALID ||
+ iterator_->Valid();
}
leveldb::Status LevelDBIteratorImpl::SeekToLast() {
+ WillUseDBIterator();
+ DCHECK(iterator_);
iterator_->SeekToLast();
- CheckStatus();
- return iterator_->status();
+ return CheckStatus();
}
leveldb::Status LevelDBIteratorImpl::Seek(const base::StringPiece& target) {
+ WillUseDBIterator();
+ DCHECK(iterator_);
iterator_->Seek(MakeSlice(target));
- CheckStatus();
- return iterator_->status();
+ return CheckStatus();
}
leveldb::Status LevelDBIteratorImpl::Next() {
DCHECK(IsValid());
+ WillUseDBIterator();
+ DCHECK(iterator_);
iterator_->Next();
- CheckStatus();
- return iterator_->status();
+ return CheckStatus();
}
leveldb::Status LevelDBIteratorImpl::Prev() {
DCHECK(IsValid());
+ WillUseDBIterator();
+ DCHECK(iterator_);
iterator_->Prev();
- CheckStatus();
- return iterator_->status();
+ return CheckStatus();
}
base::StringPiece LevelDBIteratorImpl::Key() const {
DCHECK(IsValid());
+ if (IsDetached())
+ return key_before_eviction_;
return MakeStringPiece(iterator_->key());
}
base::StringPiece LevelDBIteratorImpl::Value() const {
DCHECK(IsValid());
+ // Always need to update the LRU, so we always call this. Const-cast needed,
+ // as we're implementing a caching layer.
+ LevelDBIteratorImpl* non_const = const_cast<LevelDBIteratorImpl*>(this);
+ non_const->WillUseDBIterator();
return MakeStringPiece(iterator_->value());
}
+void LevelDBIteratorImpl::Detach() {
+ DCHECK(!IsDetached());
+ if (iterator_->Valid()) {
+ iterator_state_ = IteratorState::EVICTED_AND_VALID;
+ key_before_eviction_ = iterator_->key().ToString();
+ } else {
+ iterator_state_ = IteratorState::EVICTED_AND_INVALID;
+ }
+ iterator_.reset();
+}
+
+bool LevelDBIteratorImpl::IsDetached() const {
+ return iterator_state_ != IteratorState::ACTIVE;
+}
+
+void LevelDBIteratorImpl::WillUseDBIterator() {
+ db_->OnIteratorUsed(this);
+ if (!IsDetached())
+ return;
+
+ iterator_ = db_->CreateLevelDBIterator(snapshot_);
+ if (iterator_state_ == IteratorState::EVICTED_AND_VALID) {
+ iterator_->Seek(key_before_eviction_);
+ key_before_eviction_.clear();
+ DCHECK(IsValid());
+ } else {
+ DCHECK(!iterator_->Valid());
+ }
+ iterator_state_ = IteratorState::ACTIVE;
+}
+
} // namespace content
« no previous file with comments | « content/browser/indexed_db/leveldb/leveldb_iterator_impl.h ('k') | content/browser/indexed_db/leveldb/leveldb_transaction.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698