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

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 & lifetime fix 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..3274dcd5d996382b5581ed16875e8378fbb5f979 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_iterator_pool_controller.h"
static leveldb::Slice MakeSlice(const base::StringPiece& s) {
return leveldb::Slice(s.begin(), s.size());
@@ -20,28 +21,42 @@ static base::StringPiece MakeStringPiece(const leveldb::Slice& s) {
namespace content {
LevelDBIteratorImpl::~LevelDBIteratorImpl() {
+ pool_controller_->NotifyIteratorDestroyed(this);
}
-LevelDBIteratorImpl::LevelDBIteratorImpl(std::unique_ptr<leveldb::Iterator> it)
- : iterator_(std::move(it)) {}
+LevelDBIteratorImpl::LevelDBIteratorImpl(
+ std::unique_ptr<leveldb::Iterator> it,
+ LevelDBIteratorPoolController* pool_controller,
+ const leveldb::Snapshot* snapshot)
+ : iterator_(std::move(it)),
+ pool_controller_(pool_controller),
+ snapshot_(snapshot) {}
void LevelDBIteratorImpl::CheckStatus() {
+ DCHECK_EQ(iterator_state_, IteratorState::ACTIVE);
const leveldb::Status& s = iterator_->status();
if (!s.ok())
LOG(ERROR) << "LevelDB iterator error: " << s.ToString();
}
bool LevelDBIteratorImpl::IsValid() const {
- return iterator_->Valid();
+ return iterator_state_ == IteratorState::EVICTED_AND_VALID ||
+ iterator_->Valid();
}
leveldb::Status LevelDBIteratorImpl::SeekToLast() {
+ RecordUsage();
+ RestoreDBIteratorIfEvicted();
pwnall 2017/03/24 09:16:03 I see these two methods together everywhere. Would
dmurph 2017/03/24 23:33:39 Done.
+ DCHECK(iterator_);
iterator_->SeekToLast();
CheckStatus();
return iterator_->status();
}
leveldb::Status LevelDBIteratorImpl::Seek(const base::StringPiece& target) {
+ RecordUsage();
+ RestoreDBIteratorIfEvicted();
+ DCHECK(iterator_);
iterator_->Seek(MakeSlice(target));
CheckStatus();
return iterator_->status();
@@ -49,6 +64,9 @@ leveldb::Status LevelDBIteratorImpl::Seek(const base::StringPiece& target) {
leveldb::Status LevelDBIteratorImpl::Next() {
DCHECK(IsValid());
+ RecordUsage();
+ RestoreDBIteratorIfEvicted();
+ DCHECK(iterator_);
iterator_->Next();
CheckStatus();
return iterator_->status();
@@ -56,6 +74,9 @@ leveldb::Status LevelDBIteratorImpl::Next() {
leveldb::Status LevelDBIteratorImpl::Prev() {
DCHECK(IsValid());
+ RecordUsage();
+ RestoreDBIteratorIfEvicted();
+ DCHECK(iterator_);
iterator_->Prev();
CheckStatus();
return iterator_->status();
@@ -63,12 +84,53 @@ leveldb::Status LevelDBIteratorImpl::Prev() {
base::StringPiece LevelDBIteratorImpl::Key() const {
DCHECK(IsValid());
- return MakeStringPiece(iterator_->key());
+ if (iterator_state_ == IteratorState::ACTIVE)
+ return MakeStringPiece(iterator_->key());
+ return key_before_eviction_;
}
base::StringPiece LevelDBIteratorImpl::Value() const {
DCHECK(IsValid());
+ // Always need to update the LRU, so we always call this. Const-cast needed,
+ // as we're dealing with a caching layer.
+ LevelDBIteratorImpl* non_const = const_cast<LevelDBIteratorImpl*>(this);
+ non_const->RecordUsage();
+ non_const->RestoreDBIteratorIfEvicted();
return MakeStringPiece(iterator_->value());
}
+void LevelDBIteratorImpl::PurgeMemory() {
+ DCHECK_EQ(iterator_state_, IteratorState::ACTIVE);
+ 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::IsEvicted() const {
pwnall 2017/03/24 09:16:03 It's surprising to me that you sometimes call this
dmurph 2017/03/24 23:33:39 Done.
+ return iterator_state_ != IteratorState::ACTIVE;
+}
+
+void LevelDBIteratorImpl::RecordUsage() {
+ pool_controller_->NotifyIteratorUsed(this);
+}
+
+void LevelDBIteratorImpl::RestoreDBIteratorIfEvicted() {
+ if (iterator_state_ == IteratorState::ACTIVE)
+ return;
+
+ iterator_ = pool_controller_->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

Powered by Google App Engine
This is Rietveld 408576698