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