blob: 833ba5953460913127a6e34078914064bf48ed9c [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('base.guid');
base.require('base.range');
base.require('tracing.trace_model.counter_series');
/**
* @fileoverview Provides the Counter class.
*/
base.exportTo('tracing.trace_model', function() {
/**
* Stores all the samples for a given counter.
* @constructor
*/
function Counter(parent, id, category, name) {
this.guid_ = base.GUID.allocate();
this.parent = parent;
this.id = id;
this.category = category || '';
this.name = name;
this.series_ = [];
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;
},
set timestamps(arg) {
throw new Error('Bad counter API. No cookie.');
},
set seriesNames(arg) {
throw new Error('Bad counter API. No cookie.');
},
set seriesColors(arg) {
throw new Error('Bad counter API. No cookie.');
},
set samples(arg) {
throw new Error('Bad counter API. No cookie.');
},
addSeries: function(series) {
this.series_.push(series);
},
getSeries: function(idx) {
return this.series_[idx];
},
get series() {
return this.series_;
},
get numSeries() {
return this.series_.length;
},
get numSamples() {
if (this.series_.length === 0)
return 0;
return this.series_[0].length;
},
get timestamps() {
if (this.series_.length === 0)
return [];
return this.series_[0].timestamps;
},
/**
* 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 ret = [];
this.series_.forEach(function(series) {
ret.push(series.getStatistics(sampleIndices));
});
return ret;
},
/**
* Shifts all the timestamps inside this counter forward by the amount
* specified.
*/
shiftTimestampsForward: function(amount) {
for (var i = 0; i < this.series_.length; ++i)
this.series_[i].shiftTimestampsForward(amount);
},
/**
* Updates the bounds for this counter based on the samples it contains.
*/
updateBounds: function() {
this.totals = [];
this.maxTotal = 0;
this.bounds.reset();
if (this.series_.length === 0)
return;
var firstSeries = this.series_[0];
var lastSeries = this.series_[this.series_.length - 1];
this.bounds.addValue(firstSeries.getTimestamp(0));
this.bounds.addValue(lastSeries.getTimestamp(lastSeries.length - 1));
var numSeries = this.numSeries;
this.maxTotal = -Infinity;
// Sum the samples at each timestamp.
// Note, this assumes that all series have all timestamps.
for (var i = 0; i < firstSeries.length; ++i) {
var total = 0;
this.series_.forEach(function(series) {
total += series.getSample(i).value;
this.totals.push(total);
}.bind(this));
this.maxTotal = Math.max(total, this.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
};
});