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.hdfs.util; 019 020import java.util.Arrays; 021 022import com.google.common.base.Preconditions; 023 024/** 025 * Similar to {@link EnumCounters} except that the value type is double. 026 * 027 * @param <E> the enum type 028 */ 029public class EnumDoubles<E extends Enum<E>> { 030 /** The class of the enum. */ 031 private final Class<E> enumClass; 032 /** An array of doubles corresponding to the enum type. */ 033 private final double[] doubles; 034 035 /** 036 * Construct doubles for the given enum constants. 037 * @param enumClass the enum class. 038 */ 039 public EnumDoubles(final Class<E> enumClass) { 040 final E[] enumConstants = enumClass.getEnumConstants(); 041 Preconditions.checkNotNull(enumConstants); 042 this.enumClass = enumClass; 043 this.doubles = new double[enumConstants.length]; 044 } 045 046 /** @return the value corresponding to e. */ 047 public final double get(final E e) { 048 return doubles[e.ordinal()]; 049 } 050 051 /** Negate all values. */ 052 public final void negation() { 053 for(int i = 0; i < doubles.length; i++) { 054 doubles[i] = -doubles[i]; 055 } 056 } 057 058 /** Set e to the given value. */ 059 public final void set(final E e, final double value) { 060 doubles[e.ordinal()] = value; 061 } 062 063 /** Set the values of this object to that object. */ 064 public final void set(final EnumDoubles<E> that) { 065 for(int i = 0; i < doubles.length; i++) { 066 this.doubles[i] = that.doubles[i]; 067 } 068 } 069 070 /** Reset all values to zero. */ 071 public final void reset() { 072 for(int i = 0; i < doubles.length; i++) { 073 this.doubles[i] = 0.0; 074 } 075 } 076 077 /** Add the given value to e. */ 078 public final void add(final E e, final double value) { 079 doubles[e.ordinal()] += value; 080 } 081 082 /** Add the values of that object to this. */ 083 public final void add(final EnumDoubles<E> that) { 084 for(int i = 0; i < doubles.length; i++) { 085 this.doubles[i] += that.doubles[i]; 086 } 087 } 088 089 /** Subtract the given value from e. */ 090 public final void subtract(final E e, final double value) { 091 doubles[e.ordinal()] -= value; 092 } 093 094 /** Subtract the values of this object from that object. */ 095 public final void subtract(final EnumDoubles<E> that) { 096 for(int i = 0; i < doubles.length; i++) { 097 this.doubles[i] -= that.doubles[i]; 098 } 099 } 100 101 @Override 102 public boolean equals(Object obj) { 103 if (obj == this) { 104 return true; 105 } else if (obj == null || !(obj instanceof EnumDoubles)) { 106 return false; 107 } 108 final EnumDoubles<?> that = (EnumDoubles<?>)obj; 109 return this.enumClass == that.enumClass 110 && Arrays.equals(this.doubles, that.doubles); 111 } 112 113 @Override 114 public int hashCode() { 115 return Arrays.hashCode(doubles); 116 } 117 118 @Override 119 public String toString() { 120 final E[] enumConstants = enumClass.getEnumConstants(); 121 final StringBuilder b = new StringBuilder(); 122 for(int i = 0; i < doubles.length; i++) { 123 final String name = enumConstants[i].name(); 124 b.append(name).append("=").append(doubles[i]).append(", "); 125 } 126 return b.substring(0, b.length() - 2); 127 } 128}