OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/performance_monitor/database.h" | 5 #include "chrome/browser/performance_monitor/database.h" |
6 | 6 |
7 #include "base/file_path.h" | 7 #include "base/file_path.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
11 #include "base/json/json_writer.h" | 11 #include "base/json/json_writer.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/path_service.h" | 13 #include "base/path_service.h" |
14 #include "base/string_number_conversions.h" | 14 #include "base/string_number_conversions.h" |
15 #include "base/string_split.h" | 15 #include "base/string_split.h" |
16 #include "base/stringprintf.h" | 16 #include "base/stringprintf.h" |
17 #include "base/time.h" | 17 #include "base/time.h" |
18 #include "base/utf_string_conversions.h" | 18 #include "base/utf_string_conversions.h" |
19 #include "chrome/common/chrome_paths.h" | 19 #include "chrome/common/chrome_paths.h" |
20 #include "content/public/browser/browser_thread.h" | 20 #include "content/public/browser/browser_thread.h" |
21 #include "third_party/leveldatabase/src/include/leveldb/db.h" | 21 #include "third_party/leveldatabase/src/include/leveldb/db.h" |
22 | 22 |
| 23 namespace performance_monitor { |
23 namespace { | 24 namespace { |
24 const char kDbDir[] = "Performance Monitor Databases"; | 25 const char kDbDir[] = "Performance Monitor Databases"; |
25 const char kRecentDb[] = "Recent Metrics"; | 26 const char kRecentDb[] = "Recent Metrics"; |
26 const char kEventDb[] = "Events"; | 27 const char kEventDb[] = "Events"; |
27 const char kStateDb[] = "Configuration"; | 28 const char kStateDb[] = "Configuration"; |
28 const char kActiveIntervalDb[] = "Active Interval"; | 29 const char kActiveIntervalDb[] = "Active Interval"; |
29 const char kMetricDb[] = "Metrics"; | 30 const char kMetricDb[] = "Metrics"; |
30 const char kDelimiter = '!'; | 31 const char kDelimiter = '!'; |
31 | 32 |
32 struct RecentKey { | 33 struct RecentKey { |
33 RecentKey(const std::string& recent_time, const std::string& recent_metric, | 34 RecentKey(const std::string& recent_time, |
34 const std::string& recent_activity) | 35 MetricType recent_type, |
| 36 const std::string& recent_activity) |
35 : time(recent_time), | 37 : time(recent_time), |
36 metric(recent_metric), | 38 type(recent_type), |
37 activity(recent_activity) {} | 39 activity(recent_activity) {} |
38 ~RecentKey() {} | 40 ~RecentKey() {} |
39 | 41 |
40 const std::string time; | 42 const std::string time; |
41 const std::string metric; | 43 const MetricType type; |
42 const std::string activity; | 44 const std::string activity; |
43 }; | 45 }; |
44 | 46 |
45 struct MetricKey { | 47 struct MetricKey { |
46 MetricKey(const std::string& metric_time, const std::string& metric_metric, | 48 MetricKey(const std::string& metric_time, |
47 const std::string& metric_activity) | 49 MetricType metric_type, |
| 50 const std::string& metric_activity) |
48 : time(metric_time), | 51 : time(metric_time), |
49 metric(metric_metric), | 52 type(metric_type), |
50 activity(metric_activity) {} | 53 activity(metric_activity) {} |
51 ~MetricKey() {} | 54 ~MetricKey() {} |
52 | 55 |
53 const std::string time; | 56 const std::string time; |
54 const std::string metric; | 57 const MetricType type; |
55 const std::string activity; | 58 const std::string activity; |
56 }; | 59 }; |
57 | 60 |
58 // The position of different elements in the key for the event db. | 61 // The position of different elements in the key for the event db. |
59 enum EventKeyPosition { | 62 enum EventKeyPosition { |
60 EVENT_TIME, // The time the event was generated. | 63 EVENT_TIME, // The time the event was generated. |
61 EVENT_TYPE // The type of event. | 64 EVENT_TYPE // The type of event. |
62 }; | 65 }; |
63 | 66 |
64 // The position of different elements in the key for the recent db. | 67 // The position of different elements in the key for the recent db. |
65 enum RecentKeyPosition { | 68 enum RecentKeyPosition { |
66 RECENT_TIME, // The time the stat was gathered. | 69 RECENT_TIME, // The time the stat was gathered. |
67 RECENT_METRIC, // The unique identifier for the type of metric gathered. | 70 RECENT_TYPE, // The unique identifier for the type of metric gathered. |
68 RECENT_ACTIVITY // The unique identifier for the activity. | 71 RECENT_ACTIVITY // The unique identifier for the activity. |
69 }; | 72 }; |
70 | 73 |
71 // The position of different elements in the key for a metric db. | 74 // The position of different elements in the key for a metric db. |
72 enum MetricKeyPosition { | 75 enum MetricKeyPosition { |
73 METRIC_METRIC, // The unique identifier for the metric. | 76 METRIC_TYPE, // The unique identifier for the metric. |
74 METRIC_TIME, // The time the stat was gathered. | 77 METRIC_TIME, // The time the stat was gathered. |
75 METRIC_ACTIVITY // The unique identifier for the activity. | 78 METRIC_ACTIVITY // The unique identifier for the activity. |
76 }; | 79 }; |
77 | 80 |
78 // If the db is quiet for this number of minutes, then it is considered down. | 81 // If the db is quiet for this number of minutes, then it is considered down. |
79 const base::TimeDelta kActiveIntervalTimeout = base::TimeDelta::FromMinutes(5); | 82 const base::TimeDelta kActiveIntervalTimeout = base::TimeDelta::FromMinutes(5); |
80 | 83 |
81 // Create the key used for internal active interval monitoring. | 84 // Create the key used for internal active interval monitoring. |
82 // Key Schema: <Time> | 85 // Key Schema: <Time> |
83 std::string CreateActiveIntervalKey(const base::Time& time) { | 86 std::string CreateActiveIntervalKey(const base::Time& time) { |
84 return StringPrintf("%016" PRId64, time.ToInternalValue()); | 87 return StringPrintf("%016" PRId64, time.ToInternalValue()); |
85 } | 88 } |
86 | 89 |
87 // Create the database key for a particular event. | 90 // Create the database key for a particular event. |
88 // Key Schema: <Time>-<Event Type> | 91 // Key Schema: <Time>-<Event Type> |
89 // Where '-' represents the delimiter. | 92 // Where '-' represents the delimiter. |
90 std::string CreateEventKey(const base::Time& time, | 93 std::string CreateEventKey(const base::Time& time, EventType event_type) { |
91 performance_monitor::EventType type) { | |
92 return StringPrintf("%016" PRId64 "%c%04d", time.ToInternalValue(), | 94 return StringPrintf("%016" PRId64 "%c%04d", time.ToInternalValue(), |
93 kDelimiter, static_cast<int>(type)); | 95 kDelimiter, static_cast<int>(event_type)); |
94 } | 96 } |
95 | 97 |
96 // Create the database key for a certain metric to go in the "Recent" database. | 98 // Create the database key for a certain metric to go in the "Recent" database. |
97 // Key Schema: <Time>-<Metric>-<Activity> | 99 // Key Schema: <Time>-<Metric>-<Activity> |
98 std::string CreateRecentKey(const base::Time& time, | 100 std::string CreateRecentKey(const base::Time& time, |
99 const std::string& metric, | 101 MetricType metric_type, |
100 const std::string& activity) { | 102 const std::string& activity) { |
101 return StringPrintf("%016" PRId64 "%c%s%c%s", time.ToInternalValue(), | 103 return StringPrintf("%016" PRId64 "%c%04d%c%s", time.ToInternalValue(), |
102 kDelimiter, metric.c_str(), kDelimiter, activity.c_str()); | 104 kDelimiter, metric_type, kDelimiter, activity.c_str()); |
| 105 } |
| 106 |
| 107 EventType EventKeyToEventType(const std::string& event_key) { |
| 108 std::vector<std::string> split; |
| 109 base::SplitString(event_key, kDelimiter, &split); |
| 110 int event_type = 0; |
| 111 base::StringToInt(split[EVENT_TYPE], &event_type); |
| 112 return static_cast<EventType>(event_type); |
| 113 } |
| 114 |
| 115 MetricType StringToMetricType(const std::string& metric_type) { |
| 116 int metric_type_int = 0; |
| 117 base::StringToInt(metric_type, &metric_type_int); |
| 118 return static_cast<MetricType>(metric_type_int); |
103 } | 119 } |
104 | 120 |
105 RecentKey SplitRecentKey(const std::string& key) { | 121 RecentKey SplitRecentKey(const std::string& key) { |
106 std::vector<std::string> split; | 122 std::vector<std::string> split; |
107 base::SplitString(key, kDelimiter, &split); | 123 base::SplitString(key, kDelimiter, &split); |
108 return RecentKey(split[RECENT_TIME], split[RECENT_METRIC], | 124 return RecentKey(split[RECENT_TIME], StringToMetricType(split[RECENT_TYPE]), |
109 split[RECENT_ACTIVITY]); | 125 split[RECENT_ACTIVITY]); |
110 } | 126 } |
111 | 127 |
112 // Create the database key for a statistic of a certain metric. | 128 // Create the database key for a statistic of a certain metric. |
113 // Key Schema: <Metric>-<Time>-<Activity> | 129 // Key Schema: <Metric>-<Time>-<Activity> |
114 std::string CreateMetricKey(const base::Time& time, | 130 std::string CreateMetricKey(const base::Time& time, |
115 const std::string& metric, | 131 MetricType metric_type, |
116 const std::string& activity) { | 132 const std::string& activity) { |
117 return StringPrintf("%s%c%016" PRId64 "%c%s", metric.c_str(), kDelimiter, | 133 return StringPrintf("%04d%c%016" PRId64 "%c%s", metric_type, kDelimiter, |
118 time.ToInternalValue(), kDelimiter, activity.c_str()); | 134 time.ToInternalValue(), kDelimiter, activity.c_str()); |
119 } | 135 } |
120 | 136 |
121 MetricKey SplitMetricKey(const std::string& key) { | 137 MetricKey SplitMetricKey(const std::string& key) { |
122 std::vector<std::string> split; | 138 std::vector<std::string> split; |
123 base::SplitString(key, kDelimiter, &split); | 139 base::SplitString(key, kDelimiter, &split); |
124 return MetricKey(split[METRIC_TIME], split[METRIC_METRIC], | 140 return MetricKey(split[METRIC_TIME], StringToMetricType(split[METRIC_TYPE]), |
125 split[METRIC_ACTIVITY]); | 141 split[METRIC_ACTIVITY]); |
126 } | 142 } |
127 | 143 |
128 // Create the key for recent_map_. | 144 // Create the key for recent_map_. |
129 // Key Schema: <Activity>-<Metric> | 145 // Key Schema: <Activity>-<Metric> |
130 std::string CreateRecentMapKey(const std::string& metric, | 146 std::string CreateRecentMapKey(MetricType metric_type, |
131 const std::string& activity) { | 147 const std::string& activity) { |
132 return activity + kDelimiter + metric; | 148 return StringPrintf("%s%c%04d", activity.c_str(), kDelimiter, metric_type); |
133 } | 149 } |
134 | 150 |
135 int EventKeyToType(const std::string& event_key) { | 151 TimeRange ActiveIntervalToTimeRange(const std::string& start_time, |
136 std::vector<std::string> split; | 152 const std::string& end_time) { |
137 base::SplitString(event_key, kDelimiter, &split); | |
138 int event_type; | |
139 base::StringToInt(split[EVENT_TYPE], &event_type); | |
140 return event_type; | |
141 } | |
142 | |
143 performance_monitor::TimeRange ActiveIntervalToTimeRange( | |
144 const std::string& start_time, | |
145 const std::string& end_time) { | |
146 int64 start_time_int = 0; | 153 int64 start_time_int = 0; |
147 int64 end_time_int = 0; | 154 int64 end_time_int = 0; |
148 base::StringToInt64(start_time, &start_time_int); | 155 base::StringToInt64(start_time, &start_time_int); |
149 base::StringToInt64(end_time, &end_time_int); | 156 base::StringToInt64(end_time, &end_time_int); |
150 return performance_monitor::TimeRange( | 157 return TimeRange(base::Time::FromInternalValue(start_time_int), |
151 base::Time::FromInternalValue(start_time_int), | 158 base::Time::FromInternalValue(end_time_int)); |
152 base::Time::FromInternalValue(end_time_int)); | |
153 } | 159 } |
154 | 160 |
155 } // namespace | 161 } // namespace |
156 | 162 |
157 namespace performance_monitor { | |
158 | |
159 const char Database::kDatabaseSequenceToken[] = | 163 const char Database::kDatabaseSequenceToken[] = |
160 "_performance_monitor_db_sequence_token_"; | 164 "_performance_monitor_db_sequence_token_"; |
161 | 165 |
162 TimeRange::TimeRange() { | 166 TimeRange::TimeRange() { |
163 } | 167 } |
164 | 168 |
165 TimeRange::TimeRange(base::Time start_time, base::Time end_time) | 169 TimeRange::TimeRange(base::Time start_time, base::Time end_time) |
166 : start(start_time), | 170 : start(start_time), |
167 end(end_time) { | 171 end(end_time) { |
168 } | 172 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 const base::Time& end) { | 248 const base::Time& end) { |
245 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 249 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
246 EventList events; | 250 EventList events; |
247 std::string start_key = CreateEventKey(start, EVENT_UNDEFINED); | 251 std::string start_key = CreateEventKey(start, EVENT_UNDEFINED); |
248 std::string end_key = CreateEventKey(end, EVENT_NUMBER_OF_EVENTS); | 252 std::string end_key = CreateEventKey(end, EVENT_NUMBER_OF_EVENTS); |
249 scoped_ptr<leveldb::Iterator> it(event_db_->NewIterator(read_options_)); | 253 scoped_ptr<leveldb::Iterator> it(event_db_->NewIterator(read_options_)); |
250 for (it->Seek(start_key); | 254 for (it->Seek(start_key); |
251 it->Valid() && it->key().ToString() <= end_key; | 255 it->Valid() && it->key().ToString() <= end_key; |
252 it->Next()) { | 256 it->Next()) { |
253 if (type != EVENT_UNDEFINED) { | 257 if (type != EVENT_UNDEFINED) { |
254 int key_type = EventKeyToType(it->key().ToString()); | 258 EventType key_type = EventKeyToEventType(it->key().ToString()); |
255 if (key_type != type) | 259 if (key_type != type) |
256 continue; | 260 continue; |
257 } | 261 } |
258 base::DictionaryValue* dict = NULL; | 262 base::DictionaryValue* dict = NULL; |
259 if (!base::JSONReader::Read( | 263 if (!base::JSONReader::Read( |
260 it->value().ToString())->GetAsDictionary(&dict)) { | 264 it->value().ToString())->GetAsDictionary(&dict)) { |
261 LOG(ERROR) << "Unable to convert database event to JSON."; | 265 LOG(ERROR) << "Unable to convert database event to JSON."; |
262 continue; | 266 continue; |
263 } | 267 } |
264 scoped_ptr<Event> event = | 268 scoped_ptr<Event> event = |
265 Event::FromValue(scoped_ptr<base::DictionaryValue>(dict)); | 269 Event::FromValue(scoped_ptr<base::DictionaryValue>(dict)); |
266 if (!event.get()) | 270 if (!event.get()) |
267 continue; | 271 continue; |
268 events.push_back(linked_ptr<Event>(event.release())); | 272 events.push_back(linked_ptr<Event>(event.release())); |
269 } | 273 } |
270 return events; | 274 return events; |
271 } | 275 } |
272 | 276 |
273 Database::EventTypeSet Database::GetEventTypes(const base::Time& start, | 277 Database::EventTypeSet Database::GetEventTypes(const base::Time& start, |
274 const base::Time& end) { | 278 const base::Time& end) { |
275 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 279 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
276 EventTypeSet results; | 280 EventTypeSet results; |
277 std::string start_key = CreateEventKey(start, EVENT_UNDEFINED); | 281 std::string start_key = CreateEventKey(start, EVENT_UNDEFINED); |
278 std::string end_key = CreateEventKey(end, EVENT_NUMBER_OF_EVENTS); | 282 std::string end_key = CreateEventKey(end, EVENT_NUMBER_OF_EVENTS); |
279 scoped_ptr<leveldb::Iterator> it(event_db_->NewIterator(read_options_)); | 283 scoped_ptr<leveldb::Iterator> it(event_db_->NewIterator(read_options_)); |
280 for (it->Seek(start_key); | 284 for (it->Seek(start_key); |
281 it->Valid() && it->key().ToString() <= end_key; | 285 it->Valid() && it->key().ToString() <= end_key; |
282 it->Next()) { | 286 it->Next()) { |
283 int key_type = EventKeyToType(it->key().ToString()); | 287 EventType key_type = EventKeyToEventType(it->key().ToString()); |
284 results.insert(static_cast<EventType>(key_type)); | 288 results.insert(key_type); |
285 } | 289 } |
286 return results; | 290 return results; |
287 } | 291 } |
288 | 292 |
289 bool Database::AddMetric(const std::string& activity, const std::string& metric, | 293 bool Database::AddMetric(const std::string& activity, MetricType metric, |
290 const std::string& value) { | 294 const std::string& value) { |
291 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 295 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
292 UpdateActiveInterval(); | 296 UpdateActiveInterval(); |
293 base::Time timestamp = clock_->GetTime(); | 297 base::Time timestamp = clock_->GetTime(); |
294 std::string recent_key = CreateRecentKey(timestamp, metric, activity); | 298 std::string recent_key = CreateRecentKey(timestamp, metric, activity); |
295 std::string metric_key = CreateMetricKey(timestamp, metric, activity); | 299 std::string metric_key = CreateMetricKey(timestamp, metric, activity); |
296 std::string recent_map_key = CreateRecentMapKey(metric, activity); | 300 std::string recent_map_key = CreateRecentMapKey(metric, activity); |
297 // Use recent_map_ to quickly find the key that must be removed. | 301 // Use recent_map_ to quickly find the key that must be removed. |
298 RecentMap::iterator old_it = recent_map_.find(recent_map_key); | 302 RecentMap::iterator old_it = recent_map_.find(recent_map_key); |
299 if (old_it != recent_map_.end()) | 303 if (old_it != recent_map_.end()) |
300 recent_db_->Delete(write_options_, old_it->second); | 304 recent_db_->Delete(write_options_, old_it->second); |
301 recent_map_[recent_map_key] = recent_key; | 305 recent_map_[recent_map_key] = recent_key; |
302 leveldb::Status recent_status = | 306 leveldb::Status recent_status = |
303 recent_db_->Put(write_options_, recent_key, value); | 307 recent_db_->Put(write_options_, recent_key, value); |
304 leveldb::Status metric_status = | 308 leveldb::Status metric_status = |
305 metric_db_->Put(write_options_, metric_key, value); | 309 metric_db_->Put(write_options_, metric_key, value); |
306 return recent_status.ok() && metric_status.ok(); | 310 return recent_status.ok() && metric_status.ok(); |
307 } | 311 } |
308 | 312 |
309 void Database::AddMetricDetails(const MetricDetails& details) { | 313 std::vector<const MetricDetails*> Database::GetActiveMetrics( |
310 UpdateActiveInterval(); | 314 const base::Time& start, const base::Time& end) { |
311 metric_details_map_[details.name] = details; | 315 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
312 } | 316 std::vector<const MetricDetails*> results; |
| 317 std::string recent_start_key = CreateRecentKey( |
| 318 start, static_cast<MetricType>(0), std::string()); |
| 319 std::string recent_end_key = CreateRecentKey( |
| 320 end, METRIC_NUMBER_OF_METRICS, std::string()); |
| 321 std::string recent_end_of_time_key = CreateRecentKey( |
| 322 clock_->GetTime(), METRIC_NUMBER_OF_METRICS, std::string()); |
313 | 323 |
314 std::vector<MetricDetails> Database::GetActiveMetrics(const base::Time& start, | 324 std::set<MetricType> active_metrics; |
315 const base::Time& end) { | |
316 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
317 UpdateActiveInterval(); | |
318 std::vector<MetricDetails> results; | |
319 std::string recent_start_key = CreateRecentKey(start, std::string(), | |
320 std::string()); | |
321 std::string recent_end_key = CreateRecentKey(end, std::string(), | |
322 std::string()); | |
323 std::string recent_end_of_time_key = CreateRecentKey(clock_->GetTime(), | |
324 std::string(), | |
325 std::string()); | |
326 std::set<std::string> active_metrics; | |
327 // Get all the guaranteed metrics. | 325 // Get all the guaranteed metrics. |
328 scoped_ptr<leveldb::Iterator> recent_it( | 326 scoped_ptr<leveldb::Iterator> recent_it( |
329 recent_db_->NewIterator(read_options_)); | 327 recent_db_->NewIterator(read_options_)); |
330 for (recent_it->Seek(recent_start_key); | 328 for (recent_it->Seek(recent_start_key); |
331 recent_it->Valid() && recent_it->key().ToString() <= recent_end_key; | 329 recent_it->Valid() && recent_it->key().ToString() <= recent_end_key; |
332 recent_it->Next()) { | 330 recent_it->Next()) { |
333 RecentKey split_key = SplitRecentKey(recent_it->key().ToString()); | 331 RecentKey split_key = SplitRecentKey(recent_it->key().ToString()); |
334 active_metrics.insert(split_key.metric); | 332 active_metrics.insert(split_key.type); |
335 } | 333 } |
336 // Get all the possible metrics (metrics that may have been updated after | 334 // Get all the possible metrics (metrics that may have been updated after |
337 // |end|). | 335 // |end|). |
338 std::set<std::string> possible_metrics; | 336 std::set<MetricType> possible_metrics; |
339 for (recent_it->Seek(recent_end_key); | 337 for (recent_it->Seek(recent_end_key); |
340 recent_it->Valid() && | 338 recent_it->Valid() && |
341 recent_it->key().ToString() <= recent_end_of_time_key; | 339 recent_it->key().ToString() <= recent_end_of_time_key; |
342 recent_it->Next()) { | 340 recent_it->Next()) { |
343 RecentKey split_key = SplitRecentKey(recent_it->key().ToString()); | 341 RecentKey split_key = SplitRecentKey(recent_it->key().ToString()); |
344 possible_metrics.insert(split_key.metric); | 342 possible_metrics.insert(split_key.type); |
345 } | 343 } |
346 std::set<std::string>::iterator possible_it; | 344 std::set<MetricType>::iterator possible_it; |
347 scoped_ptr<leveldb::Iterator> metric_it( | 345 scoped_ptr<leveldb::Iterator> metric_it( |
348 metric_db_->NewIterator(read_options_)); | 346 metric_db_->NewIterator(read_options_)); |
349 for (possible_it = possible_metrics.begin(); | 347 for (possible_it = possible_metrics.begin(); |
350 possible_it != possible_metrics.end(); | 348 possible_it != possible_metrics.end(); |
351 ++possible_it) { | 349 ++possible_it) { |
352 std::string metric_start_key = CreateMetricKey(start, *possible_it, | 350 std::string metric_start_key = CreateMetricKey(start, *possible_it, |
353 std::string()); | 351 std::string()); |
354 std::string metric_end_key = CreateMetricKey(end, *possible_it, | 352 std::string metric_end_key = CreateMetricKey(end, *possible_it, |
355 std::string()); | 353 std::string()); |
356 metric_it->Seek(metric_start_key); | 354 metric_it->Seek(metric_start_key); |
357 // Stats in the timerange from any activity makes the metric active. | 355 // Stats in the timerange from any activity makes the metric active. |
358 if (metric_it->Valid() && metric_it->key().ToString() <= metric_end_key) { | 356 if (metric_it->Valid() && metric_it->key().ToString() <= metric_end_key) { |
359 active_metrics.insert(*possible_it); | 357 active_metrics.insert(*possible_it); |
360 } | 358 } |
361 } | 359 } |
362 std::set<std::string>::iterator it; | 360 std::set<MetricType>::iterator it; |
363 for (it = active_metrics.begin(); it != active_metrics.end(); ++it) { | 361 for (it = active_metrics.begin(); it != active_metrics.end(); ++it) |
364 MetricDetailsMap::iterator metric_it; | 362 results.push_back(GetMetricDetails(*it)); |
365 metric_it = metric_details_map_.find(*it); | 363 |
366 if (metric_it == metric_details_map_.end()) | |
367 results.push_back(MetricDetails(*it, kMetricNotFoundError)); | |
368 else | |
369 results.push_back(metric_it->second); | |
370 } | |
371 return results; | 364 return results; |
372 } | 365 } |
373 | 366 |
374 std::vector<std::string> Database::GetActiveActivities( | 367 std::vector<std::string> Database::GetActiveActivities( |
375 const std::string& metric, const base::Time& start) { | 368 MetricType metric_type, const base::Time& start) { |
376 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 369 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
377 UpdateActiveInterval(); | |
378 std::vector<std::string> results; | 370 std::vector<std::string> results; |
379 std::string start_key = CreateRecentKey(start, std::string(), std::string()); | 371 std::string start_key = CreateRecentKey( |
| 372 start, static_cast<MetricType>(0), std::string()); |
380 scoped_ptr<leveldb::Iterator> it(recent_db_->NewIterator(read_options_)); | 373 scoped_ptr<leveldb::Iterator> it(recent_db_->NewIterator(read_options_)); |
381 for (it->Seek(start_key); it->Valid(); it->Next()) { | 374 for (it->Seek(start_key); it->Valid(); it->Next()) { |
382 RecentKey split_key = SplitRecentKey(it->key().ToString()); | 375 RecentKey split_key = SplitRecentKey(it->key().ToString()); |
383 if (split_key.metric == metric) | 376 if (split_key.type == metric_type) |
384 results.push_back(split_key.activity); | 377 results.push_back(split_key.activity); |
385 } | 378 } |
386 return results; | 379 return results; |
387 } | 380 } |
388 | 381 |
389 Database::MetricInfoVector Database::GetStatsForActivityAndMetric( | 382 Database::MetricInfoVector Database::GetStatsForActivityAndMetric( |
390 const std::string& activity, const std::string& metric, | 383 const std::string& activity, MetricType metric_type, |
391 const base::Time& start, const base::Time& end) { | 384 const base::Time& start, const base::Time& end) { |
392 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 385 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
393 UpdateActiveInterval(); | |
394 MetricInfoVector results; | 386 MetricInfoVector results; |
395 std::string start_key = CreateMetricKey(start, metric, activity); | 387 std::string start_key = CreateMetricKey(start, metric_type, activity); |
396 std::string end_key = CreateMetricKey(end, metric, activity); | 388 std::string end_key = CreateMetricKey(end, metric_type, activity); |
397 scoped_ptr<leveldb::Iterator> it(metric_db_->NewIterator(read_options_)); | 389 scoped_ptr<leveldb::Iterator> it(metric_db_->NewIterator(read_options_)); |
398 for (it->Seek(start_key); | 390 for (it->Seek(start_key); |
399 it->Valid() && it->key().ToString() <= end_key; | 391 it->Valid() && it->key().ToString() <= end_key; |
400 it->Next()) { | 392 it->Next()) { |
401 MetricKey split_key = SplitMetricKey(it->key().ToString()); | 393 MetricKey split_key = SplitMetricKey(it->key().ToString()); |
402 if (split_key.activity == activity) | 394 if (split_key.activity == activity) |
403 results.push_back(MetricInfo(split_key.time, it->value().ToString())); | 395 results.push_back(MetricInfo(split_key.time, it->value().ToString())); |
404 } | 396 } |
405 return results; | 397 return results; |
406 } | 398 } |
407 | 399 |
408 Database::MetricVectorMap Database::GetStatsForMetricByActivity( | 400 Database::MetricVectorMap Database::GetStatsForMetricByActivity( |
409 const std::string& metric, const base::Time& start, const base::Time& end) { | 401 MetricType metric_type, const base::Time& start, const base::Time& end) { |
410 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 402 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
411 UpdateActiveInterval(); | |
412 MetricVectorMap results; | 403 MetricVectorMap results; |
413 std::string start_key = CreateMetricKey(start, metric, std::string()); | 404 std::string start_key = CreateMetricKey(start, metric_type, std::string()); |
414 std::string end_key = CreateMetricKey(end, metric, std::string()); | 405 std::string end_key = CreateMetricKey(end, metric_type, std::string()); |
415 scoped_ptr<leveldb::Iterator> it(metric_db_->NewIterator(read_options_)); | 406 scoped_ptr<leveldb::Iterator> it(metric_db_->NewIterator(read_options_)); |
416 for (it->Seek(start_key); | 407 for (it->Seek(start_key); |
417 it->Valid() && it->key().ToString() <= end_key; | 408 it->Valid() && it->key().ToString() <= end_key; |
418 it->Next()) { | 409 it->Next()) { |
419 MetricKey split_key = SplitMetricKey(it->key().ToString()); | 410 MetricKey split_key = SplitMetricKey(it->key().ToString()); |
420 if (!results[split_key.activity].get()) { | 411 if (!results[split_key.activity].get()) { |
421 results[split_key.activity] = | 412 results[split_key.activity] = |
422 linked_ptr<MetricInfoVector>(new MetricInfoVector()); | 413 linked_ptr<MetricInfoVector>(new MetricInfoVector()); |
423 } | 414 } |
424 results[split_key.activity]->push_back( | 415 results[split_key.activity]->push_back( |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 active_interval_db_ = scoped_ptr<leveldb::DB>(new_db); | 465 active_interval_db_ = scoped_ptr<leveldb::DB>(new_db); |
475 leveldb::DB::Open(open_options, | 466 leveldb::DB::Open(open_options, |
476 WideToUTF8(path_.AppendASCII(kMetricDb).value()), &new_db); | 467 WideToUTF8(path_.AppendASCII(kMetricDb).value()), &new_db); |
477 metric_db_ = scoped_ptr<leveldb::DB>(new_db); | 468 metric_db_ = scoped_ptr<leveldb::DB>(new_db); |
478 leveldb::DB::Open(open_options, | 469 leveldb::DB::Open(open_options, |
479 WideToUTF8(path_.AppendASCII(kEventDb).value()), &new_db); | 470 WideToUTF8(path_.AppendASCII(kEventDb).value()), &new_db); |
480 event_db_ = scoped_ptr<leveldb::DB>(new_db); | 471 event_db_ = scoped_ptr<leveldb::DB>(new_db); |
481 #endif | 472 #endif |
482 } | 473 } |
483 | 474 |
484 void Database::InitMetricDetails() { | |
485 // TODO(mtytel): Delete this sample metric when a real one is added. | |
486 metric_details_map_[kSampleMetricName] = | |
487 MetricDetails(kSampleMetricName, kSampleMetricDescription); | |
488 } | |
489 | |
490 bool Database::Close() { | 475 bool Database::Close() { |
491 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 476 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
492 metric_db_.reset(); | 477 metric_db_.reset(); |
493 recent_db_.reset(); | 478 recent_db_.reset(); |
494 state_db_.reset(); | 479 state_db_.reset(); |
495 active_interval_db_.reset(); | 480 active_interval_db_.reset(); |
496 start_time_key_.clear(); | 481 start_time_key_.clear(); |
497 return true; | 482 return true; |
498 } | 483 } |
499 | 484 |
500 void Database::LoadRecents() { | 485 void Database::LoadRecents() { |
501 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 486 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
502 recent_map_.clear(); | 487 recent_map_.clear(); |
503 scoped_ptr<leveldb::Iterator> it(recent_db_->NewIterator(read_options_)); | 488 scoped_ptr<leveldb::Iterator> it(recent_db_->NewIterator(read_options_)); |
504 for (it->SeekToFirst(); it->Valid(); it->Next()) { | 489 for (it->SeekToFirst(); it->Valid(); it->Next()) { |
505 RecentKey split_key = SplitRecentKey(it->key().ToString()); | 490 RecentKey split_key = SplitRecentKey(it->key().ToString()); |
506 recent_map_[CreateRecentMapKey(split_key.metric, split_key.activity)] = | 491 recent_map_[CreateRecentMapKey(split_key.type, split_key.activity)] = |
507 it->key().ToString(); | 492 it->key().ToString(); |
508 } | 493 } |
509 } | 494 } |
510 | 495 |
511 // TODO(chebert): Only update the active interval under certian circumstances | 496 // TODO(chebert): Only update the active interval under certian circumstances |
512 // eg. every 10 times or when forced. | 497 // eg. every 10 times or when forced. |
513 void Database::UpdateActiveInterval() { | 498 void Database::UpdateActiveInterval() { |
514 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 499 CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
515 base::Time current_time = clock_->GetTime(); | 500 base::Time current_time = clock_->GetTime(); |
516 std::string end_time; | 501 std::string end_time; |
517 // If the last update was too long ago. | 502 // If the last update was too long ago. |
518 if (start_time_key_.empty() || | 503 if (start_time_key_.empty() || |
519 current_time - last_update_time_ > kActiveIntervalTimeout) { | 504 current_time - last_update_time_ > kActiveIntervalTimeout) { |
520 start_time_key_ = CreateActiveIntervalKey(current_time); | 505 start_time_key_ = CreateActiveIntervalKey(current_time); |
521 end_time = start_time_key_; | 506 end_time = start_time_key_; |
522 } else { | 507 } else { |
523 end_time = CreateActiveIntervalKey(clock_->GetTime()); | 508 end_time = CreateActiveIntervalKey(clock_->GetTime()); |
524 } | 509 } |
525 last_update_time_ = current_time; | 510 last_update_time_ = current_time; |
526 active_interval_db_->Put(write_options_, start_time_key_, end_time); | 511 active_interval_db_->Put(write_options_, start_time_key_, end_time); |
527 } | 512 } |
528 | 513 |
529 } // namespace performance_monitor | 514 } // namespace performance_monitor |
OLD | NEW |