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

Side by Side Diff: third_party/leveldatabase/env_chromium.cc

Issue 2855953002: leveldb: Add DBTracker for exposing databases to Chrome's memory-infra. (Closed)
Patch Set: Address comments Created 3 years, 5 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved. 1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. See the AUTHORS file for names of contributors. 3 // found in the LICENSE file. See the AUTHORS file for names of contributors.
4 4
5 #include "third_party/leveldatabase/env_chromium.h" 5 #include "third_party/leveldatabase/env_chromium.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #if defined(OS_POSIX) 9 #if defined(OS_POSIX)
10 #include <dirent.h> 10 #include <dirent.h>
11 #include <sys/types.h> 11 #include <sys/types.h>
12 #endif 12 #endif
13 13
14 #include "base/files/file_enumerator.h" 14 #include "base/files/file_enumerator.h"
15 #include "base/files/file_util.h" 15 #include "base/files/file_util.h"
16 #include "base/format_macros.h"
16 #include "base/lazy_instance.h" 17 #include "base/lazy_instance.h"
18 #include "base/logging.h"
17 #include "base/macros.h" 19 #include "base/macros.h"
18 #include "base/metrics/histogram_functions.h" 20 #include "base/metrics/histogram_functions.h"
19 #include "base/process/process_metrics.h" 21 #include "base/process/process_metrics.h"
20 #include "base/stl_util.h" 22 #include "base/stl_util.h"
23 #include "base/strings/string_number_conversions.h"
21 #include "base/strings/string_util.h" 24 #include "base/strings/string_util.h"
22 #include "base/strings/stringprintf.h" 25 #include "base/strings/stringprintf.h"
23 #include "base/strings/utf_string_conversions.h" 26 #include "base/strings/utf_string_conversions.h"
24 #include "base/threading/thread_restrictions.h" 27 #include "base/threading/thread_restrictions.h"
28 #include "base/trace_event/memory_dump_manager.h"
29 #include "base/trace_event/memory_dump_provider.h"
30 #include "base/trace_event/process_memory_dump.h"
25 #include "base/trace_event/trace_event.h" 31 #include "base/trace_event/trace_event.h"
26 #include "third_party/leveldatabase/chromium_logger.h" 32 #include "third_party/leveldatabase/chromium_logger.h"
27 #include "third_party/leveldatabase/src/include/leveldb/options.h" 33 #include "third_party/leveldatabase/src/include/leveldb/options.h"
28 #include "third_party/re2/src/re2/re2.h" 34 #include "third_party/re2/src/re2/re2.h"
29 35
30 using base::FilePath; 36 using base::FilePath;
31 using leveldb::FileLock; 37 using leveldb::FileLock;
32 using leveldb::Slice; 38 using leveldb::Slice;
33 using leveldb::Status; 39 using leveldb::Status;
34 40
(...skipping 1053 matching lines...) Expand 10 before | Expand all | Expand 10 after
1088 return LEVELDB_STATUS_CORRUPTION; 1094 return LEVELDB_STATUS_CORRUPTION;
1089 if (s.IsNotSupportedError()) 1095 if (s.IsNotSupportedError())
1090 return LEVELDB_STATUS_NOT_SUPPORTED; 1096 return LEVELDB_STATUS_NOT_SUPPORTED;
1091 if (s.IsIOError()) 1097 if (s.IsIOError())
1092 return LEVELDB_STATUS_IO_ERROR; 1098 return LEVELDB_STATUS_IO_ERROR;
1093 // TODO(cmumford): IsInvalidArgument() was just added to leveldb. Use this 1099 // TODO(cmumford): IsInvalidArgument() was just added to leveldb. Use this
1094 // function once that change goes to the public repository. 1100 // function once that change goes to the public repository.
1095 return LEVELDB_STATUS_INVALID_ARGUMENT; 1101 return LEVELDB_STATUS_INVALID_ARGUMENT;
1096 } 1102 }
1097 1103
1104 // Forwards all calls to the underlying leveldb::DB instance.
1105 // Adds / removes itself in the DBTracker it's created with.
1106 class DBTracker::TrackedDBImpl : public base::LinkNode<TrackedDBImpl>,
1107 public TrackedDB {
1108 public:
1109 TrackedDBImpl(DBTracker* tracker, const std::string name, leveldb::DB* db)
1110 : tracker_(tracker), name_(name), db_(db) {
1111 tracker_->DatabaseOpened(this);
1112 }
1113
1114 ~TrackedDBImpl() override { tracker_->DatabaseDestroyed(this); }
1115
1116 const std::string& name() const override { return name_; }
1117
1118 leveldb::Status Put(const leveldb::WriteOptions& options,
1119 const leveldb::Slice& key,
1120 const leveldb::Slice& value) override {
1121 return db_->Put(options, key, value);
1122 }
1123
1124 leveldb::Status Delete(const leveldb::WriteOptions& options,
1125 const leveldb::Slice& key) override {
1126 return db_->Delete(options, key);
1127 }
1128
1129 leveldb::Status Write(const leveldb::WriteOptions& options,
1130 leveldb::WriteBatch* updates) override {
1131 return db_->Write(options, updates);
1132 }
1133
1134 leveldb::Status Get(const leveldb::ReadOptions& options,
1135 const leveldb::Slice& key,
1136 std::string* value) override {
1137 return db_->Get(options, key, value);
1138 }
1139
1140 const leveldb::Snapshot* GetSnapshot() override { return db_->GetSnapshot(); }
1141
1142 void ReleaseSnapshot(const leveldb::Snapshot* snapshot) override {
1143 return db_->ReleaseSnapshot(snapshot);
1144 }
1145
1146 bool GetProperty(const leveldb::Slice& property,
1147 std::string* value) override {
1148 return db_->GetProperty(property, value);
1149 }
1150
1151 void GetApproximateSizes(const leveldb::Range* range,
1152 int n,
1153 uint64_t* sizes) override {
1154 return db_->GetApproximateSizes(range, n, sizes);
1155 }
1156
1157 void CompactRange(const leveldb::Slice* begin,
1158 const leveldb::Slice* end) override {
1159 return db_->CompactRange(begin, end);
1160 }
1161
1162 leveldb::Iterator* NewIterator(const leveldb::ReadOptions& options) override {
1163 return db_->NewIterator(options);
1164 }
1165
1166 private:
1167 DBTracker* tracker_;
1168 std::string name_;
1169 std::unique_ptr<leveldb::DB> db_;
1170 };
1171
1172 // Reports live databases to memory-infra. For each live database the following
1173 // information is reported:
1174 // 1. Instance pointer (to disambiguate databases).
1175 // 2. Memory taken by the database.
1176 // 3. The name of the database (when not in BACKGROUND mode to avoid exposing
1177 // PIIs in slow reports).
1178 //
1179 // Example report (as seen after clicking "leveldatabase" in "Overview" pane
1180 // in Chrome tracing UI):
1181 //
1182 // Component size name
1183 // ---------------------------------------------------------------------------
1184 // leveldatabase 204.4 KiB
1185 // 0x7FE70F2040A0 4.0 KiB /Users/.../data_reduction_proxy_leveldb
1186 // 0x7FE70F530D80 188.4 KiB /Users/.../Sync Data/LevelDB
1187 // 0x7FE71442F270 4.0 KiB /Users/.../Sync App Settings/...
1188 // 0x7FE71471EC50 8.0 KiB /Users/.../Extension State
1189 //
1190 class DBTracker::MemoryDumpProvider
1191 : public base::trace_event::MemoryDumpProvider {
1192 public:
1193 bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
1194 base::trace_event::ProcessMemoryDump* pmd) override {
1195 auto db_visitor = [&](TrackedDB* db) {
1196 std::string db_dump_name = base::StringPrintf(
1197 "leveldatabase/0x%" PRIXPTR, reinterpret_cast<uintptr_t>(db));
1198 auto* db_dump = pmd->CreateAllocatorDump(db_dump_name.c_str());
1199
1200 uint64_t db_memory_usage = 0;
1201 {
1202 std::string usage_string;
1203 bool success = db->GetProperty("leveldb.approximate-memory-usage",
1204 &usage_string) &&
1205 base::StringToUint64(usage_string, &db_memory_usage);
1206 DCHECK(success);
1207 }
1208 db_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
1209 base::trace_event::MemoryAllocatorDump::kUnitsBytes,
1210 db_memory_usage);
1211
1212 if (args.level_of_detail !=
1213 base::trace_event::MemoryDumpLevelOfDetail::BACKGROUND) {
1214 db_dump->AddString("name", "", db->name());
1215 }
1216
1217 const char* system_allocator_name =
1218 base::trace_event::MemoryDumpManager::GetInstance()
1219 ->system_allocator_pool_name();
1220 if (system_allocator_name) {
1221 pmd->AddSuballocation(db_dump->guid(), system_allocator_name);
1222 }
1223 };
1224
1225 DBTracker::GetInstance()->VisitDatabases(db_visitor);
1226 return true;
1227 }
1228 };
1229
1230 DBTracker::DBTracker() : mdp_(new MemoryDumpProvider()) {
1231 base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
1232 mdp_.get(), "LevelDB", nullptr);
1233 }
1234
1235 DBTracker::~DBTracker() {
1236 NOTREACHED(); // DBTracker is a singleton
1237 }
1238
1239 DBTracker* DBTracker::GetInstance() {
1240 static DBTracker* instance = new DBTracker();
1241 return instance;
1242 }
1243
1244 leveldb::Status DBTracker::OpenDatabase(const leveldb::Options& options,
1245 const std::string& name,
1246 TrackedDB** dbptr) {
1247 leveldb::DB* db = nullptr;
1248 auto status = leveldb::DB::Open(options, name, &db);
1249 if (status.ok()) {
1250 // TrackedDBImpl ctor adds the instance to the tracker.
1251 *dbptr = new TrackedDBImpl(GetInstance(), name, db);
1252 }
1253 return status;
1254 }
1255
1256 void DBTracker::VisitDatabases(const DatabaseVisitor& visitor) {
1257 base::AutoLock lock(databases_lock_);
1258 for (auto* i = databases_.head(); i != databases_.end(); i = i->next()) {
1259 visitor(i->value());
1260 }
1261 }
1262
1263 void DBTracker::DatabaseOpened(TrackedDBImpl* database) {
1264 base::AutoLock lock(databases_lock_);
1265 databases_.Append(database);
1266 }
1267
1268 void DBTracker::DatabaseDestroyed(TrackedDBImpl* database) {
1269 base::AutoLock lock(databases_lock_);
1270 database->RemoveFromList();
1271 }
1272
1273 leveldb::Status OpenDB(const leveldb::Options& options,
1274 const std::string& name,
1275 std::unique_ptr<leveldb::DB>* dbptr) {
1276 DBTracker::TrackedDB* tracked_db = nullptr;
1277 leveldb::Status status =
1278 DBTracker::GetInstance()->OpenDatabase(options, name, &tracked_db);
1279 if (status.ok()) {
1280 dbptr->reset(tracked_db);
1281 }
1282 return status;
1283 }
1284
1098 } // namespace leveldb_env 1285 } // namespace leveldb_env
1099 1286
1100 namespace leveldb { 1287 namespace leveldb {
1101 1288
1102 Env* Env::Default() { 1289 Env* Env::Default() {
1103 return leveldb_env::default_env.Pointer(); 1290 return leveldb_env::default_env.Pointer();
1104 } 1291 }
1105 1292
1106 } // namespace leveldb 1293 } // namespace leveldb
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698