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

Unified Diff: third_party/leveldatabase/env_chromium.cc

Issue 2855953002: leveldb: Add DBTracker for exposing databases to Chrome's memory-infra. (Closed)
Patch Set: Created 3 years, 8 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
« no previous file with comments | « third_party/leveldatabase/env_chromium.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/leveldatabase/env_chromium.cc
diff --git a/third_party/leveldatabase/env_chromium.cc b/third_party/leveldatabase/env_chromium.cc
index b4daa541479b695c7b525c20973bc233a9d4da2c..510100599d7d935dfe044a7bf30a3c18c159117c 100644
--- a/third_party/leveldatabase/env_chromium.cc
+++ b/third_party/leveldatabase/env_chromium.cc
@@ -4,6 +4,8 @@
#include "third_party/leveldatabase/env_chromium.h"
+#include <inttypes.h>
+
#include <utility>
#if defined(OS_POSIX)
@@ -21,9 +23,14 @@
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/trace_event/memory_dump_manager.h"
+#include "base/trace_event/memory_dump_provider.h"
+#include "base/trace_event/process_memory_dump.h"
#include "base/threading/thread_restrictions.h"
#include "base/trace_event/trace_event.h"
#include "third_party/leveldatabase/chromium_logger.h"
+#include "third_party/leveldatabase/src/include/leveldb/db.h"
#include "third_party/leveldatabase/src/include/leveldb/options.h"
#include "third_party/re2/src/re2/re2.h"
@@ -1071,6 +1078,153 @@ LevelDBStatusValue GetLevelDBStatusUMAValue(const leveldb::Status& s) {
return LEVELDB_STATUS_INVALID_ARGUMENT;
}
+class DBRegistry::DBProxy: public base::LinkNode<DBProxy>, public leveldb::DB {
+ public:
+ DBProxy(const leveldb::Options& options, const std::string name, leveldb::DB* db)
+ : options_(options), name_(name), db_(db) {
+ DBRegistry::GetInstance()->Register(this);
+ }
+
+ ~DBProxy() override {
+ DBRegistry::GetInstance()->Unregister(this);
+ }
+
+ const leveldb::Options& options() const { return options_; };
+
+ const std::string& name() const { return name_; }
+
+ Status Put(const leveldb::WriteOptions& options,
+ const leveldb::Slice& key,
+ const leveldb::Slice& value) override {
+ return db_->Put(options, key, value);
+ }
+
+ Status Delete(const leveldb::WriteOptions& options,
+ const leveldb::Slice& key) override {
+ return db_->Delete(options, key);
+ }
+
+ Status Write(const leveldb::WriteOptions& options, leveldb::WriteBatch* updates) override {
+ return db_->Write(options, updates);
+ }
+
+ Status Get(const leveldb::ReadOptions& options, const leveldb::Slice& key, std::string* value) override {
+ return db_->Get(options, key, value);
+ }
+
+ leveldb::Iterator* NewIterator(const leveldb::ReadOptions& options) override {
+ return db_->NewIterator(options);
+ }
+
+ const leveldb::Snapshot* GetSnapshot() override {
+ return db_->GetSnapshot();
+ }
+
+ void ReleaseSnapshot(const leveldb::Snapshot* snapshot) override {
+ return db_->ReleaseSnapshot(snapshot);
+ }
+
+ bool GetProperty(const leveldb::Slice& property, std::string* value) override {
+ return db_->GetProperty(property, value);
+ }
+
+ void GetApproximateSizes(const leveldb::Range* range, int n, uint64_t* sizes) override {
+ return db_->GetApproximateSizes(range, n, sizes);
+ }
+
+ void CompactRange(const leveldb::Slice* begin, const leveldb::Slice* end) override {
+ return db_->CompactRange(begin, end);
+ }
+
+ private:
+ leveldb::Options options_;
+ std::string name_;
+ std::unique_ptr<leveldb::DB> db_;
+};
+
+class DBRegistry::MDP: public base::trace_event::MemoryDumpProvider {
+ public:
+ bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
ssid 2017/05/10 23:52:52 If we are adding all the databases here then we sh
+ base::trace_event::ProcessMemoryDump* pmd) override {
+ auto db_dumper = [&](const leveldb::Options& options,
+ const std::string& name,
+ leveldb::DB* db) {
+ std::string db_name;
+ if (name.empty()) {
+ db_name = "<in memory db>";
+ } else {
+ // XXX: 'name' is actually a filesystem path - figure a way to extract
+ // db name only (last component doesn't cut it).
+ //
+ // For now we show the path, but replace slashes with something
+ // that looks like a slash, to make memory-infra show it as a
+ // string (and not as a tree).
+ base::ReplaceChars(name, "/", "\u2215", &db_name);
+ }
+ std::string dump_name = base::StringPrintf(
+ "leveldatabase/%s (0x%" PRIXPTR ")",
+ db_name.c_str(),
+ reinterpret_cast<uintptr_t>(db));
+ auto* dump = pmd->CreateAllocatorDump(dump_name.c_str());
+
+ uint64_t memory_usage = 0;
+ std::string memory_usage_string;
+ bool got_memory_usage =
+ db->GetProperty("leveldb.approximate-memory-usage", &memory_usage_string) &&
+ base::StringToUint64(memory_usage_string, &memory_usage);
+ DCHECK(got_memory_usage);
+
+ dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
+ base::trace_event::MemoryAllocatorDump::kUnitsBytes,
+ memory_usage);
+ };
+
+ DBRegistry::GetInstance()->Visit(db_dumper);
+
+ return true;
+ }
+};
+
+DBRegistry::DBRegistry(): mdp_(new MDP()) {
+ base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
+ mdp_.get(), "LevelDB", nullptr);
+}
+
+DBRegistry::~DBRegistry() = default;
+
+DBRegistry* DBRegistry::GetInstance() {
+ static DBRegistry* instance = new DBRegistry();
+ return instance;
+}
+
+leveldb::Status DBRegistry::Open(const leveldb::Options& options,
+ const std::string& name,
+ leveldb::DB** dbptr) {
+ auto status = leveldb::DB::Open(options, name, dbptr);
+ if (status.ok()) {
+ *dbptr = new DBProxy(options, name, *dbptr);
+ }
+ return status;
+}
+
+void DBRegistry::Visit(const Visitor& visitor) {
+ base::AutoLock lock(lock_);
+ for (auto* i = proxies_.head(); i != proxies_.end(); i = i->next()) {
+ auto* proxy = i->value();
+ visitor(proxy->options(), proxy->name(), proxy);
+ }
+}
+
+void DBRegistry::Register(DBProxy* proxy) {
+ base::AutoLock lock(lock_);
+ proxies_.Append(proxy);
+}
+
+void DBRegistry::Unregister(DBProxy* proxy) {
+ base::AutoLock lock(lock_);
+ proxy->RemoveFromList();
+}
+
} // namespace leveldb_env
namespace leveldb {
« no previous file with comments | « third_party/leveldatabase/env_chromium.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698