1<!DOCTYPE html> 2<!-- 3Copyright (c) 2013 The Chromium Authors. All rights reserved. 4Use of this source code is governed by a BSD-style license that can be 5found in the LICENSE file. 6--> 7 8<link rel="import" href="/tracing/model/counter_series.html"> 9<link rel="import" href="/tracing/model/event_container.html"> 10<link rel="import" href="/tracing/base/guid.html"> 11<link rel="import" href="/tracing/base/range.html"> 12 13<script> 14'use strict'; 15 16tr.exportTo('tr.model', function() { 17 18 /** 19 * A container holding all series of a given type of measurement. 20 * 21 * As an example, if we're measuring the throughput of data sent over several 22 * USB connections, the throughput of each cable might be added as a separate 23 * series to a single counter. 24 * 25 * @constructor 26 * @extends {EventContainer} 27 */ 28 function Counter(parent, id, category, name) { 29 tr.model.EventContainer.call(this); 30 31 this.parent_ = parent; 32 this.id_ = id; 33 this.category_ = category || ''; 34 this.name_ = name; 35 36 this.series_ = []; 37 this.totals = []; 38 } 39 40 Counter.prototype = { 41 __proto__: tr.model.EventContainer.prototype, 42 43 get parent() { 44 return this.parent_; 45 }, 46 47 get id() { 48 return this.id_; 49 }, 50 51 get category() { 52 return this.category_; 53 }, 54 55 get name() { 56 return this.name_; 57 }, 58 59 iterateAllEventsInThisContainer: function(eventTypePredicate, 60 callback, opt_this) { 61 }, 62 63 iterateAllChildEventContainers: function(callback, opt_this) { 64 for (var i = 0; i < this.series_.length; i++) 65 callback.call(opt_this, this.series_[i]); 66 }, 67 68 set timestamps(arg) { 69 throw new Error('Bad counter API. No cookie.'); 70 }, 71 72 set seriesNames(arg) { 73 throw new Error('Bad counter API. No cookie.'); 74 }, 75 76 set seriesColors(arg) { 77 throw new Error('Bad counter API. No cookie.'); 78 }, 79 80 set samples(arg) { 81 throw new Error('Bad counter API. No cookie.'); 82 }, 83 84 addSeries: function(series) { 85 series.counter = this; 86 series.seriesIndex = this.series_.length; 87 this.series_.push(series); 88 return series; 89 }, 90 91 getSeries: function(idx) { 92 return this.series_[idx]; 93 }, 94 95 get series() { 96 return this.series_; 97 }, 98 99 get numSeries() { 100 return this.series_.length; 101 }, 102 103 get numSamples() { 104 if (this.series_.length === 0) 105 return 0; 106 return this.series_[0].length; 107 }, 108 109 get timestamps() { 110 if (this.series_.length === 0) 111 return []; 112 return this.series_[0].timestamps; 113 }, 114 115 /** 116 * Obtains min, max, avg, values, start, and end for different series for 117 * a given counter 118 * getSampleStatistics([0,1]) 119 * The statistics objects that this returns are an array of objects, one 120 * object for each series for the counter in the form: 121 * {min: minVal, max: maxVal, avg: avgVal, start: startVal, end: endVal} 122 * 123 * @param {Array.<Number>} Indices to summarize. 124 * @return {Object} An array of statistics. Each element in the array 125 * has data for one of the series in the selected counter. 126 */ 127 getSampleStatistics: function(sampleIndices) { 128 sampleIndices.sort(); 129 130 var ret = []; 131 this.series_.forEach(function(series) { 132 ret.push(series.getStatistics(sampleIndices)); 133 }); 134 return ret; 135 }, 136 137 /** 138 * Shifts all the timestamps inside this counter forward by the amount 139 * specified. 140 */ 141 shiftTimestampsForward: function(amount) { 142 for (var i = 0; i < this.series_.length; ++i) 143 this.series_[i].shiftTimestampsForward(amount); 144 }, 145 146 /** 147 * Updates the bounds for this counter based on the samples it contains. 148 */ 149 updateBounds: function() { 150 this.totals = []; 151 this.maxTotal = 0; 152 this.bounds.reset(); 153 154 if (this.series_.length === 0) 155 return; 156 157 var firstSeries = this.series_[0]; 158 var lastSeries = this.series_[this.series_.length - 1]; 159 160 this.bounds.addValue(firstSeries.getTimestamp(0)); 161 this.bounds.addValue(lastSeries.getTimestamp(lastSeries.length - 1)); 162 163 var numSeries = this.numSeries; 164 this.maxTotal = -Infinity; 165 166 // Sum the samples at each timestamp. 167 // Note, this assumes that all series have all timestamps. 168 for (var i = 0; i < firstSeries.length; ++i) { 169 var total = 0; 170 this.series_.forEach(function(series) { 171 total += series.getSample(i).value; 172 this.totals.push(total); 173 }.bind(this)); 174 175 this.maxTotal = Math.max(total, this.maxTotal); 176 } 177 } 178 }; 179 180 /** 181 * Comparison between counters that orders by parent.compareTo, then name. 182 */ 183 Counter.compare = function(x, y) { 184 var tmp = x.parent.compareTo(y); 185 if (tmp != 0) 186 return tmp; 187 var tmp = x.name.localeCompare(y.name); 188 if (tmp == 0) 189 return x.tid - y.tid; 190 return tmp; 191 }; 192 193 return { 194 Counter: Counter 195 }; 196}); 197</script> 198