blob: 2e3e009f559aa18ad5ad8b021abcd3f06e8c2fa2 [file] [log] [blame]
// 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';
base.require('guid');
base.require('range');
/**
* @fileoverview Provides the Counter class.
*/
base.exportTo('tracing.model', function() {
/**
* Stores all the samples for a given counter.
* @constructor
*/
function Counter(parent, id, category, name) {
this.guid_ = tracing.GUID.allocate();
this.parent = parent;
this.id = id;
this.category = category || '';
this.name = name;
this.seriesNames = [];
this.seriesColors = [];
this.timestamps = [];
this.samples = [];
this.bounds = new base.Range();
}
Counter.prototype = {
__proto__: Object.prototype,
/*
* @return {Number} A globally unique identifier for this counter.
*/
get guid() {
return this.guid_;
},
toJSON: function() {
var obj = new Object();
var keys = Object.keys(this);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (typeof this[key] == 'function')
continue;
if (key == 'parent') {
obj[key] = this[key].guid;
continue;
}
obj[key] = this[key];
}
return obj;
},
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 = [];
this.maxTotal = 0;
this.bounds.reset();
if (this.samples.length == 0)
return;
this.bounds.addValue(this.timestamps[0]);
this.bounds.addValue(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.compareTo, then name.
*/
Counter.compare = function(x, y) {
var tmp = x.parent.compareTo(y);
if (tmp != 0)
return tmp;
var tmp = x.name.localeCompare(y.name);
if (tmp == 0)
return x.tid - y.tid;
return tmp;
};
return {
Counter: Counter
};
});