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