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

Side by Side Diff: chrome/browser/performance_monitor/database.cc

Issue 10545139: Performance Monitor Database (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fixed windows fail 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/format_macros.h"
10 #include "base/logging.h"
11 #include "base/path_service.h"
12 #include "base/string_number_conversions.h"
13 #include "base/stringprintf.h"
14 #include "base/time.h"
15 #include "base/utf_string_conversions.h"
16 #include "chrome/common/chrome_paths.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "third_party/leveldatabase/src/include/leveldb/db.h"
19
20 namespace {
21 const char kDbDir[] = "Performance Monitor Databases";
22 const char kRecentDb[] = "Recent Metrics";
23 const char kEventDb[] = "Events";
24 const char kStateDb[] = "Configuration";
25 const char kActiveIntervalDb[] = "Active Interval";
26 const char kMetricDb[] = "Metrics";
27 const char kDelimiter = '!';
28
29 // If the db is quiet for this number of microseconds, then it is considered
30 // down.
31 const base::TimeDelta kActiveIntervalTimeout = base::TimeDelta::FromSeconds(5);
32
33 // Create the key used for internal active interval monitoring.
34 std::string CreateActiveIntervalKey(const base::Time& time) {
35 return StringPrintf("%016" PRId64, time.ToInternalValue());
36 }
37 } // namespace
38
39 namespace performance_monitor {
40
41 TimeRange::TimeRange() {
42 }
43
44 TimeRange::TimeRange(base::Time start_time, base::Time end_time)
45 : start(start_time),
46 end(end_time) {
47 }
48
49 TimeRange::~TimeRange() {
50 }
51
52 base::Time Database::SystemClock::GetTime() {
53 return base::Time::Now();
54 }
55 bool Database::AddStateValue(const std::string& key, const std::string& value) {
56 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
57 UpdateActiveInterval();
58 leveldb::Status insert_status =
59 state_db_->Put(write_options_, key, value);
60 return insert_status.ok();
61 }
62
63 std::string Database::GetStateValue(const std::string& key) {
64 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
65 std::string result;
66 state_db_->Get(read_options_, key, &result);
67 return result;
68 }
69
70 void Database::Clear() {
71 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
72 metric_db_.reset();
73 recent_db_.reset();
74 state_db_.reset();
75 active_interval_db_.reset();
76 // Recursively delete all the databases.
77 if (!file_util::Delete(path_, true /* recursive */) ||
78 !file_util::CreateDirectory(path_))
79 LOG(ERROR) << "Failed to clear the performance monitor databases.";
80 }
81
82 std::vector<TimeRange> Database::GetActiveIntervals(const base::Time& start,
83 const base::Time& end) {
84 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
85 std::vector<TimeRange> results;
86 std::string start_key = CreateActiveIntervalKey(start);
87 std::string end_key = CreateActiveIntervalKey(end);
88 scoped_ptr<leveldb::Iterator> it(active_interval_db_->NewIterator(
89 read_options_));
90 it->Seek(start_key);
91 int64 start_time;
92 int64 end_time;
93 // Check the previous value in case we jumped in in the middle of an active
94 // interval.
95 if (it->Valid()) {
96 it->Prev();
97 if (it->Valid() && it->value().ToString() > start_key) {
98 base::StringToInt64(it->key().ToString(), &start_time);
99 base::StringToInt64(it->value().ToString(), &end_time);
100 results.push_back(TimeRange(base::Time::FromInternalValue(start_time),
101 base::Time::FromInternalValue(end_time)));
102 }
103 }
104 for (it->Seek(start_key);
105 it->Valid() && it->key().ToString() < end_key;
106 it->Next()) {
107 base::StringToInt64(it->key().ToString(), &start_time);
108 base::StringToInt64(it->value().ToString(), &end_time);
109 results.push_back(TimeRange(base::Time::FromInternalValue(start_time),
110 base::Time::FromInternalValue(end_time)));
111 }
112 return results;
113 }
114
115 Database::Database(const FilePath& path)
116 : path_(path),
117 read_options_(leveldb::ReadOptions()),
118 write_options_(leveldb::WriteOptions()) {
119 leveldb::DB* new_db = NULL;
120 leveldb::Options open_options;
121 open_options.create_if_missing = true;
122
123 #if defined(OS_POSIX)
124 leveldb::DB::Open(open_options, path_.AppendASCII(kRecentDb).value(),
125 &new_db);
126 recent_db_ = scoped_ptr<leveldb::DB>(new_db);
127 leveldb::DB::Open(open_options, path_.AppendASCII(kStateDb).value(),
128 &new_db);
129 state_db_ = scoped_ptr<leveldb::DB>(new_db);
130 leveldb::DB::Open(open_options, path_.AppendASCII(kActiveIntervalDb).value(),
131 &new_db);
132 active_interval_db_ = scoped_ptr<leveldb::DB>(new_db);
133 leveldb::DB::Open(open_options, path_.AppendASCII(kMetricDb).value(),
134 &new_db);
135 metric_db_ = scoped_ptr<leveldb::DB>(new_db);
136 #elif defined(OS_WIN)
137 leveldb::DB::Open(open_options,
138 WideToUTF8(path_.AppendASCII(kRecentDb).value()), &new_db);
139 recent_db_ = scoped_ptr<leveldb::DB>(new_db);
140 leveldb::DB::Open(open_options,
141 WideToUTF8(path_.AppendASCII(kStateDb).value()), &new_db);
142 state_db_ = scoped_ptr<leveldb::DB>(new_db);
143 leveldb::DB::Open(open_options,
144 WideToUTF8(path_.AppendASCII(kActiveIntervalDb).value()),
145 &new_db);
146 active_interval_db_ = scoped_ptr<leveldb::DB>(new_db);
147 leveldb::DB::Open(open_options,
148 WideToUTF8(path_.AppendASCII(kMetricDb).value()), &new_db);
149 metric_db_ = scoped_ptr<leveldb::DB>(new_db);
150 #endif
151 clock_ = scoped_ptr<Clock>(new SystemClock());
152 }
153
154 Database::~Database() {
155 Close();
156 }
157
158 // Static
159 scoped_refptr<Database> Database::Create(FilePath path) {
160 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
161 if (path.empty()) {
162 CHECK(PathService::Get(chrome::DIR_USER_DATA, &path));
163 path = path.AppendASCII(kDbDir);
164 }
165 if (!file_util::DirectoryExists(path) && !file_util::CreateDirectory(path))
166 return scoped_refptr<Database>();
167 return scoped_refptr<Database>(new Database(path));
168 }
169
170 bool Database::Close() {
171 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
172
173 metric_db_.reset();
174 recent_db_.reset();
175 state_db_.reset();
176 active_interval_db_.reset();
177 start_time_key_.clear();
178
179 return true;
180 }
181
182 // TODO(eriq): Only update the active interval under certian circumstances eg.
183 // every 10 times or when forced.
184 void Database::UpdateActiveInterval() {
185 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
186 base::Time current_time = clock_->GetTime();
187 std::string end_time;
188 // If the last update was too long ago.
189 if (start_time_key_.empty() ||
190 current_time - last_update_time_ > kActiveIntervalTimeout) {
191 start_time_key_ = CreateActiveIntervalKey(current_time);
192 end_time = start_time_key_;
193 } else {
194 end_time = CreateActiveIntervalKey(clock_->GetTime());
195 }
196 active_interval_db_->Put(write_options_, start_time_key_, end_time);
197 }
198 } // namespace performance_monitor
OLDNEW
« no previous file with comments | « chrome/browser/performance_monitor/database.h ('k') | chrome/browser/performance_monitor/database_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698