View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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   * Represents a value of a field.
27   *
28   * The type of a value is defined by {@link FieldValue}.
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 }