ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/DoubleMaxUpdater.java
Revision: 1.1
Committed: Tue Aug 2 18:04:12 2011 UTC (12 years, 9 months ago) by dl
Branch: MAIN
Log Message:
Refactor and introduce new forms of update

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