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

Unified Diff: chrome/browser/performance_monitor/database.cc

Issue 10443092: Performance Monitor Database (Closed) Base URL: http://git.chromium.org/chromium/src.git@cpm_event_construction
Patch Set: Synced with changes made in the Event Structure/Construction Cls Created 8 years, 6 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: chrome/browser/performance_monitor/database.cc
diff --git a/chrome/browser/performance_monitor/database.cc b/chrome/browser/performance_monitor/database.cc
new file mode 100644
index 0000000000000000000000000000000000000000..29ac01c9e3ba980cfc892c9f8806a5afe530873b
--- /dev/null
+++ b/chrome/browser/performance_monitor/database.cc
@@ -0,0 +1,172 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/performance_monitor/database.h"
+
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/path_service.h"
+#include "base/string_number_conversions.h"
+#include "base/stringprintf.h"
+#include "base/time.h"
+#include "chrome/common/chrome_paths.h"
+#include "content/public/browser/browser_thread.h"
+#include "third_party/leveldatabase/src/include/leveldb/db.h"
+
+namespace {
+const char kDbDir[] = "performance_monitor_dbs";
Aaron Boodman 2012/06/08 21:40:05 In Chrome, these files are normally named very hum
eaugusti 2012/06/08 22:52:08 Done.
+const char kRecentDb[] = "_performance_monitor_meta_recent";
Aaron Boodman 2012/06/08 21:40:05 Since these are inside the directory, the 'perform
eaugusti 2012/06/08 22:52:08 Done.
+const char kEventDb[] = "_performance_monitor_meta_events";
+const char kStateDb[] = "_performance_monitor_meta_state";
+const char kUptimeDb[] = "_performance_monitor_meta_uptime";
Aaron Boodman 2012/06/08 21:40:05 'uptime' has a well understood meaning that is dif
eaugusti 2012/06/08 22:52:08 How about Active Interval?
+const char kDelimiter = '!';
+
+// If the db is quiet for this number of microseconds, then it is considered
+// down.
+const int kUptimeTimeout = 5 * base::Time::kMicrosecondsPerMinute;
Aaron Boodman 2012/06/08 19:33:56 Typically we either use base::TimeDelate, or encod
eaugusti 2012/06/08 22:52:08 Done.
+
+// Create the key used for internal uptime monitoring.
+std::string CreateUptimeKey(const base::Time& time) {
+ return StringPrintf("%016ld", time.ToInternalValue());
+}
+} // namespace
+
+namespace performance_monitor {
+
+base::Time SystemClock::GetTime() {
+ return base::Time::Now();
+}
+bool Database::AddStateValueOnBackgroundThread(const std::string& key,
+ const std::string& value) {
+ CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ UpdateUptimeOnBackgroundThread();
+ leveldb::DB* state_db = FetchDBOnBackgroundThread(std::string(kStateDb));
Aaron Boodman 2012/06/08 19:33:56 There is implicit conversion from const char[] to
eaugusti 2012/06/08 22:52:08 Done.
+ leveldb::Status insert_status =
+ state_db->Put(write_options_, key, value);
+ return insert_status.ok();
+}
+
+std::string Database::GetStateValueOnBackgroundThread(const std::string& key) {
+ CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ UpdateUptimeOnBackgroundThread();
+ std::string result;
+ leveldb::DB* db = FetchDBOnBackgroundThread(std::string(kStateDb));
+ db->Get(read_options_, key, &result);
+ return result;
+}
+
+void Database::ClearOnBackgroundThread() {
+ CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ LevelDbMap::iterator db_iter;
+ for (db_iter = databases_.begin(); db_iter != databases_.end(); ++db_iter)
+ delete db_iter->second;
Aaron Boodman 2012/06/08 19:33:56 Use linked_ptr so that you don't need to do the de
eaugusti 2012/06/08 22:52:08 Done.
+ databases_.clear();
+ CHECK(file_util::Delete(path_, true));
Aaron Boodman 2012/06/08 19:33:56 Document the magic boolean or use a named constant
Aaron Boodman 2012/06/08 19:33:56 CHECK means: if this condition is false, the code
eaugusti 2012/06/08 22:52:08 Done.
+ CHECK(file_util::CreateDirectory(path_));
+}
+
+Database::TimePairs Database::GetUptimeOnBackgroundThread(
+ const base::Time& start, const base::Time& end) {
+ CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ UpdateUptimeOnBackgroundThread();
Aaron Boodman 2012/06/08 21:40:05 I think you probably don't want to update here.
eaugusti 2012/06/08 22:52:08 Done.
+ TimePairs results;
+ std::string start_key = CreateUptimeKey(start);
+ std::string end_key = CreateUptimeKey(end);
+ leveldb::DB* db = FetchDBOnBackgroundThread(kUptimeDb);
+ leveldb::Iterator* it = db->NewIterator(read_options_);
+ it->Seek(start_key);
+ int64 start_time;
+ int64 end_time;
+ // Check the previous value in case we jumped in in the middle of an uptime.
+ it->Prev();
+ if (it->Valid() && it->value().ToString() > start_key) {
Aaron Boodman 2012/06/08 21:40:05 Scary to compare lexographically. In this case it
eaugusti 2012/06/08 22:52:08 In key generation we pad with enough 0's to make l
+ base::StringToInt64(it->key().ToString(), &start_time);
+ base::StringToInt64(it->value().ToString(), &end_time);
+ results.push_back(std::pair<base::Time, base::Time>(
+ base::Time::FromInternalValue(start_time),
+ base::Time::FromInternalValue(end_time)));
+ }
+ for (it->Seek(start_key);
+ it->Valid() && it->key().ToString() < end_key;
+ it->Next()) {
+ base::StringToInt64(it->key().ToString(), &start_time);
+ base::StringToInt64(it->value().ToString(), &end_time);
+ results.push_back(std::pair<base::Time, base::Time>(
+ base::Time::FromInternalValue(start_time),
+ base::Time::FromInternalValue(end_time)));
+ }
+ delete it;
Aaron Boodman 2012/06/08 21:40:05 scoped_ptr to avoid manual delete?
eaugusti 2012/06/08 22:52:08 Done.
+ return results;
+}
+
+Database::Database(const FilePath& path, scoped_refptr<DBClock> clock)
+ : path_(path),
+ clock_(clock),
+ read_options_(leveldb::ReadOptions()),
+ write_options_(leveldb::WriteOptions()) {
+ start_time_key_ = CreateUptimeKey(clock_->GetTime());
+ last_update_time_ = clock->GetTime();
+ uptime_threshold_ = base::TimeDelta::FromMicroseconds(kUptimeTimeout);
+}
+
+Database::~Database() {
+ CloseOnBackgroundThread();
+}
+
+// Static
+scoped_refptr<Database> Database::InitOnBackgroundThread(
+ FilePath path, scoped_refptr<DBClock> clock) {
+ CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ if (path.empty()) {
+ CHECK(PathService::Get(chrome::DIR_USER_DATA, &path));
+ path = path.AppendASCII(kDbDir);
+ }
+ if (!file_util::DirectoryExists(path) && !file_util::CreateDirectory(path))
+ return scoped_refptr<Database>();
+ scoped_refptr<Database> db = new Database(path, clock);
+ return db;
+}
+
+bool Database::CloseOnBackgroundThread() {
+ CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ UpdateUptimeOnBackgroundThread();
+ LevelDbMap::iterator db_iter;
+ for (db_iter = databases_.begin(); db_iter != databases_.end(); ++db_iter)
+ delete db_iter->second;
+ databases_.clear();
+ return true;
+}
+
+leveldb::DB* Database::FetchDBOnBackgroundThread(const std::string& id) {
+ CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ LevelDbMap::iterator db_iter = databases_.find(id);
+ if (db_iter != databases_.end())
+ return db_iter->second;
+ leveldb::DB* new_db;
Aaron Boodman 2012/06/08 21:40:05 = NULL;
eaugusti 2012/06/08 22:52:08 Done.
+ leveldb::Options open_options;
+ open_options.create_if_missing = true;
+ FilePath db_path = path_.AppendASCII(id);
+ leveldb::Status status = leveldb::DB::Open(open_options, db_path.value(),
+ &new_db);
+ databases_[id] = new_db;
+ return new_db;
+}
+
+// TODO(eriq): Only update uptime under certian circumstances eg. every 10
+// times or when forced.
+void Database::UpdateUptimeOnBackgroundThread() {
+ CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+ leveldb::DB* uptime_db = FetchDBOnBackgroundThread(kUptimeDb);
+ base::Time current_time = clock_->GetTime();
+ std::string end_time;
+ // If the last update was too long ago.
+ if (current_time - last_update_time_ > uptime_threshold_) {
+ start_time_key_ = CreateUptimeKey(current_time);
+ end_time = start_time_key_;
+ } else {
+ end_time = CreateUptimeKey(clock_->GetTime());
+ }
+ uptime_db->Put(write_options_, start_time_key_, end_time);
+}
+} // namespace performance_monitor

Powered by Google App Engine
This is Rietveld 408576698