Coverage Summary for Class: AtomicDoubleArray (com.google.common.util.concurrent)

Class Class, % Method, % Line, %
AtomicDoubleArray 0% (0/1) 0% (0/14) 0% (0/53)


1 /* 2  * Written by Doug Lea with assistance from members of JCP JSR-166 3  * Expert Group and released to the public domain, as explained at 4  * http://creativecommons.org/publicdomain/zero/1.0/ 5  */ 6  7 /* 8  * Source: 9  * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/extra/AtomicDoubleArray.java?revision=1.5 10  * (Modified to adapt to guava coding conventions and 11  * to use AtomicLongArray instead of sun.misc.Unsafe) 12  */ 13  14 package com.google.common.util.concurrent; 15  16 import static java.lang.Double.doubleToRawLongBits; 17 import static java.lang.Double.longBitsToDouble; 18  19 import com.google.common.annotations.GwtIncompatible; 20 import com.google.common.primitives.ImmutableLongArray; 21 import com.google.errorprone.annotations.CanIgnoreReturnValue; 22 import java.util.concurrent.atomic.AtomicLongArray; 23  24 /** 25  * A {@code double} array in which elements may be updated atomically. See the {@link 26  * java.util.concurrent.atomic} package specification for description of the properties of atomic 27  * variables. 28  * 29  * <p><a id="bitEquals"></a>This class compares primitive {@code double} values in methods such as 30  * {@link #compareAndSet} by comparing their bitwise representation using {@link 31  * Double#doubleToRawLongBits}, which differs from both the primitive double {@code ==} operator and 32  * from {@link Double#equals}, as if implemented by: 33  * 34  * <pre>{@code 35  * static boolean bitEquals(double x, double y) { 36  * long xBits = Double.doubleToRawLongBits(x); 37  * long yBits = Double.doubleToRawLongBits(y); 38  * return xBits == yBits; 39  * } 40  * }</pre> 41  * 42  * @author Doug Lea 43  * @author Martin Buchholz 44  * @since 11.0 45  */ 46 @GwtIncompatible 47 @ElementTypesAreNonnullByDefault 48 public class AtomicDoubleArray implements java.io.Serializable { 49  private static final long serialVersionUID = 0L; 50  51  // Making this non-final is the lesser evil according to Effective 52  // Java 2nd Edition Item 76: Write readObject methods defensively. 53  private transient AtomicLongArray longs; 54  55  /** 56  * Creates a new {@code AtomicDoubleArray} of the given length, with all elements initially zero. 57  * 58  * @param length the length of the array 59  */ 60  public AtomicDoubleArray(int length) { 61  this.longs = new AtomicLongArray(length); 62  } 63  64  /** 65  * Creates a new {@code AtomicDoubleArray} with the same length as, and all elements copied from, 66  * the given array. 67  * 68  * @param array the array to copy elements from 69  * @throws NullPointerException if array is null 70  */ 71  public AtomicDoubleArray(double[] array) { 72  final int len = array.length; 73  long[] longArray = new long[len]; 74  for (int i = 0; i < len; i++) { 75  longArray[i] = doubleToRawLongBits(array[i]); 76  } 77  this.longs = new AtomicLongArray(longArray); 78  } 79  80  /** 81  * Returns the length of the array. 82  * 83  * @return the length of the array 84  */ 85  public final int length() { 86  return longs.length(); 87  } 88  89  /** 90  * Gets the current value at position {@code i}. 91  * 92  * @param i the index 93  * @return the current value 94  */ 95  public final double get(int i) { 96  return longBitsToDouble(longs.get(i)); 97  } 98  99  /** 100  * Atomically sets the element at position {@code i} to the given value. 101  * 102  * @param i the index 103  * @param newValue the new value 104  */ 105  public final void set(int i, double newValue) { 106  long next = doubleToRawLongBits(newValue); 107  longs.set(i, next); 108  } 109  110  /** 111  * Eventually sets the element at position {@code i} to the given value. 112  * 113  * @param i the index 114  * @param newValue the new value 115  */ 116  public final void lazySet(int i, double newValue) { 117  long next = doubleToRawLongBits(newValue); 118  longs.lazySet(i, next); 119  } 120  121  /** 122  * Atomically sets the element at position {@code i} to the given value and returns the old value. 123  * 124  * @param i the index 125  * @param newValue the new value 126  * @return the previous value 127  */ 128  public final double getAndSet(int i, double newValue) { 129  long next = doubleToRawLongBits(newValue); 130  return longBitsToDouble(longs.getAndSet(i, next)); 131  } 132  133  /** 134  * Atomically sets the element at position {@code i} to the given updated value if the current 135  * value is <a href="#bitEquals">bitwise equal</a> to the expected value. 136  * 137  * @param i the index 138  * @param expect the expected value 139  * @param update the new value 140  * @return true if successful. False return indicates that the actual value was not equal to the 141  * expected value. 142  */ 143  public final boolean compareAndSet(int i, double expect, double update) { 144  return longs.compareAndSet(i, doubleToRawLongBits(expect), doubleToRawLongBits(update)); 145  } 146  147  /** 148  * Atomically sets the element at position {@code i} to the given updated value if the current 149  * value is <a href="#bitEquals">bitwise equal</a> to the expected value. 150  * 151  * <p>May <a 152  * href="http://download.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/package-summary.html#Spurious"> 153  * fail spuriously</a> and does not provide ordering guarantees, so is only rarely an appropriate 154  * alternative to {@code compareAndSet}. 155  * 156  * @param i the index 157  * @param expect the expected value 158  * @param update the new value 159  * @return true if successful 160  */ 161  public final boolean weakCompareAndSet(int i, double expect, double update) { 162  return longs.weakCompareAndSet(i, doubleToRawLongBits(expect), doubleToRawLongBits(update)); 163  } 164  165  /** 166  * Atomically adds the given value to the element at index {@code i}. 167  * 168  * @param i the index 169  * @param delta the value to add 170  * @return the previous value 171  */ 172  @CanIgnoreReturnValue 173  public final double getAndAdd(int i, double delta) { 174  while (true) { 175  long current = longs.get(i); 176  double currentVal = longBitsToDouble(current); 177  double nextVal = currentVal + delta; 178  long next = doubleToRawLongBits(nextVal); 179  if (longs.compareAndSet(i, current, next)) { 180  return currentVal; 181  } 182  } 183  } 184  185  /** 186  * Atomically adds the given value to the element at index {@code i}. 187  * 188  * @param i the index 189  * @param delta the value to add 190  * @return the updated value 191  */ 192  @CanIgnoreReturnValue 193  public double addAndGet(int i, double delta) { 194  while (true) { 195  long current = longs.get(i); 196  double currentVal = longBitsToDouble(current); 197  double nextVal = currentVal + delta; 198  long next = doubleToRawLongBits(nextVal); 199  if (longs.compareAndSet(i, current, next)) { 200  return nextVal; 201  } 202  } 203  } 204  205  /** 206  * Returns the String representation of the current values of array. 207  * 208  * @return the String representation of the current values of array 209  */ 210  @Override 211  public String toString() { 212  int iMax = length() - 1; 213  if (iMax == -1) { 214  return "[]"; 215  } 216  217  // Double.toString(Math.PI).length() == 17 218  StringBuilder b = new StringBuilder((17 + 2) * (iMax + 1)); 219  b.append('['); 220  for (int i = 0; ; i++) { 221  b.append(longBitsToDouble(longs.get(i))); 222  if (i == iMax) { 223  return b.append(']').toString(); 224  } 225  b.append(',').append(' '); 226  } 227  } 228  229  /** 230  * Saves the state to a stream (that is, serializes it). 231  * 232  * @serialData The length of the array is emitted (int), followed by all of its elements (each a 233  * {@code double}) in the proper order. 234  */ 235  private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { 236  s.defaultWriteObject(); 237  238  // Write out array length 239  int length = length(); 240  s.writeInt(length); 241  242  // Write out all elements in the proper order. 243  for (int i = 0; i < length; i++) { 244  s.writeDouble(get(i)); 245  } 246  } 247  248  /** Reconstitutes the instance from a stream (that is, deserializes it). */ 249  private void readObject(java.io.ObjectInputStream s) 250  throws java.io.IOException, ClassNotFoundException { 251  s.defaultReadObject(); 252  253  int length = s.readInt(); 254  ImmutableLongArray.Builder builder = ImmutableLongArray.builder(); 255  for (int i = 0; i < length; i++) { 256  builder.add(doubleToRawLongBits(s.readDouble())); 257  } 258  this.longs = new AtomicLongArray(builder.build().toArray()); 259  } 260 }