ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/DoubleMaxUpdater.java
Revision: 1.12
Committed: Mon May 5 20:20:15 2014 UTC (9 years, 11 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.11: +7 -4 lines
Log Message:
import everything to reduce diffs with guava fork

File Contents

# Content
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 package jsr166e;
8
9 import java.io.IOException;
10 import java.io.ObjectInputStream;
11 import java.io.ObjectOutputStream;
12 import java.io.Serializable;
13
14 /**
15 * One or more variables that together maintain a running {@code double}
16 * maximum with initial value {@code Double.NEGATIVE_INFINITY}. When
17 * updates (method {@link #update}) are contended across threads, the
18 * set of variables may grow dynamically to reduce contention. Method
19 * {@link #max} (or, equivalently, {@link #doubleValue}) returns the
20 * current maximum across the variables maintaining updates.
21 *
22 * <p>This class extends {@link Number}, but does <em>not</em> define
23 * methods such as {@code equals}, {@code hashCode} and {@code
24 * compareTo} because instances are expected to be mutated, and so are
25 * not useful as collection keys.
26 *
27 * <p><em>jsr166e note: This class is targeted to be placed in
28 * java.util.concurrent.atomic.</em>
29 *
30 * @since 1.8
31 * @author Doug Lea
32 */
33 public class DoubleMaxUpdater extends Striped64 implements Serializable {
34 private static final long serialVersionUID = 7249069246863182397L;
35 /**
36 * Long representation of negative infinity. See class Double
37 * internal documentation for explanation.
38 */
39 private static final long MIN_AS_LONG = 0xfff0000000000000L;
40
41 /**
42 * Update function. See class DoubleAdder for rationale
43 * for using conversions from/to long.
44 */
45 final long fn(long v, long x) {
46 return Double.longBitsToDouble(v) > Double.longBitsToDouble(x) ? v : x;
47 }
48
49 /**
50 * Creates a new instance with initial value of {@code
51 * Double.NEGATIVE_INFINITY}.
52 */
53 public DoubleMaxUpdater() {
54 base = MIN_AS_LONG;
55 }
56
57 /**
58 * Updates the maximum to be at least the given value.
59 *
60 * @param x the value to update
61 */
62 public void update(double x) {
63 long lx = Double.doubleToRawLongBits(x);
64 Cell[] as; long b, v; int[] hc; Cell a; int n;
65 if ((as = cells) != null ||
66 (Double.longBitsToDouble(b = base) < x && !casBase(b, lx))) {
67 boolean uncontended = true;
68 if ((hc = threadHashCode.get()) == null ||
69 as == null || (n = as.length) < 1 ||
70 (a = as[(n - 1) & hc[0]]) == null ||
71 (Double.longBitsToDouble(v = a.value) < x &&
72 !(uncontended = a.cas(v, lx))))
73 retryUpdate(lx, hc, uncontended);
74 }
75 }
76
77 /**
78 * Returns the current maximum. The returned value is
79 * <em>NOT</em> an atomic snapshot; invocation in the absence of
80 * concurrent updates returns an accurate result, but concurrent
81 * updates that occur while the value is being calculated might
82 * not be incorporated.
83 *
84 * @return the maximum
85 */
86 public double max() {
87 Cell[] as = cells;
88 double max = Double.longBitsToDouble(base);
89 if (as != null) {
90 int n = as.length;
91 double v;
92 for (int i = 0; i < n; ++i) {
93 Cell a = as[i];
94 if (a != null && (v = Double.longBitsToDouble(a.value)) > max)
95 max = v;
96 }
97 }
98 return max;
99 }
100
101 /**
102 * Resets variables maintaining updates to {@code
103 * Double.NEGATIVE_INFINITY}. This method may be a useful
104 * alternative to creating a new updater, but is only effective if
105 * there are no concurrent updates. Because this method is
106 * intrinsically racy, it should only be used when it is known
107 * that no threads are concurrently updating.
108 */
109 public void reset() {
110 internalReset(MIN_AS_LONG);
111 }
112
113 /**
114 * Equivalent in effect to {@link #max} followed by {@link
115 * #reset}. This method may apply for example during quiescent
116 * points between multithreaded computations. If there are
117 * updates concurrent with this method, the returned value is
118 * <em>not</em> guaranteed to be the final value occurring before
119 * the reset.
120 *
121 * @return the maximum
122 */
123 public double maxThenReset() {
124 Cell[] as = cells;
125 double max = Double.longBitsToDouble(base);
126 base = MIN_AS_LONG;
127 if (as != null) {
128 int n = as.length;
129 for (int i = 0; i < n; ++i) {
130 Cell a = as[i];
131 if (a != null) {
132 double v = Double.longBitsToDouble(a.value);
133 a.value = MIN_AS_LONG;
134 if (v > max)
135 max = v;
136 }
137 }
138 }
139 return max;
140 }
141
142 /**
143 * Returns the String representation of the {@link #max}.
144 * @return the String representation of the {@link #max}
145 */
146 public String toString() {
147 return Double.toString(max());
148 }
149
150 /**
151 * Equivalent to {@link #max}.
152 *
153 * @return the max
154 */
155 public double doubleValue() {
156 return max();
157 }
158
159 /**
160 * Returns the {@link #max} as a {@code long} after a
161 * narrowing primitive conversion.
162 */
163 public long longValue() {
164 return (long)max();
165 }
166
167 /**
168 * Returns the {@link #max} as an {@code int} after a
169 * narrowing primitive conversion.
170 */
171 public int intValue() {
172 return (int)max();
173 }
174
175 /**
176 * Returns the {@link #max} as a {@code float}
177 * after a narrowing primitive conversion.
178 */
179 public float floatValue() {
180 return (float)max();
181 }
182
183 private void writeObject(ObjectOutputStream s) throws IOException {
184 s.defaultWriteObject();
185 s.writeDouble(max());
186 }
187
188 private void readObject(ObjectInputStream s)
189 throws IOException, ClassNotFoundException {
190 s.defaultReadObject();
191 busy = 0;
192 cells = null;
193 base = Double.doubleToRawLongBits(s.readDouble());
194 }
195
196 }