private static long apply(DoubleBinaryOperator fn, long v, double x) { double d = Double.longBitsToDouble(v); d = (fn == null) ? d + x : fn.applyAsDouble(d, x); return Double.doubleToRawLongBits(d); }
/** * Returns the current value. The returned value is <em>NOT</em> * an atomic snapshot; invocation in the absence of concurrent * updates returns an accurate result, but concurrent updates that * occur while the value is being calculated might not be * incorporated. * * @return the current value */ public double get() { Cell[] cs = cells; double result = longBitsToDouble(base); if (cs != null) { for (Cell c : cs) { if (c != null) { result = function.applyAsDouble (result, longBitsToDouble(c.value)); } } } return result; }
/** * Equivalent in effect to {@link #get} followed by {@link * #reset}. This method may apply for example during quiescent * points between multithreaded computations. If there are * updates concurrent with this method, the returned value is * <em>not</em> guaranteed to be the final value occurring before * the reset. * * @return the value before reset */ public double getThenReset() { Cell[] cs = cells; double result = longBitsToDouble(getAndSetBase(identity)); if (cs != null) { for (Cell c : cs) { if (c != null) { double v = longBitsToDouble(c.getAndSet(identity)); result = function.applyAsDouble(result, v); } } } return result; }
/** * Updates with the given value. * * @param x the value */ public void accumulate(double x) { Cell[] cs; long b, v, r; int m; Cell c; if ((cs = cells) != null || ((r = doubleToRawLongBits (function.applyAsDouble(longBitsToDouble(b = base), x))) != b && !casBase(b, r))) { boolean uncontended = true; if (cs == null || (m = cs.length - 1) < 0 || (c = cs[getProbe() & m]) == null || !(uncontended = ((r = doubleToRawLongBits (function.applyAsDouble (longBitsToDouble(v = c.value), x))) == v) || c.cas(v, r))) doubleAccumulate(x, function, uncontended); } }
double lout = lt.out; rt.in = (l == org ? lout : fn.applyAsDouble(pin, lout)); for (int c;;) { if (((c = rt.getPendingCount()) & CUMULATE) != 0) a[i] = sum = fn.applyAsDouble(sum, a[i]); sum = fn.applyAsDouble(sum, a[i]); double lout = lt.out; par.out = (rt.hi == fnc ? lout : fn.applyAsDouble(lout, rt.out));
double lout = lt.out; rt.in = (l == org ? lout : fn.applyAsDouble(pin, lout)); for (int c;;) { if (((c = rt.getPendingCount()) & CUMULATE) != 0) a[i] = sum = fn.applyAsDouble(sum, a[i]); sum = fn.applyAsDouble(sum, a[i]); double lout = lt.out; par.out = (rt.hi == fnc ? lout : fn.applyAsDouble(lout, rt.out));