Home | History | Annotate | Download | only in performance_monitor
      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