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 * Represents a value of a field. The type of a value is defined by {@link FieldValue}. 027 */ 028@InterfaceAudience.Private 029public final class FieldValue implements Comparable<FieldValue> { 030 031 private final Object value; 032 private final FieldValueType type; 033 034 FieldValue(Object value, FieldValueType type) { 035 Objects.requireNonNull(value); 036 this.type = Objects.requireNonNull(type); 037 038 switch (type) { 039 case STRING: 040 if (value instanceof String) { 041 this.value = value; 042 break; 043 } 044 throw new IllegalArgumentException("invalid type"); 045 046 case INTEGER: 047 if (value instanceof Integer) { 048 this.value = value; 049 break; 050 } else if (value instanceof String) { 051 this.value = Integer.valueOf((String) value); 052 break; 053 } 054 throw new IllegalArgumentException("invalid type"); 055 056 case LONG: 057 if (value instanceof Long) { 058 this.value = value; 059 break; 060 } else if (value instanceof String) { 061 this.value = Long.valueOf((String) value); 062 break; 063 } 064 throw new IllegalArgumentException("invalid type"); 065 066 case FLOAT: 067 if (value instanceof Float) { 068 this.value = value; 069 break; 070 } else if (value instanceof String) { 071 this.value = Float.valueOf((String) value); 072 break; 073 } 074 throw new IllegalArgumentException("invalid type"); 075 076 case SIZE: 077 if (value instanceof Size) { 078 this.value = optimizeSize((Size) value); 079 break; 080 } else if (value instanceof String) { 081 this.value = optimizeSize(parseSizeString((String) value)); 082 break; 083 } 084 throw new IllegalArgumentException("invalid type"); 085 086 case PERCENT: 087 if (value instanceof Float) { 088 this.value = value; 089 break; 090 } else if (value instanceof String) { 091 this.value = parsePercentString((String) value); 092 break; 093 } 094 throw new IllegalArgumentException("invalid type"); 095 096 default: 097 throw new AssertionError(); 098 } 099 } 100 101 private Size optimizeSize(Size size) { 102 if (size.get(Size.Unit.BYTE) < 1024d) { 103 return size.getUnit() == Size.Unit.BYTE 104 ? size 105 : new Size(size.get(Size.Unit.BYTE), Size.Unit.BYTE); 106 } else if (size.get(Size.Unit.KILOBYTE) < 1024d) { 107 return size.getUnit() == Size.Unit.KILOBYTE 108 ? size 109 : 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 113 : 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 117 : new Size(size.get(Size.Unit.GIGABYTE), Size.Unit.GIGABYTE); 118 } else if (size.get(Size.Unit.TERABYTE) < 1024d) { 119 return size.getUnit() == Size.Unit.TERABYTE 120 ? size 121 : new Size(size.get(Size.Unit.TERABYTE), Size.Unit.TERABYTE); 122 } 123 return size.getUnit() == Size.Unit.PETABYTE 124 ? size 125 : new Size(size.get(Size.Unit.PETABYTE), Size.Unit.PETABYTE); 126 } 127 128 private Size parseSizeString(String sizeString) { 129 if (sizeString.length() < 3) { 130 throw new IllegalArgumentException("invalid size"); 131 } 132 133 String valueString = sizeString.substring(0, sizeString.length() - 2); 134 String unitSimpleName = sizeString.substring(sizeString.length() - 2); 135 return new Size(Double.parseDouble(valueString), convertToUnit(unitSimpleName)); 136 } 137 138 private Size.Unit convertToUnit(String unitSimpleName) { 139 for (Size.Unit unit : Size.Unit.values()) { 140 if (unitSimpleName.equals(unit.getSimpleName())) { 141 return unit; 142 } 143 } 144 throw new IllegalArgumentException("invalid size"); 145 } 146 147 private Float parsePercentString(String percentString) { 148 if (percentString.endsWith("%")) { 149 percentString = percentString.substring(0, percentString.length() - 1); 150 } 151 return Float.valueOf(percentString); 152 } 153 154 public String asString() { 155 return toString(); 156 } 157 158 public int asInt() { 159 return (Integer) value; 160 } 161 162 public long asLong() { 163 return (Long) value; 164 } 165 166 public float asFloat() { 167 return (Float) value; 168 } 169 170 public Size asSize() { 171 return (Size) value; 172 } 173 174 @Override 175 public String toString() { 176 switch (type) { 177 case STRING: 178 case INTEGER: 179 case LONG: 180 case FLOAT: 181 return value.toString(); 182 183 case SIZE: 184 Size size = (Size) value; 185 return String.format("%.1f", size.get()) + size.getUnit().getSimpleName(); 186 187 case PERCENT: 188 return String.format("%.2f", (Float) value) + "%"; 189 190 default: 191 throw new AssertionError(); 192 } 193 } 194 195 @Override 196 public int compareTo(@NonNull FieldValue o) { 197 if (type != o.type) { 198 throw new IllegalArgumentException("invalid type"); 199 } 200 201 switch (type) { 202 case STRING: 203 return ((String) value).compareTo((String) o.value); 204 205 case INTEGER: 206 return ((Integer) value).compareTo((Integer) o.value); 207 208 case LONG: 209 return ((Long) value).compareTo((Long) o.value); 210 211 case FLOAT: 212 case PERCENT: 213 return ((Float) value).compareTo((Float) o.value); 214 215 case SIZE: 216 return ((Size) value).compareTo((Size) o.value); 217 218 default: 219 throw new AssertionError(); 220 } 221 } 222 223 @Override 224 public boolean equals(Object o) { 225 if (this == o) { 226 return true; 227 } 228 if (!(o instanceof FieldValue)) { 229 return false; 230 } 231 FieldValue that = (FieldValue) o; 232 return value.equals(that.value) && type == that.type; 233 } 234 235 @Override 236 public int hashCode() { 237 return Objects.hash(value, type); 238 } 239 240 public FieldValue plus(FieldValue o) { 241 if (type != o.type) { 242 throw new IllegalArgumentException("invalid type"); 243 } 244 245 switch (type) { 246 case STRING: 247 return new FieldValue(((String) value).concat((String) o.value), type); 248 249 case INTEGER: 250 return new FieldValue(((Integer) value) + ((Integer) o.value), type); 251 252 case LONG: 253 return new FieldValue(((Long) value) + ((Long) o.value), type); 254 255 case FLOAT: 256 case PERCENT: 257 return new FieldValue(((Float) value) + ((Float) o.value), type); 258 259 case SIZE: 260 Size size = (Size) value; 261 Size oSize = (Size) o.value; 262 Size.Unit unit = size.getUnit(); 263 return new FieldValue(new Size(size.get(unit) + oSize.get(unit), unit), type); 264 265 default: 266 throw new AssertionError(); 267 } 268 } 269 270 public int compareToIgnoreCase(FieldValue o) { 271 if (type != o.type) { 272 throw new IllegalArgumentException("invalid type"); 273 } 274 275 switch (type) { 276 case STRING: 277 return ((String) value).compareToIgnoreCase((String) o.value); 278 279 case INTEGER: 280 case LONG: 281 case FLOAT: 282 case SIZE: 283 case PERCENT: 284 return compareTo(o); 285 286 default: 287 throw new AssertionError(); 288 } 289 } 290}