blob: bde287836952b82e765e26422714da165bb97d84 [file] [log] [blame]
Thomas Vachuska24c849c2014-10-27 09:53:05 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 Open Networking Laboratory
Thomas Vachuska24c849c2014-10-27 09:53:05 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska24c849c2014-10-27 09:53:05 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska24c849c2014-10-27 09:53:05 -070015 */
toma7083182014-09-25 21:38:03 -070016package org.onlab.util;
17
18import java.util.Objects;
19
20import static com.google.common.base.MoreObjects.toStringHelper;
21import static com.google.common.base.Preconditions.checkArgument;
22
23/**
24 * Counting mechanism capable of tracking occurrences and rates.
25 */
26public class Counter {
27
28 private long total = 0;
29 private long start = System.currentTimeMillis();
30 private long end = 0;
31
32 /**
33 * Creates a new counter.
34 */
35 public Counter() {
36 }
37
38 /**
39 * Creates a new counter in a specific state. If non-zero end time is
40 * specified, the counter will be frozen.
41 *
42 * @param start start time
43 * @param total total number of items to start with
44 * @param end end time; if non-ze
45 */
46 public Counter(long start, long total, long end) {
47 checkArgument(start <= end, "Malformed interval: start > end");
48 checkArgument(total >= 0, "Total must be non-negative");
49 this.start = start;
50 this.total = total;
51 this.end = end;
52 }
53
54 /**
55 * Resets the counter, by zeroing out the count and restarting the timer.
56 */
57 public synchronized void reset() {
58 end = 0;
59 total = 0;
60 start = System.currentTimeMillis();
61 }
62
63 /**
64 * Freezes the counter in the current state including the counts and times.
65 */
66 public synchronized void freeze() {
67 end = System.currentTimeMillis();
68 }
69
70 /**
71 * Adds the specified number of occurrences to the counter. No-op if the
72 * counter has been frozen.
73 *
74 * @param count number of occurrences
75 */
76 public synchronized void add(long count) {
77 checkArgument(count >= 0, "Count must be non-negative");
78 if (end == 0L) {
79 total += count;
80 }
81 }
82
83 /**
84 * Returns the number of occurrences per second.
85 *
86 * @return throughput in occurrences per second
87 */
88 public synchronized double throughput() {
89 return total / duration();
90 }
91
92 /**
93 * Returns the total number of occurrences counted.
94 *
95 * @return number of counted occurrences
96 */
97 public synchronized long total() {
98 return total;
99 }
100
101 /**
102 * Returns the duration expressed in fractional number of seconds.
103 *
104 * @return fractional number of seconds since the last reset
105 */
106 public synchronized double duration() {
107 // Protect against 0 return by artificially setting duration to 1ms
108 long duration = (end == 0L ? System.currentTimeMillis() : end) - start;
109 return (duration == 0 ? 1 : duration) / 1000.0;
110 }
111
112 @Override
113 public int hashCode() {
114 return Objects.hash(total, start, end);
115 }
116
117 @Override
118 public boolean equals(Object obj) {
119 if (this == obj) {
120 return true;
121 }
122 if (obj instanceof Counter) {
123 final Counter other = (Counter) obj;
124 return Objects.equals(this.total, other.total) &&
125 Objects.equals(this.start, other.start) &&
126 Objects.equals(this.end, other.end);
127 }
128 return false;
129 }
130
131 @Override
132 public String toString() {
133 return toStringHelper(this)
134 .add("total", total)
135 .add("start", start)
136 .add("end", end)
137 .toString();
138 }
139}