1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.hbtop.field;
19
20 import edu.umd.cs.findbugs.annotations.NonNull;
21 import java.util.Objects;
22
23 import org.apache.hadoop.hbase.classification.InterfaceAudience;
24
25
26
27
28
29
30 @InterfaceAudience.Private
31 public final class FieldValue implements Comparable<FieldValue> {
32
33 private final Object value;
34 private final FieldValueType type;
35
36 FieldValue(Object value, FieldValueType type) {
37 Objects.requireNonNull(value);
38 this.type = Objects.requireNonNull(type);
39
40 switch (type) {
41 case STRING:
42 if (value instanceof String) {
43 this.value = value;
44 break;
45 }
46 throw new IllegalArgumentException("invalid type");
47
48 case INTEGER:
49 if (value instanceof Integer) {
50 this.value = value;
51 break;
52 } else if (value instanceof String) {
53 this.value = Integer.valueOf((String) value);
54 break;
55 }
56 throw new IllegalArgumentException("invalid type");
57
58 case LONG:
59 if (value instanceof Long) {
60 this.value = value;
61 break;
62 } else if (value instanceof String) {
63 this.value = Long.valueOf((String) value);
64 break;
65 }
66 throw new IllegalArgumentException("invalid type");
67
68 case FLOAT:
69 if (value instanceof Float) {
70 this.value = value;
71 break;
72 } else if (value instanceof String) {
73 this.value = Float.valueOf((String) value);
74 break;
75 }
76 throw new IllegalArgumentException("invalid type");
77
78 case SIZE:
79 if (value instanceof Size) {
80 this.value = optimizeSize((Size) value);
81 break;
82 } else if (value instanceof String) {
83 this.value = optimizeSize(parseSizeString((String) value));
84 break;
85 }
86 throw new IllegalArgumentException("invalid type");
87
88 case PERCENT:
89 if (value instanceof Float) {
90 this.value = value;
91 break;
92 } else if (value instanceof String) {
93 this.value = parsePercentString((String) value);
94 break;
95 }
96 throw new IllegalArgumentException("invalid type");
97
98 default:
99 throw new AssertionError();
100 }
101 }
102
103 private Size optimizeSize(Size size) {
104 if (size.get(Size.Unit.BYTE) < 1024d) {
105 return size.getUnit() == Size.Unit.BYTE ?
106 size : new Size(size.get(Size.Unit.BYTE), Size.Unit.BYTE);
107 } else if (size.get(Size.Unit.KILOBYTE) < 1024d) {
108 return size.getUnit() == Size.Unit.KILOBYTE ?
109 size : new Size(size.get(Size.Unit.KILOBYTE), Size.Unit.KILOBYTE);
110 } else if (size.get(Size.Unit.MEGABYTE) < 1024d) {
111 return size.getUnit() == Size.Unit.MEGABYTE ?
112 size : new Size(size.get(Size.Unit.MEGABYTE), Size.Unit.MEGABYTE);
113 } else if (size.get(Size.Unit.GIGABYTE) < 1024d) {
114 return size.getUnit() == Size.Unit.GIGABYTE ?
115 size : new Size(size.get(Size.Unit.GIGABYTE), Size.Unit.GIGABYTE);
116 } else if (size.get(Size.Unit.TERABYTE) < 1024d) {
117 return size.getUnit() == Size.Unit.TERABYTE ?
118 size : new Size(size.get(Size.Unit.TERABYTE), Size.Unit.TERABYTE);
119 }
120 return size.getUnit() == Size.Unit.PETABYTE ?
121 size : new Size(size.get(Size.Unit.PETABYTE), Size.Unit.PETABYTE);
122 }
123
124 private Size parseSizeString(String sizeString) {
125 if (sizeString.length() < 3) {
126 throw new IllegalArgumentException("invalid size");
127 }
128
129 String valueString = sizeString.substring(0, sizeString.length() - 2);
130 String unitSimpleName = sizeString.substring(sizeString.length() - 2);
131 return new Size(Double.parseDouble(valueString), convertToUnit(unitSimpleName));
132 }
133
134 private Size.Unit convertToUnit(String unitSimpleName) {
135 for (Size.Unit unit: Size.Unit.values()) {
136 if (unitSimpleName.equals(unit.getSimpleName())) {
137 return unit;
138 }
139 }
140 throw new IllegalArgumentException("invalid size");
141 }
142
143 private Float parsePercentString(String percentString) {
144 if (percentString.endsWith("%")) {
145 percentString = percentString.substring(0, percentString.length() - 1);
146 }
147 return Float.valueOf(percentString);
148 }
149
150 public String asString() {
151 return toString();
152 }
153
154 public int asInt() {
155 return (Integer) value;
156 }
157
158 public long asLong() {
159 return (Long) value;
160 }
161
162 public float asFloat() {
163 return (Float) value;
164 }
165
166 public Size asSize() {
167 return (Size) value;
168 }
169
170 @Override
171 public String toString() {
172 switch (type) {
173 case STRING:
174 case INTEGER:
175 case LONG:
176 case FLOAT:
177 return value.toString();
178
179 case SIZE:
180 Size size = (Size) value;
181 return String.format("%.1f", size.get()) + size.getUnit().getSimpleName();
182
183 case PERCENT:
184 return String.format("%.2f", (Float) value) + "%";
185
186 default:
187 throw new AssertionError();
188 }
189 }
190
191 @Override
192 public int compareTo(@NonNull FieldValue o) {
193 if (type != o.type) {
194 throw new IllegalArgumentException("invalid type");
195 }
196
197 switch (type) {
198 case STRING:
199 return ((String) value).compareTo((String) o.value);
200
201 case INTEGER:
202 return ((Integer) value).compareTo((Integer) o.value);
203
204 case LONG:
205 return ((Long) value).compareTo((Long) o.value);
206
207 case FLOAT:
208 case PERCENT:
209 return ((Float) value).compareTo((Float) o.value);
210
211 case SIZE:
212 return ((Size) value).compareTo((Size) o.value);
213
214 default:
215 throw new AssertionError();
216 }
217 }
218
219 @Override
220 public boolean equals(Object o) {
221 if (this == o) {
222 return true;
223 }
224 if (!(o instanceof FieldValue)) {
225 return false;
226 }
227 FieldValue that = (FieldValue) o;
228 return value.equals(that.value) && type == that.type;
229 }
230
231 @Override
232 public int hashCode() {
233 return Objects.hash(value, type);
234 }
235
236 public FieldValue plus(FieldValue o) {
237 if (type != o.type) {
238 throw new IllegalArgumentException("invalid type");
239 }
240
241 switch (type) {
242 case STRING:
243 return new FieldValue(((String) value).concat((String) o.value), type);
244
245 case INTEGER:
246 return new FieldValue(((Integer) value) + ((Integer) o.value), type);
247
248 case LONG:
249 return new FieldValue(((Long) value) + ((Long) o.value), type);
250
251 case FLOAT:
252 case PERCENT:
253 return new FieldValue(((Float) value) + ((Float) o.value), type);
254
255 case SIZE:
256 Size size = (Size) value;
257 Size oSize = (Size) o.value;
258 Size.Unit unit = size.getUnit();
259 return new FieldValue(new Size(size.get(unit) + oSize.get(unit), unit), type);
260
261 default:
262 throw new AssertionError();
263 }
264 }
265
266 public int compareToIgnoreCase(FieldValue o) {
267 if (type != o.type) {
268 throw new IllegalArgumentException("invalid type");
269 }
270
271 switch (type) {
272 case STRING:
273 return ((String) value).compareToIgnoreCase((String) o.value);
274
275 case INTEGER:
276 case LONG:
277 case FLOAT:
278 case SIZE:
279 case PERCENT:
280 return compareTo(o);
281
282 default:
283 throw new AssertionError();
284 }
285 }
286 }