001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.hbtop.field; 019 020import edu.umd.cs.findbugs.annotations.NonNull; 021import java.util.Objects; 022import org.apache.hadoop.hbase.Size; 023import org.apache.yetus.audience.InterfaceAudience; 024 025 026/** 027 * Represents a value of a field. 028 * 029 * The type of a value is defined by {@link FieldValue}. 030 */ 031@InterfaceAudience.Private 032public final class FieldValue implements Comparable<FieldValue> { 033 034 private final Object value; 035 private final FieldValueType type; 036 037 FieldValue(Object value, FieldValueType type) { 038 Objects.requireNonNull(value); 039 this.type = Objects.requireNonNull(type); 040 041 switch (type) { 042 case STRING: 043 if (value instanceof String) { 044 this.value = value; 045 break; 046 } 047 throw new IllegalArgumentException("invalid type"); 048 049 case INTEGER: 050 if (value instanceof Integer) { 051 this.value = value; 052 break; 053 } else if (value instanceof String) { 054 this.value = Integer.valueOf((String) value); 055 break; 056 } 057 throw new IllegalArgumentException("invalid type"); 058 059 case LONG: 060 if (value instanceof Long) { 061 this.value = value; 062 break; 063 } else if (value instanceof String) { 064 this.value = Long.valueOf((String) value); 065 break; 066 } 067 throw new IllegalArgumentException("invalid type"); 068 069 case FLOAT: 070 if (value instanceof Float) { 071 this.value = value; 072 break; 073 } else if (value instanceof String) { 074 this.value = Float.valueOf((String) value); 075 break; 076 } 077 throw new IllegalArgumentException("invalid type"); 078 079 case SIZE: 080 if (value instanceof Size) { 081 this.value = optimizeSize((Size) value); 082 break; 083 } else if (value instanceof String) { 084 this.value = optimizeSize(parseSizeString((String) value)); 085 break; 086 } 087 throw new IllegalArgumentException("invalid type"); 088 089 case PERCENT: 090 if (value instanceof Float) { 091 this.value = value; 092 break; 093 } else if (value instanceof String) { 094 this.value = parsePercentString((String) value); 095 break; 096 } 097 throw new IllegalArgumentException("invalid type"); 098 099 default: 100 throw new AssertionError(); 101 } 102 } 103 104 private Size optimizeSize(Size size) { 105 if (size.get(Size.Unit.BYTE) < 1024d) { 106 return size.getUnit() == Size.Unit.BYTE ? 107 size : new Size(size.get(Size.Unit.BYTE), Size.Unit.BYTE); 108 } else if (size.get(Size.Unit.KILOBYTE) < 1024d) { 109 return size.getUnit() == Size.Unit.KILOBYTE ? 110 size : new Size(size.get(Size.Unit.KILOBYTE), Size.Unit.KILOBYTE); 111 } else if (size.get(Size.Unit.MEGABYTE) < 1024d) { 112 return size.getUnit() == Size.Unit.MEGABYTE ? 113 size : new Size(size.get(Size.Unit.MEGABYTE), Size.Unit.MEGABYTE); 114 } else if (size.get(Size.Unit.GIGABYTE) < 1024d) { 115 return size.getUnit() == Size.Unit.GIGABYTE ? 116 size : new Size(size.get(Size.Unit.GIGABYTE), Size.Unit.GIGABYTE); 117 } else if (size.get(Size.Unit.TERABYTE) < 1024d) { 118 return size.getUnit() == Size.Unit.TERABYTE ? 119 size : new Size(size.get(Size.Unit.TERABYTE), Size.Unit.TERABYTE); 120 } 121 return size.getUnit() == Size.Unit.PETABYTE ? 122 size : new Size(size.get(Size.Unit.PETABYTE), Size.Unit.PETABYTE); 123 } 124 125 private Size parseSizeString(String sizeString) { 126 if (sizeString.length() < 3) { 127 throw new IllegalArgumentException("invalid size"); 128 } 129 130 String valueString = sizeString.substring(0, sizeString.length() - 2); 131 String unitSimpleName = sizeString.substring(sizeString.length() - 2); 132 return new Size(Double.parseDouble(valueString), convertToUnit(unitSimpleName)); 133 } 134 135 private Size.Unit convertToUnit(String unitSimpleName) { 136 for (Size.Unit unit: Size.Unit.values()) { 137 if (unitSimpleName.equals(unit.getSimpleName())) { 138 return unit; 139 } 140 } 141 throw new IllegalArgumentException("invalid size"); 142 } 143 144 private Float parsePercentString(String percentString) { 145 if (percentString.endsWith("%")) { 146 percentString = percentString.substring(0, percentString.length() - 1); 147 } 148 return Float.valueOf(percentString); 149 } 150 151 public String asString() { 152 return toString(); 153 } 154 155 public int asInt() { 156 return (Integer) value; 157 } 158 159 public long asLong() { 160 return (Long) value; 161 } 162 163 public float asFloat() { 164 return (Float) value; 165 } 166 167 public Size asSize() { 168 return (Size) value; 169 } 170 171 @Override 172 public String toString() { 173 switch (type) { 174 case STRING: 175 case INTEGER: 176 case LONG: 177 case FLOAT: 178 case SIZE: 179 return value.toString(); 180 181 case PERCENT: 182 return String.format("%.2f", (Float) value) + "%"; 183 184 default: 185 throw new AssertionError(); 186 } 187 } 188 189 @Override 190 public int compareTo(@NonNull FieldValue o) { 191 if (type != o.type) { 192 throw new IllegalArgumentException("invalid type"); 193 } 194 195 switch (type) { 196 case STRING: 197 return ((String) value).compareTo((String) o.value); 198 199 case INTEGER: 200 return ((Integer) value).compareTo((Integer) o.value); 201 202 case LONG: 203 return ((Long) value).compareTo((Long) o.value); 204 205 case FLOAT: 206 case PERCENT: 207 return ((Float) value).compareTo((Float) o.value); 208 209 case SIZE: 210 return ((Size) value).compareTo((Size) o.value); 211 212 default: 213 throw new AssertionError(); 214 } 215 } 216 217 @Override 218 public boolean equals(Object o) { 219 if (this == o) { 220 return true; 221 } 222 if (!(o instanceof FieldValue)) { 223 return false; 224 } 225 FieldValue that = (FieldValue) o; 226 return value.equals(that.value) && type == that.type; 227 } 228 229 @Override 230 public int hashCode() { 231 return Objects.hash(value, type); 232 } 233 234 public FieldValue plus(FieldValue o) { 235 if (type != o.type) { 236 throw new IllegalArgumentException("invalid type"); 237 } 238 239 switch (type) { 240 case STRING: 241 return new FieldValue(((String) value).concat((String) o.value), type); 242 243 case INTEGER: 244 return new FieldValue(((Integer) value) + ((Integer) o.value), type); 245 246 case LONG: 247 return new FieldValue(((Long) value) + ((Long) o.value), type); 248 249 case FLOAT: 250 case PERCENT: 251 return new FieldValue(((Float) value) + ((Float) o.value), type); 252 253 case SIZE: 254 Size size = (Size) value; 255 Size oSize = (Size) o.value; 256 Size.Unit unit = size.getUnit(); 257 return new FieldValue(new Size(size.get(unit) + oSize.get(unit), unit), type); 258 259 default: 260 throw new AssertionError(); 261 } 262 } 263 264 public int compareToIgnoreCase(FieldValue o) { 265 if (type != o.type) { 266 throw new IllegalArgumentException("invalid type"); 267 } 268 269 switch (type) { 270 case STRING: 271 return ((String) value).compareToIgnoreCase((String) o.value); 272 273 case INTEGER: 274 case LONG: 275 case FLOAT: 276 case SIZE: 277 case PERCENT: 278 return compareTo(o); 279 280 default: 281 throw new AssertionError(); 282 } 283 } 284}