Home | History | Annotate | Download | only in src
      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 'use strict';
      6 
      7 /**
      8  * @fileoverview Provides the TimelineCounter class.
      9  */
     10 base.exportTo('tracing', function() {
     11 
     12   var nextCounterGUID = 1;
     13 
     14   /**
     15    * Stores all the samples for a given counter.
     16    * @constructor
     17    */
     18   function TimelineCounter(parent, id, category, name) {
     19     if (parent == null) {
     20       this.parent_id = null;
     21     } else if (parent.pid != undefined) {
     22       this.parent_id = parent.pid;
     23     } else if (parent.cpuNumber != undefined) {
     24       this.parent_id = parent.cpuNumber;
     25     }
     26     this.id = id;
     27     this.category = category || '';
     28     this.name = name;
     29     this.seriesNames = [];
     30     this.seriesColors = [];
     31     this.timestamps = [];
     32     this.samples = [];
     33     this.guid_ = nextCounterGUID++;
     34   }
     35 
     36   TimelineCounter.prototype = {
     37     __proto__: Object.prototype,
     38     /*
     39      * @return {Number} A globally unique identifier for this counter.
     40      */
     41     get guid() {
     42       return this.guid_;
     43     },
     44 
     45     get numSeries() {
     46       return this.seriesNames.length;
     47     },
     48 
     49     get numSamples() {
     50       return this.timestamps.length;
     51     },
     52 
     53     getSampleValue: function(index, seriesIndex) {
     54       return this.samples[index * this.numSeries + seriesIndex];
     55     },
     56 
     57     /**
     58      * Obtains min, max, avg, values, start, and end for different series for
     59      * a given counter
     60      *     getSampleStatistics([0,1])
     61      * The statistics objects that this returns are an array of objects, one
     62      * object for each series for the counter in the form:
     63      * {min: minVal, max: maxVal, avg: avgVal, start: startVal, end: endVal}
     64      *
     65      * @param {Array.<Number>} Indices to summarize.
     66      * @return {Object} An array of statistics. Each element in the array
     67      * has data for one of the series in the selected counter.
     68      */
     69     getSampleStatistics: function(sampleIndices) {
     70       sampleIndices.sort();
     71       var sampleIndex = this.sampleIndex;
     72       var numSeries = this.numSeries;
     73       var numSamples = this.numSamples;
     74 
     75       var ret = [];
     76 
     77       for (var i = 0; i < numSeries; ++i) {
     78         var sum = 0;
     79         var min = Number.MAX_VALUE;
     80         var max = -Number.MAX_VALUE;
     81         for (var j = 0; j < sampleIndices.length; j++) {
     82           var x = sampleIndices[j];
     83           sum += this.getSampleValue(x, i);
     84           min = Math.min(this.getSampleValue(x, i), min);
     85           max = Math.max(this.getSampleValue(x, i), max);
     86         }
     87         var avg = sum / sampleIndices.length;
     88         var start = this.getSampleValue(sampleIndices[0], i);
     89         var end = this.getSampleValue(
     90             sampleIndices[sampleIndices.length - 1], i);
     91 
     92         ret.push({min: min,
     93           max: max,
     94           avg: avg,
     95           start: start,
     96           end: end});
     97       }
     98       return ret;
     99     },
    100 
    101     /**
    102      * Shifts all the timestamps inside this counter forward by the amount
    103      * specified.
    104      */
    105     shiftTimestampsForward: function(amount) {
    106       for (var sI = 0; sI < this.timestamps.length; sI++)
    107         this.timestamps[sI] = (this.timestamps[sI] + amount);
    108     },
    109 
    110     /**
    111      * Updates the bounds for this counter based on the samples it contains.
    112      */
    113     updateBounds: function() {
    114       if (this.seriesNames.length != this.seriesColors.length)
    115         throw new Error('seriesNames.length must match seriesColors.length');
    116       if (this.numSeries * this.numSamples != this.samples.length)
    117         throw new Error('samples.length must be a multiple of numSamples.');
    118 
    119       this.totals = [];
    120       if (this.samples.length == 0) {
    121         this.minTimestamp = undefined;
    122         this.maxTimestamp = undefined;
    123         this.maxTotal = 0;
    124         return;
    125       }
    126       this.minTimestamp = this.timestamps[0];
    127       this.maxTimestamp = this.timestamps[this.timestamps.length - 1];
    128 
    129       var numSeries = this.numSeries;
    130       var maxTotal = -Infinity;
    131       for (var i = 0; i < this.timestamps.length; i++) {
    132         var total = 0;
    133         for (var j = 0; j < numSeries; j++) {
    134           total += this.samples[i * numSeries + j];
    135           this.totals.push(total);
    136         }
    137         if (total > maxTotal)
    138           maxTotal = total;
    139       }
    140       this.maxTotal = maxTotal;
    141     }
    142 
    143   };
    144 
    145   /**
    146    * Comparison between counters that orders by parent_id, then name.
    147    */
    148   TimelineCounter.compare = function(x, y) {
    149     if (x.parent_id != y.parent_id) {
    150       return x.parent_id - y.parent_id;
    151     }
    152     var tmp = x.name.localeCompare(y.name);
    153     if (tmp == 0)
    154       return x.tid - y.tid;
    155     return tmp;
    156   };
    157 
    158   return {
    159     TimelineCounter: TimelineCounter
    160   };
    161 });
    162