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

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: Re-Up 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::AddStateValue(const std::string& key, const std::string& value) {
54 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
55 UpdateActiveInterval();
56 leveldb::Status insert_status =
57 state_db_->Put(write_options_, key, value);
58 return insert_status.ok();
59 }
60
61 std::string Database::GetStateValue(const std::string& key) {
62 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
63 std::string result;
64 state_db_->Get(read_options_, key, &result);
65 return result;
66 }
67
68 void Database::Clear() {
69 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
70 metric_db_.reset();
71 recent_db_.reset();
72 state_db_.reset();
73 active_interval_db_.reset();
74 // Recursively delete all the databases.
75 if (!file_util::Delete(path_, true /* recursive */) ||
76 !file_util::CreateDirectory(path_))
77 LOG(ERROR) << "Failed to clear the performance monitor databases.";
78 }
79
80 std::vector<TimeRange> Database::GetActiveInterval(const base::Time& start,
81 const base::Time& end) {
82 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
83 std::vector<TimeRange> results;
84 std::string start_key = CreateActiveIntervalKey(start);
85 std::string end_key = CreateActiveIntervalKey(end);
86 scoped_ptr<leveldb::Iterator> it(active_interval_db_->NewIterator(
87 read_options_));
88 it->Seek(start_key);
89 int64 start_time;
90 int64 end_time;
91 // Check the previous value in case we jumped in in the middle of an active
92 // interval.
93 it->Prev();
94 if (it->Valid() && it->value().ToString() > start_key) {
95 base::StringToInt64(it->key().ToString(), &start_time);
96 base::StringToInt64(it->value().ToString(), &end_time);
97 results.push_back(TimeRange(base::Time::FromInternalValue(start_time),
98 base::Time::FromInternalValue(end_time)));
99 }
100 for (it->Seek(start_key);
101 it->Valid() && it->key().ToString() < end_key;
102 it->Next()) {
103 base::StringToInt64(it->key().ToString(), &start_time);
104 base::StringToInt64(it->value().ToString(), &end_time);
105 results.push_back(TimeRange(base::Time::FromInternalValue(start_time),
106 base::Time::FromInternalValue(end_time)));
107 }
108 return results;
109 }
110
111 Database::Database(const FilePath& path)
112 : path_(path),
113 read_options_(leveldb::ReadOptions()),
114 write_options_(leveldb::WriteOptions()) {
115 leveldb::DB* new_db = NULL;
116 leveldb::Options open_options;
117 open_options.create_if_missing = true;
118 leveldb::DB::Open(open_options, path_.AppendASCII(kRecentDb).value(),
119 &new_db);
120 recent_db_ = scoped_ptr<leveldb::DB>(new_db);
121 leveldb::DB::Open(open_options, path_.AppendASCII(kStateDb).value(),
122 &new_db);
123 state_db_ = scoped_ptr<leveldb::DB>(new_db);
124 leveldb::DB::Open(open_options, path_.AppendASCII(kActiveIntervalDb).value(),
125 &new_db);
126 active_interval_db_ = scoped_ptr<leveldb::DB>(new_db);
127 leveldb::DB::Open(open_options, path_.AppendASCII(kMetricDb).value(),
128 &new_db);
129 metric_db_ = scoped_ptr<leveldb::DB>(new_db);
130 clock_ = scoped_ptr<Clock>(new SystemClock());
131 }
132
133 Database::~Database() {
134 Close();
135 }
136
137 // Static
138 scoped_refptr<Database> Database::Create(FilePath path) {
139 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
140 if (path.empty()) {
141 CHECK(PathService::Get(chrome::DIR_USER_DATA, &path));
142 path = path.AppendASCII(kDbDir);
143 }
144 if (!file_util::DirectoryExists(path) && !file_util::CreateDirectory(path))
145 return scoped_refptr<Database>();
146 return scoped_refptr<Database>(new Database(path));
147 }
148
149 bool Database::Close() {
150 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
151 UpdateActiveInterval();
152 start_time_key_.clear();
153 return true;
154 }
155
156 // TODO(eriq): Only update the active interval under certian circumstances eg.
157 // every 10 times or when forced.
158 void Database::UpdateActiveInterval() {
159 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
160 base::Time current_time = clock_->GetTime();
161 std::string end_time;
162 // If the last update was too long ago.
163 if (start_time_key_.empty() ||
164 current_time - last_update_time_ > kActiveIntervalTimeout) {
165 start_time_key_ = CreateActiveIntervalKey(current_time);
166 end_time = start_time_key_;
167 } else {
168 end_time = CreateActiveIntervalKey(clock_->GetTime());
169 }
170 active_interval_db_->Put(write_options_, start_time_key_, end_time);
171 }
172 } // 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