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