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

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

Issue 2760163002: [IndexedDB] Pool and evict leveldb iterators, to save memory (Closed)
Patch Set: compile fixed 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_database.cc
diff --git a/content/browser/indexed_db/leveldb/leveldb_database.cc b/content/browser/indexed_db/leveldb/leveldb_database.cc
index 7eaa89405cb23782b5c070ca97947a64edb9f3ef..8804a680b1ee856d5ae45194c4feadefce188495 100644
--- a/content/browser/indexed_db/leveldb/leveldb_database.cc
+++ b/content/browser/indexed_db/leveldb/leveldb_database.cc
@@ -41,6 +41,7 @@
using base::StringPiece;
namespace content {
+static const size_t kDefaultMaxOpenIteratorsPerDatabase = 50;
jsbell 2017/03/22 23:55:32 We should note that this applies only to iterators
dmurph 2017/03/23 20:56:48 Done.
// Forcing flushes to disk at the end of a transaction guarantees that the
// data hit disk, but drastically impacts throughput when the filesystem is
@@ -92,9 +93,15 @@ LevelDBSnapshot::LevelDBSnapshot(LevelDBDatabase* db)
LevelDBSnapshot::~LevelDBSnapshot() { db_->ReleaseSnapshot(snapshot_); }
-LevelDBDatabase::LevelDBDatabase() {}
+LevelDBDatabase::LevelDBDatabase()
+ : iterator_lru_(kDefaultMaxOpenIteratorsPerDatabase) {}
+
+LevelDBDatabase::LevelDBDatabase(size_t max_open_iterators)
+ : iterator_lru_(max_open_iterators) {}
LevelDBDatabase::~LevelDBDatabase() {
+ LOCAL_HISTOGRAM_COUNTS_10000("Storage.IndexedDB.LevelDB.MaxIterators",
+ max_iterators_);
base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
this);
// db_'s destructor uses comparator_adapter_; order of deletion is important.
@@ -285,6 +292,43 @@ static void HistogramLevelDBError(const std::string& histogram_name,
ParseAndHistogramCorruptionDetails(histogram_name, s);
}
+leveldb::Status LevelDBDatabase::OpenForTesting(
jsbell 2017/03/22 23:55:32 Too much duplicated code. :( Can we refactor? I d
dmurph 2017/03/23 20:56:48 Done.
+ const base::FilePath& file_name,
+ const LevelDBComparator* comparator,
+ std::unique_ptr<LevelDBDatabase>* result,
+ size_t max_open_cursors) {
+ IDB_TRACE("LevelDBDatabase::Open");
+ base::TimeTicks begin_time = base::TimeTicks::Now();
+
+ std::unique_ptr<ComparatorAdapter> comparator_adapter(
+ base::MakeUnique<ComparatorAdapter>(comparator));
+
+ std::unique_ptr<leveldb::DB> db;
+ std::unique_ptr<const leveldb::FilterPolicy> filter_policy;
+ const leveldb::Status s = OpenDB(comparator_adapter.get(), LevelDBEnv::Get(),
+ file_name, &db, &filter_policy);
+
+ if (!s.ok()) {
+ HistogramLevelDBError("WebCore.IndexedDB.LevelDBOpenErrors", s);
+ LOG(ERROR) << "Failed to open LevelDB database from "
+ << file_name.AsUTF8Unsafe() << "," << s.ToString();
+ return s;
+ }
+
+ UMA_HISTOGRAM_MEDIUM_TIMES("WebCore.IndexedDB.LevelDB.OpenTime",
+ base::TimeTicks::Now() - begin_time);
+
+ CheckFreeSpace("Success", file_name);
+
+ (*result) = base::WrapUnique(new LevelDBDatabase(max_open_cursors));
+ (*result)->db_ = std::move(db);
+ (*result)->comparator_adapter_ = std::move(comparator_adapter);
+ (*result)->comparator_ = comparator;
+ (*result)->filter_policy_ = std::move(filter_policy);
+ (*result)->file_name_for_tracing = file_name.BaseName().AsUTF8Unsafe();
+ return s;
+}
+
leveldb::Status LevelDBDatabase::Open(const base::FilePath& file_name,
const LevelDBComparator* comparator,
std::unique_ptr<LevelDBDatabase>* result,
@@ -479,4 +523,30 @@ bool LevelDBDatabase::OnMemoryDump(
return true;
}
+void LevelDBDatabase::NotifyIteratorCreated(LevelDBIterator* iter) {
+ num_iterators_++;
+ max_iterators_ = std::max(max_iterators_, num_iterators_);
+}
+
+void LevelDBDatabase::NotifyIteratorUsed(LevelDBIterator* iter) {
+ // This line updates the LRU if the item exists.
+ if (iterator_lru_.Get(iter) != iterator_lru_.end())
+ return;
+ if (iterator_lru_.size() == iterator_lru_.max_size()) {
+ auto to_evict_iter = iterator_lru_.rbegin();
+ LevelDBIterator* to_evict = to_evict_iter->first;
+ to_evict->PurgeMemory();
+ iterator_lru_.Erase(to_evict_iter);
+ }
+ iterator_lru_.Put(iter, iter);
+}
+
+void LevelDBDatabase::NotifyIteratorDestroyed(LevelDBIterator* iter) {
+ DCHECK_GT(num_iterators_, 0u);
+ --num_iterators_;
+ auto it = iterator_lru_.Get(iter);
jsbell 2017/03/22 23:55:32 Peek() instead of Get(), since we don't need to me
dmurph 2017/03/23 20:56:47 Done.
+ if (it == iterator_lru_.end())
+ return;
+ iterator_lru_.Erase(it);
+}
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698