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/key_builder.h" 6 7 #include "base/format_macros.h" 8 #include "base/logging.h" 9 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_split.h" 11 #include "base/strings/stringprintf.h" 12 13 namespace performance_monitor { 14 15 namespace { 16 17 const char kDelimiter = '!'; 18 19 // These values are used as the portion of the generated key which represents 20 // the event/metric type when inserting values in the database. We use an ASCII 21 // character as a mapping, rather than the enum of the metric or event itself, 22 // so that we can edit the MetricType and EventType enums as desired, without 23 // worrying about the integrity of the database. 24 // 25 // Once a character mapping has been set for a metric or event, do not change 26 // its value! New character mappings should be greater than 34 (ASCII characters 27 // below 32 have meaning, 33 is '!' - the database delimiter, and 34 is reserved 28 // for the 'Undefined' character mapping). Do not repeat values within the 29 // metric/event sets (repeated values between sets are okay). 30 // 31 // Deprecated keys: A key which is deprecated should be clearly marked as such, 32 // and its use discontinued. Do not remove the key from the listing! (Otherwise, 33 // a new metric may take its key and think the old data belongs to it.) 34 35 enum MetricKeyChar { 36 METRIC_UNDEFINED_KEY_CHAR = 34, 37 METRIC_CPU_USAGE_KEY_CHAR = 35, 38 METRIC_PRIVATE_MEMORY_USAGE_KEY_CHAR = 36, 39 METRIC_SHARED_MEMORY_USAGE_KEY_CHAR = 37, 40 METRIC_STARTUP_TIME_KEY_CHAR = 38, 41 METRIC_TEST_STARTUP_TIME_KEY_CHAR = 39, 42 METRIC_SESSION_RESTORE_TIME_KEY_CHAR = 40, 43 METRIC_PAGE_LOAD_TIME_KEY_CHAR = 41, 44 METRIC_NETWORK_BYTES_READ_KEY_CHAR = 42, 45 METRIC_NUMBER_OF_METRICS_KEY_CHAR = 255, 46 }; 47 48 enum EventKeyChar { 49 EVENT_UNDEFINED_KEY_CHAR = 34, 50 EVENT_EXTENSION_INSTALL_KEY_CHAR = 35, 51 EVENT_EXTENSION_UNINSTALL_KEY_CHAR = 36, 52 EVENT_EXTENSION_UPDATE_KEY_CHAR = 37, 53 EVENT_EXTENSION_ENABLE_KEY_CHAR = 38, 54 EVENT_EXTENSION_DISABLE_KEY_CHAR = 39, 55 EVENT_CHROME_UPDATE_KEY_CHAR = 40, 56 EVENT_RENDERER_HANG_KEY_CHAR = 41, 57 EVENT_RENDERER_CRASH_KEY_CHAR = 42, 58 EVENT_RENDERER_KILLED_KEY_CHAR = 43, 59 EVENT_UNCLEAN_EXIT_KEY_CHAR = 44, 60 EVENT_NUMBER_OF_EVENTS_KEY_CHAR = 255, 61 }; 62 63 // The position of different elements in the key for the event db. 64 enum EventKeyPosition { 65 EVENT_TIME, // The time the event was generated. 66 EVENT_TYPE // The type of event. 67 }; 68 69 // The position of different elements in the key for the recent db. 70 enum RecentKeyPosition { 71 RECENT_TIME, // The time the stat was gathered. 72 RECENT_TYPE, // The unique identifier for the type of metric gathered. 73 RECENT_ACTIVITY // The unique identifier for the activity. 74 }; 75 76 // The position of different elements in the key for the max value db. 77 enum MaxValueKeyPosition { 78 MAX_VALUE_TYPE, // The unique identifier for the type of metric gathered. 79 MAX_VALUE_ACTIVITY // The unique identifier for the activity. 80 }; 81 82 // The position of different elements in the key for a metric db. 83 enum MetricKeyPosition { 84 METRIC_TYPE, // The unique identifier for the metric. 85 METRIC_TIME, // The time the stat was gathered. 86 METRIC_ACTIVITY // The unique identifier for the activity. 87 }; 88 89 } // namespace 90 91 RecentKey::RecentKey(const std::string& recent_time, 92 MetricType recent_type, 93 const std::string& recent_activity) 94 : time(recent_time), type(recent_type), activity(recent_activity) { 95 } 96 97 RecentKey::~RecentKey() { 98 } 99 100 MetricKey::MetricKey(const std::string& metric_time, 101 MetricType metric_type, 102 const std::string& metric_activity) 103 : time(metric_time), type(metric_type), activity(metric_activity) { 104 } 105 106 MetricKey::~MetricKey() { 107 } 108 109 KeyBuilder::KeyBuilder() { 110 PopulateKeyMaps(); 111 } 112 113 KeyBuilder::~KeyBuilder() { 114 } 115 116 void KeyBuilder::PopulateKeyMaps() { 117 // Hard-code the generation of the map between event types and event key 118 // character mappings. 119 event_type_to_event_key_char_[EVENT_UNDEFINED] = EVENT_UNDEFINED_KEY_CHAR; 120 event_type_to_event_key_char_[EVENT_EXTENSION_INSTALL] = 121 EVENT_EXTENSION_INSTALL_KEY_CHAR; 122 event_type_to_event_key_char_[EVENT_EXTENSION_UNINSTALL] = 123 EVENT_EXTENSION_UNINSTALL_KEY_CHAR; 124 event_type_to_event_key_char_[EVENT_EXTENSION_UPDATE] = 125 EVENT_EXTENSION_UPDATE_KEY_CHAR; 126 event_type_to_event_key_char_[EVENT_EXTENSION_ENABLE] = 127 EVENT_EXTENSION_ENABLE_KEY_CHAR; 128 event_type_to_event_key_char_[EVENT_EXTENSION_DISABLE] = 129 EVENT_EXTENSION_DISABLE_KEY_CHAR; 130 event_type_to_event_key_char_[EVENT_RENDERER_HANG] = 131 EVENT_RENDERER_HANG_KEY_CHAR; 132 event_type_to_event_key_char_[EVENT_RENDERER_CRASH] = 133 EVENT_RENDERER_CRASH_KEY_CHAR; 134 event_type_to_event_key_char_[EVENT_RENDERER_KILLED] = 135 EVENT_RENDERER_KILLED_KEY_CHAR; 136 event_type_to_event_key_char_[EVENT_UNCLEAN_EXIT] = 137 EVENT_UNCLEAN_EXIT_KEY_CHAR; 138 event_type_to_event_key_char_[EVENT_NUMBER_OF_EVENTS] = 139 EVENT_NUMBER_OF_EVENTS_KEY_CHAR; 140 DCHECK(event_type_to_event_key_char_.size() == EVENT_NUMBER_OF_EVENTS); 141 142 // Generate the reverse map for easy look-up between event character mappings 143 // and event types. 144 for (int i = static_cast<int>(EVENT_UNDEFINED); 145 i <= static_cast<int>(EVENT_NUMBER_OF_EVENTS); ++i) { 146 event_key_char_to_event_type_[event_type_to_event_key_char_[ 147 static_cast<EventType>(i)]] = static_cast<EventType>(i); 148 } 149 150 // Repeat the process for metrics. 151 metric_type_to_metric_key_char_[METRIC_UNDEFINED] = METRIC_UNDEFINED_KEY_CHAR; 152 metric_type_to_metric_key_char_[METRIC_CPU_USAGE] = METRIC_CPU_USAGE_KEY_CHAR; 153 metric_type_to_metric_key_char_[METRIC_PRIVATE_MEMORY_USAGE] = 154 METRIC_PRIVATE_MEMORY_USAGE_KEY_CHAR; 155 metric_type_to_metric_key_char_[METRIC_SHARED_MEMORY_USAGE] = 156 METRIC_SHARED_MEMORY_USAGE_KEY_CHAR; 157 metric_type_to_metric_key_char_[METRIC_STARTUP_TIME] = 158 METRIC_STARTUP_TIME_KEY_CHAR; 159 metric_type_to_metric_key_char_[METRIC_TEST_STARTUP_TIME] = 160 METRIC_TEST_STARTUP_TIME_KEY_CHAR; 161 metric_type_to_metric_key_char_[METRIC_PAGE_LOAD_TIME] = 162 METRIC_PAGE_LOAD_TIME_KEY_CHAR; 163 metric_type_to_metric_key_char_[METRIC_NETWORK_BYTES_READ] = 164 METRIC_NETWORK_BYTES_READ_KEY_CHAR; 165 metric_type_to_metric_key_char_[METRIC_NUMBER_OF_METRICS] = 166 METRIC_NUMBER_OF_METRICS_KEY_CHAR; 167 DCHECK(metric_type_to_metric_key_char_.size() == METRIC_NUMBER_OF_METRICS); 168 169 for (int i = static_cast<int>(METRIC_UNDEFINED); 170 i <= static_cast<int>(METRIC_NUMBER_OF_METRICS); ++i) { 171 metric_key_char_to_metric_type_[metric_type_to_metric_key_char_[ 172 static_cast<MetricType>(i)]] = static_cast<MetricType>(i); 173 } 174 } 175 176 std::string KeyBuilder::CreateActiveIntervalKey(const base::Time& time) { 177 return base::StringPrintf("%016" PRId64, time.ToInternalValue()); 178 } 179 180 std::string KeyBuilder::CreateMetricKey(const base::Time& time, 181 const MetricType type, 182 const std::string& activity) { 183 return base::StringPrintf("%c%c%016" PRId64 "%c%s", 184 metric_type_to_metric_key_char_[type], 185 kDelimiter, time.ToInternalValue(), 186 kDelimiter, activity.c_str()); 187 } 188 189 std::string KeyBuilder::CreateEventKey(const base::Time& time, 190 const EventType type) { 191 return base::StringPrintf("%016" PRId64 "%c%c", 192 time.ToInternalValue(), kDelimiter, 193 event_type_to_event_key_char_[type]); 194 } 195 196 std::string KeyBuilder::CreateRecentKey(const base::Time& time, 197 const MetricType type, 198 const std::string& activity) { 199 return base::StringPrintf("%016" PRId64 "%c%c%c%s", 200 time.ToInternalValue(), 201 kDelimiter, metric_type_to_metric_key_char_[type], 202 kDelimiter, activity.c_str()); 203 } 204 205 std::string KeyBuilder::CreateRecentMapKey(const MetricType type, 206 const std::string& activity) { 207 return base::StringPrintf("%s%c%c", 208 activity.c_str(), 209 kDelimiter, metric_type_to_metric_key_char_[type]); 210 } 211 212 std::string KeyBuilder::CreateMaxValueKey(const MetricType type, 213 const std::string& activity) { 214 return base::StringPrintf("%c%c%s", 215 metric_type_to_metric_key_char_[type], 216 kDelimiter, activity.c_str()); 217 } 218 219 EventType KeyBuilder::EventKeyToEventType(const std::string& event_key) { 220 std::vector<std::string> split; 221 base::SplitString(event_key, kDelimiter, &split); 222 DCHECK(split[EVENT_TYPE].size() == 1); 223 return event_key_char_to_event_type_[ 224 static_cast<int>(split[EVENT_TYPE].at(0))]; 225 } 226 227 RecentKey KeyBuilder::SplitRecentKey(const std::string& key) { 228 std::vector<std::string> split; 229 base::SplitString(key, kDelimiter, &split); 230 DCHECK(split[RECENT_TYPE].size() == 1); 231 return RecentKey(split[RECENT_TIME], 232 metric_key_char_to_metric_type_[ 233 static_cast<int>(split[RECENT_TYPE].at(0))], 234 split[RECENT_ACTIVITY]); 235 } 236 237 MetricKey KeyBuilder::SplitMetricKey(const std::string& key) { 238 std::vector<std::string> split; 239 base::SplitString(key, kDelimiter, &split); 240 DCHECK(split[METRIC_TYPE].size() == 1); 241 return MetricKey(split[METRIC_TIME], 242 metric_key_char_to_metric_type_[ 243 static_cast<int>(split[METRIC_TYPE].at(0))], 244 split[METRIC_ACTIVITY]); 245 } 246 247 } // namespace performance_monitor 248