• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2011 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/**
6 * @fileoverview
7 * The webapp reads the plugin's connection statistics frequently (once per
8 * second). It logs statistics to the server less frequently, to keep
9 * bandwidth and storage costs down. This class bridges that gap, by
10 * accumulating high-frequency numeric data, and providing statistics
11 * summarising that data.
12 */
13
14'use strict';
15
16/** @suppress {duplicate} */
17var remoting = remoting || {};
18
19/**
20 * @constructor
21 */
22remoting.StatsAccumulator = function() {
23  /**
24   * A map from names to lists of values.
25   * @private
26   * @type Object.<string, Array.<number>>
27   */
28  this.valueLists_ = {};
29
30  /**
31   * The first time, after this object was most recently initialized or emptied,
32   * at which a value was added to this object.
33   * @private
34   * @type {?number}
35   */
36  this.timeOfFirstValue_ = null;
37};
38
39/**
40 * Adds values to this object.
41 *
42 * @param {Object.<string, number>} newValues
43 */
44remoting.StatsAccumulator.prototype.add = function(newValues) {
45  for (var key in newValues) {
46    this.getValueList(key).push(newValues[key]);
47  }
48  if (!this.timeOfFirstValue_) {
49    this.timeOfFirstValue_ = new Date().getTime();
50  }
51};
52
53/**
54 * Empties this object.
55 */
56remoting.StatsAccumulator.prototype.empty = function() {
57  this.valueLists_ = {};
58  this.timeOfFirstValue_ = null;
59};
60
61/**
62 * Gets the number of milliseconds since the first value was added to this
63 * object, after this object was most recently initialized or emptied.
64 *
65 * @return {number} milliseconds since the first value
66 */
67remoting.StatsAccumulator.prototype.getTimeSinceFirstValue = function() {
68  if (!this.timeOfFirstValue_) {
69    return 0;
70  }
71  return new Date().getTime() - this.timeOfFirstValue_;
72};
73
74/**
75 * Calculates the mean of the values for a given key.
76 *
77 * @param {string} key
78 * @return {number} the mean of the values for that key
79 */
80remoting.StatsAccumulator.prototype.calcMean = function(key) {
81  /**
82   * @param {Array.<number>} values
83   * @return {number}
84   */
85  var calcMean = function(values) {
86    if (values.length == 0) {
87      return 0.0;
88    }
89    var sum = 0;
90    for (var i = 0; i < values.length; i++) {
91      sum += values[i];
92    }
93    return sum / values.length;
94  };
95  return this.map(key, calcMean);
96};
97
98/**
99 * Applies a given map to the list of values for a given key.
100 *
101 * @param {string} key
102 * @param {function(Array.<number>): number} map
103 * @return {number} the result of applying that map to the list of values for
104 *     that key
105 */
106remoting.StatsAccumulator.prototype.map = function(key, map) {
107  return map(this.getValueList(key));
108};
109
110/**
111 * Gets the list of values for a given key.
112 * If this object contains no values for that key, then this routine creates
113 * an empty list, stores it in this object, and returns it.
114 *
115 * @private
116 * @param {string} key
117 * @return {Array.<number>} the list of values for that key
118 */
119remoting.StatsAccumulator.prototype.getValueList = function(key) {
120  var valueList = this.valueLists_[key];
121  if (!valueList) {
122    valueList = [];
123    this.valueLists_[key] = valueList;
124  }
125  return valueList;
126};
127