1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.monitoring.counters;
19
20 import java.util.ArrayList;
21 import java.util.Collections;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Set;
25 import java.util.concurrent.ConcurrentHashMap;
26 import java.util.concurrent.CopyOnWriteArraySet;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 public class Unit implements Comparable<Unit> {
42 private static final Map<String, Unit> UNITS = new ConcurrentHashMap<String, Unit>();
43
44
45
46
47 public static class Time extends Unit {
48 public static final Unit NANOSECOND = new Unit("ns");
49 public static final Unit MICROSECOND = new Unit("µs", NANOSECOND, 1000);
50 public static final Unit MILLISECOND = new Unit("ms", MICROSECOND, 1000);
51 public static final Unit SECOND = new Unit("s", MILLISECOND, 1000);
52 public static final Unit MINUTE = new Unit("min", SECOND, 60);
53 public static final Unit HOUR = new Unit("h", MINUTE, 60);
54 public static final Unit DAY = new Unit("day", HOUR, 24);
55
56 public Time(String name) {
57 super(name);
58 }
59
60 public Time(String name, Unit derived, long scale) {
61 super(name, derived, scale);
62 }
63
64 }
65
66
67
68
69 public static class Binary
70 extends Unit {
71
72 public static final Unit BYTE = new Unit("b");
73
74 public static final Unit KBYTE = new Unit("Kb", BYTE, 1024);
75
76 public static final Unit MBYTE = new Unit("Mb", KBYTE, 1024);
77
78 public static final Unit GBYTE = new Unit("Gb", MBYTE, 1024);
79
80 public Binary(String name) {
81 super(name);
82 }
83
84 public Binary(String name, Unit derived, long scale) {
85 super(name, derived, scale);
86 }
87
88
89 }
90
91
92
93
94
95
96
97 public static final Unit UNARY = new Unit("u");
98 public static final Unit DECA = new Unit("*10", UNARY, 10);
99 public static final Unit HECTO = new Unit("*100", DECA, 10);
100 public static final Unit KILO = new Unit("*1000", HECTO, 10);
101 public static final Unit MEGA = new Unit("*10^6", KILO, 1000);
102 public static final Unit GIGA = new Unit("*10^9", MEGA, 1000);
103 public static final Unit TERA = new Unit("*10^12", GIGA, 1000);
104
105 private final String name;
106
107 private final long scale;
108
109 private Unit primary;
110
111 private List<Unit> derived;
112
113 public Set<Unit> primaryUnits = new CopyOnWriteArraySet<Unit>();
114
115
116 public static Unit get(String name) {
117 return UNITS.get(name);
118 }
119
120
121
122
123
124
125 public Unit(String name) {
126 this.name = name;
127 this.primary = this;
128 this.scale = 1;
129 this.derived = new ArrayList<Unit>();
130 this.derived.add(this);
131 primaryUnits.add(this);
132 UNITS.put(name, this);
133 }
134
135
136
137
138
139
140
141
142 public Unit(String name, Unit derived, long scale) {
143 this.name = name;
144 this.primary = derived.isPrimary() ? derived : derived.getPrimary();
145 this.scale = scale * derived.getScale();
146 primary.derived.add(this);
147 Collections.sort(primary.derived);
148 UNITS.put(name, this);
149 }
150
151 public Unit getDerived(String name) {
152 for (Unit unit : derived) {
153 if (unit.name.equals(name)) {
154 return unit;
155 }
156 }
157 return null;
158 }
159
160 public List<Unit> getDerived() {
161 return Collections.unmodifiableList(derived);
162 }
163
164
165 public String getName() {
166 return name;
167 }
168
169 public long getScale() {
170 return scale;
171 }
172
173
174
175
176
177
178
179
180 public double convert(final double value, final Unit unit) {
181 if (unit == this) {
182 return value;
183 }
184 if (!isCompatible(unit)) {
185 throw new IllegalArgumentException("unit " + name + " is incompatible with unit " + unit.name);
186 }
187 return value * unit.getScale() / scale;
188 }
189
190 public boolean isPrimary() {
191 return primary == this;
192 }
193
194 public boolean isCompatible(Unit unit) {
195 return primary == unit.getPrimary();
196 }
197
198 public Unit getPrimary() {
199 return this.primary;
200 }
201
202 public int compareTo(Unit o) {
203 return scale < o.scale ? -1 : 1;
204 }
205
206 public String toString() {
207 return name;
208 }
209
210
211
212
213 @Override
214 public int hashCode() {
215 final int prime = 31;
216 int result = 1;
217 result = prime * result + ((name == null) ? 0 : name.hashCode());
218 return result;
219 }
220
221
222
223
224 @Override
225 public boolean equals(Object obj) {
226 if (this == obj)
227 return true;
228 if (obj == null)
229 return false;
230 if (getClass() != obj.getClass())
231 return false;
232 final Unit other = (Unit) obj;
233 if (name == null) {
234 if (other.name != null)
235 return false;
236 } else if (!name.equals(other.name))
237 return false;
238 return true;
239 }
240
241 }