21574941d86aced7685555fab45bdf951bc5c9f2
[platform/framework/web/crosswalk.git] / src / third_party / trace-viewer / trace_viewer / tracing / trace_model / counter.js
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 tvcm.require('tvcm.guid');
8 tvcm.require('tvcm.range');
9 tvcm.require('tracing.trace_model.counter_series');
10
11 /**
12  * @fileoverview Provides the Counter class.
13  */
14 tvcm.exportTo('tracing.trace_model', function() {
15
16   /**
17    * Stores all the samples for a given counter.
18    * @constructor
19    */
20   function Counter(parent, id, category, name) {
21     this.guid_ = tvcm.GUID.allocate();
22
23     this.parent = parent;
24     this.id = id;
25     this.category = category || '';
26     this.name = name;
27
28     this.series_ = [];
29     this.totals = [];
30     this.bounds = new tvcm.Range();
31   }
32
33   Counter.prototype = {
34     __proto__: Object.prototype,
35
36     /*
37      * @return {Number} A globally unique identifier for this counter.
38      */
39     get guid() {
40       return this.guid_;
41     },
42
43     toJSON: function() {
44       var obj = new Object();
45       var keys = Object.keys(this);
46       for (var i = 0; i < keys.length; i++) {
47         var key = keys[i];
48         if (typeof this[key] == 'function')
49           continue;
50         if (key == 'parent') {
51           obj[key] = this[key].guid;
52           continue;
53         }
54         obj[key] = this[key];
55       }
56       return obj;
57     },
58
59     set timestamps(arg) {
60       throw new Error('Bad counter API. No cookie.');
61     },
62
63     set seriesNames(arg) {
64       throw new Error('Bad counter API. No cookie.');
65     },
66
67     set seriesColors(arg) {
68       throw new Error('Bad counter API. No cookie.');
69     },
70
71     set samples(arg) {
72       throw new Error('Bad counter API. No cookie.');
73     },
74
75     addSeries: function(series) {
76       series.counter = this;
77       series.seriesIndex = this.series_.length;
78       this.series_.push(series);
79       return series;
80     },
81
82     getSeries: function(idx) {
83       return this.series_[idx];
84     },
85
86     get series() {
87       return this.series_;
88     },
89
90     get numSeries() {
91       return this.series_.length;
92     },
93
94     get numSamples() {
95       if (this.series_.length === 0)
96         return 0;
97       return this.series_[0].length;
98     },
99
100     get timestamps() {
101       if (this.series_.length === 0)
102         return [];
103       return this.series_[0].timestamps;
104     },
105
106     /**
107      * Obtains min, max, avg, values, start, and end for different series for
108      * a given counter
109      *     getSampleStatistics([0,1])
110      * The statistics objects that this returns are an array of objects, one
111      * object for each series for the counter in the form:
112      * {min: minVal, max: maxVal, avg: avgVal, start: startVal, end: endVal}
113      *
114      * @param {Array.<Number>} Indices to summarize.
115      * @return {Object} An array of statistics. Each element in the array
116      * has data for one of the series in the selected counter.
117      */
118     getSampleStatistics: function(sampleIndices) {
119       sampleIndices.sort();
120
121       var ret = [];
122       this.series_.forEach(function(series) {
123         ret.push(series.getStatistics(sampleIndices));
124       });
125       return ret;
126     },
127
128     /**
129      * Shifts all the timestamps inside this counter forward by the amount
130      * specified.
131      */
132     shiftTimestampsForward: function(amount) {
133       for (var i = 0; i < this.series_.length; ++i)
134         this.series_[i].shiftTimestampsForward(amount);
135     },
136
137     /**
138      * Updates the bounds for this counter based on the samples it contains.
139      */
140     updateBounds: function() {
141       this.totals = [];
142       this.maxTotal = 0;
143       this.bounds.reset();
144
145       if (this.series_.length === 0)
146         return;
147
148       var firstSeries = this.series_[0];
149       var lastSeries = this.series_[this.series_.length - 1];
150
151       this.bounds.addValue(firstSeries.getTimestamp(0));
152       this.bounds.addValue(lastSeries.getTimestamp(lastSeries.length - 1));
153
154       var numSeries = this.numSeries;
155       this.maxTotal = -Infinity;
156
157       // Sum the samples at each timestamp.
158       // Note, this assumes that all series have all timestamps.
159       for (var i = 0; i < firstSeries.length; ++i) {
160         var total = 0;
161         this.series_.forEach(function(series) {
162           total += series.getSample(i).value;
163           this.totals.push(total);
164         }.bind(this));
165
166         this.maxTotal = Math.max(total, this.maxTotal);
167       }
168     },
169
170     iterateAllEvents: function(callback) {
171       for (var i = 0; i < this.series_.length; i++)
172         this.series_[i].iterateAllEvents(callback);
173     }
174   };
175
176   /**
177    * Comparison between counters that orders by parent.compareTo, then name.
178    */
179   Counter.compare = function(x, y) {
180     var tmp = x.parent.compareTo(y);
181     if (tmp != 0)
182       return tmp;
183     var tmp = x.name.localeCompare(y.name);
184     if (tmp == 0)
185       return x.tid - y.tid;
186     return tmp;
187   };
188
189   return {
190     Counter: Counter
191   };
192 });