// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. 'use strict'; /** * @fileoverview Provides the TimelineCounter class. */ base.exportTo('tracing', function() { var nextCounterGUID = 1; /** * Stores all the samples for a given counter. * @constructor */ function TimelineCounter(parent, id, category, name) { if (parent == null) { this.parent_id = null; } else if (parent.pid != undefined) { this.parent_id = parent.pid; } else if (parent.cpuNumber != undefined) { this.parent_id = parent.cpuNumber; } this.id = id; this.category = category || ''; this.name = name; this.seriesNames = []; this.seriesColors = []; this.timestamps = []; this.samples = []; this.guid_ = nextCounterGUID++; } TimelineCounter.prototype = { __proto__: Object.prototype, /* * @return {Number} A globally unique identifier for this counter. */ get guid() { return this.guid_; }, get numSeries() { return this.seriesNames.length; }, get numSamples() { return this.timestamps.length; }, getSampleValue: function(index, seriesIndex) { return this.samples[index * this.numSeries + seriesIndex]; }, /** * Obtains min, max, avg, values, start, and end for different series for * a given counter * getSampleStatistics([0,1]) * The statistics objects that this returns are an array of objects, one * object for each series for the counter in the form: * {min: minVal, max: maxVal, avg: avgVal, start: startVal, end: endVal} * * @param {Array.<Number>} Indices to summarize. * @return {Object} An array of statistics. Each element in the array * has data for one of the series in the selected counter. */ getSampleStatistics: function(sampleIndices) { sampleIndices.sort(); var sampleIndex = this.sampleIndex; var numSeries = this.numSeries; var numSamples = this.numSamples; var ret = []; for (var i = 0; i < numSeries; ++i) { var sum = 0; var min = Number.MAX_VALUE; var max = -Number.MAX_VALUE; for (var j = 0; j < sampleIndices.length; j++) { var x = sampleIndices[j]; sum += this.getSampleValue(x, i); min = Math.min(this.getSampleValue(x, i), min); max = Math.max(this.getSampleValue(x, i), max); } var avg = sum / sampleIndices.length; var start = this.getSampleValue(sampleIndices[0], i); var end = this.getSampleValue( sampleIndices[sampleIndices.length - 1], i); ret.push({min: min, max: max, avg: avg, start: start, end: end}); } return ret; }, /** * Shifts all the timestamps inside this counter forward by the amount * specified. */ shiftTimestampsForward: function(amount) { for (var sI = 0; sI < this.timestamps.length; sI++) this.timestamps[sI] = (this.timestamps[sI] + amount); }, /** * Updates the bounds for this counter based on the samples it contains. */ updateBounds: function() { if (this.seriesNames.length != this.seriesColors.length) throw new Error('seriesNames.length must match seriesColors.length'); if (this.numSeries * this.numSamples != this.samples.length) throw new Error('samples.length must be a multiple of numSamples.'); this.totals = []; if (this.samples.length == 0) { this.minTimestamp = undefined; this.maxTimestamp = undefined; this.maxTotal = 0; return; } this.minTimestamp = this.timestamps[0]; this.maxTimestamp = this.timestamps[this.timestamps.length - 1]; var numSeries = this.numSeries; var maxTotal = -Infinity; for (var i = 0; i < this.timestamps.length; i++) { var total = 0; for (var j = 0; j < numSeries; j++) { total += this.samples[i * numSeries + j]; this.totals.push(total); } if (total > maxTotal) maxTotal = total; } this.maxTotal = maxTotal; } }; /** * Comparison between counters that orders by parent_id, then name. */ TimelineCounter.compare = function(x, y) { if (x.parent_id != y.parent_id) { return x.parent_id - y.parent_id; } var tmp = x.name.localeCompare(y.name); if (tmp == 0) return x.tid - y.tid; return tmp; }; return { TimelineCounter: TimelineCounter }; });