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

Side by Side 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: Removed consolidated all the metric databases into one 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/performance_monitor/database.h"
6
7 #include "base/file_path.h"
8 #include "base/file_util.h"
9 #include "base/logging.h"
10 #include "base/path_service.h"
11 #include "base/string_number_conversions.h"
12 #include "base/stringprintf.h"
13 #include "base/time.h"
14 #include "chrome/common/chrome_paths.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "third_party/leveldatabase/src/include/leveldb/db.h"
17
18 namespace {
19 const char kDbDir[] = "Performance Monitor Databases";
20 const char kRecentDb[] = "Recent Metrics";
21 const char kEventDb[] = "Events";
22 const char kStateDb[] = "Configuration";
23 const char kActiveIntervalDb[] = "Active Interval";
24 const char kMetricDb[] = "Metrics";
25 const char kDelimiter = '!';
26
27 // If the db is quiet for this number of microseconds, then it is considered
28 // down.
29 const base::TimeDelta kActiveIntervalTimeout = base::TimeDelta::FromSeconds(5);
30
31 // Create the key used for internal active interval monitoring.
32 std::string CreateActiveIntervalKey(const base::Time& time) {
33 return StringPrintf("%016ld", time.ToInternalValue());
34 }
35 } // namespace
36
37 namespace performance_monitor {
38
39 TimeRange::TimeRange() {
40 }
41
42 TimeRange::TimeRange(base::Time start_time, base::Time end_time)
43 : start(start_time),
44 end(end_time) {
45 }
46
47 TimeRange::~TimeRange() {
48 }
49
50 base::Time Database::SystemClock::GetTime() {
51 return base::Time::Now();
52 }
53 bool Database::AddStateValueOnBackgroundThread(const std::string& key,
54 const std::string& value) {
55 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
56 UpdateActiveIntervalOnBackgroundThread();
57 leveldb::Status insert_status =
58 state_db_->Put(write_options_, key, value);
59 return insert_status.ok();
60 }
61
62 std::string Database::GetStateValueOnBackgroundThread(const std::string& key) {
63 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
64 std::string result;
65 state_db_->Get(read_options_, key, &result);
66 return result;
67 }
68
69 void Database::ClearOnBackgroundThread() {
70 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
71 metric_db_.reset();
72 recent_db_.reset();
73 state_db_.reset();
74 active_interval_db_.reset();
75 // Recursively delete all the databases.
76 if (!file_util::Delete(path_, true /* recursive */) ||
77 !file_util::CreateDirectory(path_))
78 LOG(ERROR) << "Failed to clear the performance monitor databases.";
79 }
80
81 std::vector<TimeRange> Database::GetActiveIntervalOnBackgroundThread(
82 const base::Time& start, const base::Time& end) {
83 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
84 std::vector<TimeRange> results;
85 std::string start_key = CreateActiveIntervalKey(start);
86 std::string end_key = CreateActiveIntervalKey(end);
87 scoped_ptr<leveldb::Iterator> it(active_interval_db_->NewIterator(
88 read_options_));
89 it->Seek(start_key);
90 int64 start_time;
91 int64 end_time;
92 // Check the previous value in case we jumped in in the middle of an active
93 // interval.
94 it->Prev();
95 if (it->Valid() && it->value().ToString() > start_key) {
96 base::StringToInt64(it->key().ToString(), &start_time);
97 base::StringToInt64(it->value().ToString(), &end_time);
98 results.push_back(TimeRange(base::Time::FromInternalValue(start_time),
99 base::Time::FromInternalValue(end_time)));
100 }
101 for (it->Seek(start_key);
102 it->Valid() && it->key().ToString() < end_key;
103 it->Next()) {
104 base::StringToInt64(it->key().ToString(), &start_time);
105 base::StringToInt64(it->value().ToString(), &end_time);
106 results.push_back(TimeRange(base::Time::FromInternalValue(start_time),
107 base::Time::FromInternalValue(end_time)));
108 }
109 return results;
110 }
111
112 Database::Database(const FilePath& path, linked_ptr<Database::Clock> clock)
113 : path_(path),
114 clock_(clock),
115 read_options_(leveldb::ReadOptions()),
116 write_options_(leveldb::WriteOptions()) {
117 start_time_key_ = CreateActiveIntervalKey(clock_->GetTime());
118 last_update_time_ = clock->GetTime();
119 leveldb::DB* new_db = NULL;
120 leveldb::Options open_options;
121 open_options.create_if_missing = true;
122 leveldb::DB::Open(open_options, path_.AppendASCII(kRecentDb).value(),
123 &new_db);
124 recent_db_ = linked_ptr<leveldb::DB>(new_db);
125 leveldb::DB::Open(open_options, path_.AppendASCII(kStateDb).value(),
126 &new_db);
127 state_db_ = linked_ptr<leveldb::DB>(new_db);
128 leveldb::DB::Open(open_options, path_.AppendASCII(kActiveIntervalDb).value(),
129 &new_db);
130 active_interval_db_ = linked_ptr<leveldb::DB>(new_db);
131 leveldb::DB::Open(open_options, path_.AppendASCII(kMetricDb).value(),
132 &new_db);
133 metric_db_ = linked_ptr<leveldb::DB>(new_db);
134 }
135
136 Database::~Database() {
137 CloseOnBackgroundThread();
138 }
139
140 // Static
141 scoped_refptr<Database> Database::InitOnBackgroundThread(
142 FilePath path, linked_ptr<Database::Clock> clock) {
143 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
144 if (path.empty()) {
145 CHECK(PathService::Get(chrome::DIR_USER_DATA, &path));
146 path = path.AppendASCII(kDbDir);
147 }
148 if (!file_util::DirectoryExists(path) && !file_util::CreateDirectory(path))
149 return scoped_refptr<Database>();
150 scoped_refptr<Database> db = new Database(path, clock);
151 return db;
152 }
153
154 bool Database::CloseOnBackgroundThread() {
155 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
156 UpdateActiveIntervalOnBackgroundThread();
157 return true;
158 }
159
160 // TODO(eriq): Only update the active interval under certian circumstances eg.
161 // every 10 times or when forced.
162 void Database::UpdateActiveIntervalOnBackgroundThread() {
163 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
164 base::Time current_time = clock_->GetTime();
165 std::string end_time;
166 // If the last update was too long ago.
167 if (current_time - last_update_time_ > kActiveIntervalTimeout) {
168 start_time_key_ = CreateActiveIntervalKey(current_time);
169 end_time = start_time_key_;
170 } else {
171 end_time = CreateActiveIntervalKey(clock_->GetTime());
172 }
173 active_interval_db_->Put(write_options_, start_time_key_, end_time);
174 }
175 } // namespace performance_monitor
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698