Fri, 16 Jan 2015 18:13:44 +0100
Integrate suggestion from review to improve consistency with existing code.
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
michael@0 | 3 | * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | const Cc = Components.classes; |
michael@0 | 6 | const Ci = Components.interfaces; |
michael@0 | 7 | const Cu = Components.utils; |
michael@0 | 8 | |
michael@0 | 9 | this.EXPORTED_SYMBOLS = ["TelemetryStopwatch"]; |
michael@0 | 10 | |
michael@0 | 11 | let Telemetry = Cc["@mozilla.org/base/telemetry;1"] |
michael@0 | 12 | .getService(Ci.nsITelemetry); |
michael@0 | 13 | |
michael@0 | 14 | // simpleTimers are directly associated with a histogram |
michael@0 | 15 | // name. objectTimers are associated with an object _and_ |
michael@0 | 16 | // a histogram name. |
michael@0 | 17 | let simpleTimers = {}; |
michael@0 | 18 | let objectTimers = new WeakMap(); |
michael@0 | 19 | |
michael@0 | 20 | this.TelemetryStopwatch = { |
michael@0 | 21 | /** |
michael@0 | 22 | * Starts a timer associated with a telemetry histogram. The timer can be |
michael@0 | 23 | * directly associated with a histogram, or with a pair of a histogram and |
michael@0 | 24 | * an object. |
michael@0 | 25 | * |
michael@0 | 26 | * @param aHistogram a string which must be a valid histogram name |
michael@0 | 27 | * from TelemetryHistograms.h |
michael@0 | 28 | * |
michael@0 | 29 | * @param aObj Optional parameter. If specified, the timer is associated |
michael@0 | 30 | * with this object, meaning that multiple timers for a same |
michael@0 | 31 | * histogram may be run concurrently, as long as they are |
michael@0 | 32 | * associated with different objects. |
michael@0 | 33 | * |
michael@0 | 34 | * @return true if the timer was successfully started, false otherwise. If a |
michael@0 | 35 | * timer already exists, it can't be started again, and the existing |
michael@0 | 36 | * one will be cleared in order to avoid measurements errors. |
michael@0 | 37 | */ |
michael@0 | 38 | start: function(aHistogram, aObj) { |
michael@0 | 39 | if (!validTypes(aHistogram, aObj)) |
michael@0 | 40 | return false; |
michael@0 | 41 | |
michael@0 | 42 | let timers; |
michael@0 | 43 | if (aObj) { |
michael@0 | 44 | timers = objectTimers.get(aObj, {}); |
michael@0 | 45 | objectTimers.set(aObj, timers); |
michael@0 | 46 | } else { |
michael@0 | 47 | timers = simpleTimers; |
michael@0 | 48 | } |
michael@0 | 49 | |
michael@0 | 50 | if (timers.hasOwnProperty(aHistogram)) { |
michael@0 | 51 | delete timers[aHistogram]; |
michael@0 | 52 | Cu.reportError("TelemetryStopwatch: key \"" + |
michael@0 | 53 | aHistogram + "\" was already initialized"); |
michael@0 | 54 | return false; |
michael@0 | 55 | } |
michael@0 | 56 | |
michael@0 | 57 | timers[aHistogram] = Date.now(); |
michael@0 | 58 | return true; |
michael@0 | 59 | }, |
michael@0 | 60 | |
michael@0 | 61 | /** |
michael@0 | 62 | * Deletes the timer associated with a telemetry histogram. The timer can be |
michael@0 | 63 | * directly associated with a histogram, or with a pair of a histogram and |
michael@0 | 64 | * an object. Important: Only use this method when a legitimate cancellation |
michael@0 | 65 | * should be done. |
michael@0 | 66 | * |
michael@0 | 67 | * @param aHistogram a string which must be a valid histogram name |
michael@0 | 68 | * from TelemetryHistograms.json |
michael@0 | 69 | * |
michael@0 | 70 | * @param aObj Optional parameter. If specified, the timer is associated |
michael@0 | 71 | * with this object, meaning that multiple timers for a same |
michael@0 | 72 | * histogram may be run concurrently, as long as they are |
michael@0 | 73 | * associated with different objects. |
michael@0 | 74 | * |
michael@0 | 75 | * @return true if the timer exist and it was cleared, false otherwise. |
michael@0 | 76 | */ |
michael@0 | 77 | cancel: function ts_cancel(aHistogram, aObj) { |
michael@0 | 78 | if (!validTypes(aHistogram, aObj)) |
michael@0 | 79 | return false; |
michael@0 | 80 | |
michael@0 | 81 | let timers = aObj |
michael@0 | 82 | ? objectTimers.get(aObj, {}) |
michael@0 | 83 | : simpleTimers; |
michael@0 | 84 | |
michael@0 | 85 | if (timers.hasOwnProperty(aHistogram)) { |
michael@0 | 86 | delete timers[aHistogram]; |
michael@0 | 87 | return true; |
michael@0 | 88 | } |
michael@0 | 89 | |
michael@0 | 90 | return false; |
michael@0 | 91 | }, |
michael@0 | 92 | |
michael@0 | 93 | /** |
michael@0 | 94 | * Stops the timer associated with the given histogram (and object), |
michael@0 | 95 | * calculates the time delta between start and finish, and adds the value |
michael@0 | 96 | * to the histogram. |
michael@0 | 97 | * |
michael@0 | 98 | * @param aHistogram a string which must be a valid histogram name |
michael@0 | 99 | * from TelemetryHistograms.h. If an invalid name |
michael@0 | 100 | * is given, the function will throw. |
michael@0 | 101 | * |
michael@0 | 102 | * @param aObj Optional parameter which associates the histogram timer with |
michael@0 | 103 | * the given object. |
michael@0 | 104 | * |
michael@0 | 105 | * @return true if the timer was succesfully stopped and the data was |
michael@0 | 106 | * added to the histogram, false otherwise. |
michael@0 | 107 | */ |
michael@0 | 108 | finish: function(aHistogram, aObj) { |
michael@0 | 109 | if (!validTypes(aHistogram, aObj)) |
michael@0 | 110 | return false; |
michael@0 | 111 | |
michael@0 | 112 | let timers = aObj |
michael@0 | 113 | ? objectTimers.get(aObj, {}) |
michael@0 | 114 | : simpleTimers; |
michael@0 | 115 | |
michael@0 | 116 | let start = timers[aHistogram]; |
michael@0 | 117 | delete timers[aHistogram]; |
michael@0 | 118 | |
michael@0 | 119 | if (start) { |
michael@0 | 120 | let delta = Date.now() - start; |
michael@0 | 121 | let histogram = Telemetry.getHistogramById(aHistogram); |
michael@0 | 122 | histogram.add(delta); |
michael@0 | 123 | return true; |
michael@0 | 124 | } |
michael@0 | 125 | |
michael@0 | 126 | return false; |
michael@0 | 127 | } |
michael@0 | 128 | } |
michael@0 | 129 | |
michael@0 | 130 | function validTypes(aKey, aObj) { |
michael@0 | 131 | return (typeof aKey == "string") && |
michael@0 | 132 | (aObj === undefined || typeof aObj == "object"); |
michael@0 | 133 | } |