94 * @param accumulatorFunction a side-effect-free function of two arguments
95 * @param identity identity (initial value) for the accumulator function
96 */
97 public DoubleAccumulator(DoubleBinaryOperator accumulatorFunction,
98 double identity) {
99 this.function = accumulatorFunction;
100 base = this.identity = doubleToRawLongBits(identity);
101 }
102
103 /**
104 * Updates with the given value.
105 *
106 * @param x the value
107 */
108 public void accumulate(double x) {
109 Cell[] cs; long b, v, r; int m; Cell c;
110 if ((cs = cells) != null
111 || ((r = doubleToRawLongBits
112 (function.applyAsDouble(longBitsToDouble(b = base), x))) != b
113 && !casBase(b, r))) {
114 boolean uncontended = true;
115 if (cs == null
116 || (m = cs.length - 1) < 0
117 || (c = cs[getProbe() & m]) == null
118 || !(uncontended =
119 ((r = doubleToRawLongBits
120 (function.applyAsDouble
121 (longBitsToDouble(v = c.value), x))) == v)
122 || c.cas(v, r)))
123 doubleAccumulate(x, function, uncontended);
124 }
125 }
126
127 /**
128 * Returns the current value. The returned value is <em>NOT</em>
129 * an atomic snapshot; invocation in the absence of concurrent
130 * updates returns an accurate result, but concurrent updates that
131 * occur while the value is being calculated might not be
132 * incorporated.
133 *
134 * @return the current value
135 */
136 public double get() {
137 Cell[] cs = cells;
138 double result = longBitsToDouble(base);
139 if (cs != null) {
140 for (Cell c : cs)
141 if (c != null)
142 result = function.applyAsDouble
143 (result, longBitsToDouble(c.value));
|
94 * @param accumulatorFunction a side-effect-free function of two arguments
95 * @param identity identity (initial value) for the accumulator function
96 */
97 public DoubleAccumulator(DoubleBinaryOperator accumulatorFunction,
98 double identity) {
99 this.function = accumulatorFunction;
100 base = this.identity = doubleToRawLongBits(identity);
101 }
102
103 /**
104 * Updates with the given value.
105 *
106 * @param x the value
107 */
108 public void accumulate(double x) {
109 Cell[] cs; long b, v, r; int m; Cell c;
110 if ((cs = cells) != null
111 || ((r = doubleToRawLongBits
112 (function.applyAsDouble(longBitsToDouble(b = base), x))) != b
113 && !casBase(b, r))) {
114 int index = getProbe();
115 boolean uncontended = true;
116 if (cs == null
117 || (m = cs.length - 1) < 0
118 || (c = cs[index & m]) == null
119 || !(uncontended =
120 ((r = doubleToRawLongBits
121 (function.applyAsDouble
122 (longBitsToDouble(v = c.value), x))) == v)
123 || c.cas(v, r)))
124 doubleAccumulate(x, function, uncontended, index);
125 }
126 }
127
128 /**
129 * Returns the current value. The returned value is <em>NOT</em>
130 * an atomic snapshot; invocation in the absence of concurrent
131 * updates returns an accurate result, but concurrent updates that
132 * occur while the value is being calculated might not be
133 * incorporated.
134 *
135 * @return the current value
136 */
137 public double get() {
138 Cell[] cs = cells;
139 double result = longBitsToDouble(base);
140 if (cs != null) {
141 for (Cell c : cs)
142 if (c != null)
143 result = function.applyAsDouble
144 (result, longBitsToDouble(c.value));
|