public void Compute() { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final java.util.function.DoubleBinaryOperator fn; DoubleBinaryOperator fn; //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final double[] a; double[] a; if ((fn = this.Function) == null || (a = this.Array) == null) { throw new NullPointerException(); // hoist checks } int th = Threshold, org = Origin, fnc = Fence, l, h; DoubleCumulateTask t = this; while ((l = t.Lo) >= 0 && (h = t.Hi) <= a.Length) { if (h - l > th) { DoubleCumulateTask lt = t.Left, rt = t.Right, f; if (lt == null) // first pass { int mid = (int)((uint)(l + h) >> 1); f = rt = t.Right = new DoubleCumulateTask(t, fn, a, org, fnc, th, mid, h); t = lt = t.Left = new DoubleCumulateTask(t, fn, a, org, fnc, th, l, mid); } else // possibly refork { double pin = t.@in; lt.@in = pin; f = t = null; if (rt != null) { double lout = lt.@out; rt.@in = (l == org ? lout : fn.ApplyAsDouble(pin, lout)); for (int c;;) { if (((c = rt.PendingCount) & CUMULATE) != 0) { break; } if (rt.CompareAndSetPendingCount(c, c | CUMULATE)) { t = rt; break; } } } for (int c;;) { if (((c = lt.PendingCount) & CUMULATE) != 0) { break; } if (lt.CompareAndSetPendingCount(c, c | CUMULATE)) { if (t != null) { f = t; } t = lt; break; } } if (t == null) { break; } } if (f != null) { f.Fork(); } } else { int state; // Transition to sum, cumulate, or both for (int b;;) { if (((b = t.PendingCount) & FINISHED) != 0) { goto outerBreak; // already done } state = ((b & CUMULATE) != 0? FINISHED : (l > org) ? SUMMED : (SUMMED | FINISHED)); if (t.CompareAndSetPendingCount(b, b | state)) { break; } } double sum; if (state != SUMMED) { int first; if (l == org) // leftmost; no in { sum = a[org]; first = org + 1; } else { sum = t.@in; first = l; } for (int i = first; i < h; ++i) // cumulate { a[i] = sum = fn.ApplyAsDouble(sum, a[i]); } } else if (h < fnc) // skip rightmost { sum = a[l]; for (int i = l + 1; i < h; ++i) // sum only { sum = fn.ApplyAsDouble(sum, a[i]); } } else { sum = t.@in; } t.@out = sum; for (DoubleCumulateTask par;;) // propagate { if ((par = (DoubleCumulateTask)t.Completer) == null) { if ((state & FINISHED) != 0) // enable join { t.QuietlyComplete(); } goto outerBreak; } int b = par.PendingCount; if ((b & state & FINISHED) != 0) { t = par; // both done } else if ((b & state & SUMMED) != 0) // both summed { int nextState; DoubleCumulateTask lt, rt; if ((lt = par.left) != null && (rt = par.right) != null) { double lout = lt.@out; par.@out = (rt.Hi == fnc ? lout : fn.ApplyAsDouble(lout, rt.@out)); } int refork = (((b & CUMULATE) == 0 && par.lo == org) ? CUMULATE : 0); if ((nextState = b | state | refork) == b || par.compareAndSetPendingCount(b, nextState)) { state = SUMMED; // drop finished t = par; if (refork != 0) { par.fork(); } } } else if (par.compareAndSetPendingCount(b, b | state)) { goto outerBreak; // sib not ready } } } outerContinue :; } outerBreak :; }