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