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