/* * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at * http://creativecommons.org/publicdomain/zero/1.0/ */ package extra166y; import jsr166y.*; import static extra166y.Ops.*; import java.util.*; import java.util.concurrent.atomic.*; import java.lang.reflect.Array; /** * Abstract class serving as the basis of parallel * array classes across types. */ public abstract class AbstractParallelAnyArray { /* * This class and its subclasses (most of which are defined here * as nested static classes) maintain the execution parameters for * ParallelArray, ParallelDoubleArray, and ParallelLongArray * tasks. Pap instances hold the non-operation-specific control * and data accessors needed for a task as a whole (as opposed to * subtasks), and also house some of the leaf methods that perform * the actual array processing. The leaf methods are for the most * part just plain array operations. They are boringly repetitive * in order to flatten out and minimize inner-loop overhead, as * well as to minimize call-chain depth. This makes it more likely * that dynamic compilers can go the rest of the way, and hoist * per-element method call dispatch, so we have a good chance to * speed up processing via parallelism rather than lose due to * dispatch and indirection overhead. The dispatching from Pap to * FJ and back is otherwise Visitor-pattern-like, allowing the * basic parallelism control for most FJ tasks to be centralized. * * Note the extensive use of raw types. Arrays and generics do not * work together very well. It is more manageable to avoid them here, * and let the public classes perform casts in and out to the * processing here. Also note that the majority of code in concrete * classes is just for managing the various flavors created using * with* methods. * * Internal concrete classes are named using an * abbreviation scheme to avoid mile-long class names: * O, D, L for Object, Double, Long, for underlying Parallel array * U - unfiltered * F - filtered * R - relation-filtered (aka index-filtered) * OM, DM, LM - Mapped * OC, DC, LC - combiner-mapped (aka index-mapped) */ final ForkJoinPool ex; final int origin; int fence; int threshold; AbstractParallelAnyArray(ForkJoinPool ex, int origin, int fence) { this.ex = ex; this.origin = origin; this.fence = fence; } // A few public methods exported across all subclasses /** * Returns the number of elements selected using bound or * filter restrictions. Note that this method must evaluate * all selectors to return its result. * @return the number of elements */ public int size() { if (!hasFilter()) return fence - origin; PAS.FJCountSelected f = new PAS.FJCountSelected (this, origin, fence, null); ex.invoke(f); return f.count; } /** * Returns the index of some element matching bound and filter * constraints, or -1 if none. * @return index of matching element, or -1 if none */ public int anyIndex() { if (!hasFilter()) return (origin < fence) ? origin : -1; AtomicInteger result = new AtomicInteger(-1); PAS.FJSelectAny f = new PAS.FJSelectAny (this, origin, fence, null, result); ex.invoke(f); return result.get(); } /** * Returns true if there are no elements. * @return true if there are no elements */ public boolean isEmpty() { return anyIndex() < 0; } /** * Returns size threshold for splitting into subtask. By * default, uses about 8 times as many tasks as threads */ final int computeThreshold() { int n = fence - origin; int p = ex.getParallelism(); return threshold = (p > 1) ? (1 + n / (p << 3)) : n; } /** * Returns lazily computed threshold. */ final int getThreshold() { int t = threshold; if (t == 0) t = computeThreshold(); return t; } /** * Access methods for ref, double, long. Checking for * null/false return is used as a sort of type test. These * are used to avoid duplication in non-performance-critical * aspects of control, as well as to provide a simple default * mechanism for extensions. */ Object[] ogetArray() { return null; } double[] dgetArray() { return null; } long[] lgetArray() { return null; } abstract Object oget(int index); abstract double dget(int index); abstract long lget(int index); boolean hasMap() { return false; } boolean hasFilter() { return false; } boolean isSelected(int index) { return true; } /* * Leaf methods for FJ tasks. Default versions use isSelected, * oget, dget, etc. But most are overridden in most concrete * classes to avoid per-element dispatching. */ void leafApply(int lo, int hi, Procedure procedure) { for (int i = lo; i < hi; ++i) if (isSelected(i)) procedure.op(oget(i)); } void leafApply(int lo, int hi, DoubleProcedure procedure) { for (int i = lo; i < hi; ++i) if (isSelected(i)) procedure.op(dget(i)); } void leafApply(int lo, int hi, LongProcedure procedure) { for (int i = lo; i < hi; ++i) if (isSelected(i)) procedure.op(lget(i)); } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { boolean gotFirst = false; Object r = base; for (int i = lo; i < hi; ++i) { if (isSelected(i)) { Object x = oget(i); if (!gotFirst) { gotFirst = true; r = x; } else r = reducer.op(r, x); } } return r; } double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { boolean gotFirst = false; double r = base; for (int i = lo; i < hi; ++i) { if (isSelected(i)) { double x = dget(i); if (!gotFirst) { gotFirst = true; r = x; } else r = reducer.op(r, x); } } return r; } long leafReduce(int lo, int hi, LongReducer reducer, long base) { boolean gotFirst = false; long r = base; for (int i = lo; i < hi; ++i) { if (isSelected(i)) { long x = lget(i); if (!gotFirst) { gotFirst = true; r = x; } else r = reducer.op(r, x); } } return r; } // copy elements, ignoring selector, but applying mapping void leafTransfer(int lo, int hi, Object[] dest, int offset) { for (int i = lo; i < hi; ++i) dest[offset++] = oget(i); } void leafTransfer(int lo, int hi, double[] dest, int offset) { for (int i = lo; i < hi; ++i) dest[offset++] = dget(i); } void leafTransfer(int lo, int hi, long[] dest, int offset) { for (int i = lo; i < hi; ++i) dest[offset++] = lget(i); } // copy elements indexed in indices[loIdx..hiIdx], ignoring // selector, but applying mapping void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, Object[] dest, int offset) { for (int i = loIdx; i < hiIdx; ++i) dest[offset++] = oget(indices[i]); } void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, double[] dest, int offset) { for (int i = loIdx; i < hiIdx; ++i) dest[offset++] = dget(indices[i]); } void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, long[] dest, int offset) { for (int i = loIdx; i < hiIdx; ++i) dest[offset++] = lget(indices[i]); } // add indices of selected elements to index array; return #added final int leafIndexSelected(int lo, int hi, boolean positive, int[] indices) { int k = 0; for (int i = lo; i < hi; ++i) { if (isSelected(i) == positive) indices[lo + k++] = i; } return k; } // move selected elements to indices starting at offset, // return final offset abstract int leafMoveSelected(int lo, int hi, int offset, boolean positive); // move elements indexed by indices[loIdx...hiIdx] starting // at given offset abstract void leafMoveByIndex(int[] indices, int loIdx, int hiIdx, int offset); /** * Shared support for select/map all -- probe filter, map, and * type to start selection driver, or do parallel mapping, or * just copy. */ final Object[] allObjects(Class elementType) { if (hasFilter()) { if (elementType == null) { if (!hasMap()) elementType = ogetArray().getClass().getComponentType(); else elementType = Object.class; } PAS.FJOSelectAllDriver r = new PAS.FJOSelectAllDriver (this, elementType); ex.invoke(r); return r.results; } else { int n = fence - origin; Object[] dest; if (hasMap()) { if (elementType == null) dest = new Object[n]; else dest = (Object[])Array.newInstance(elementType, n); ex.invoke(new PAS.FJOMap(this, origin, fence, null, dest, -origin)); } else { Object[] array = ogetArray(); if (elementType == null) elementType = array.getClass().getComponentType(); dest = (Object[])Array.newInstance(elementType, n); System.arraycopy(array, origin, dest, 0, n); } return dest; } } final double[] allDoubles() { if (hasFilter()) { PAS.FJDSelectAllDriver r = new PAS.FJDSelectAllDriver(this); ex.invoke(r); return r.results; } else { int n = fence - origin; double[] dest = new double[n]; if (hasMap()) { ex.invoke(new PAS.FJDMap(this, origin, fence, null, dest, -origin)); } else { double[] array = dgetArray(); System.arraycopy(array, origin, dest, 0, n); } return dest; } } final long[] allLongs() { if (hasFilter()) { PAS.FJLSelectAllDriver r = new PAS.FJLSelectAllDriver(this); ex.invoke(r); return r.results; } else { int n = fence - origin; long[] dest = new long[n]; if (hasMap()) { ex.invoke(new PAS.FJLMap(this, origin, fence, null, dest, -origin)); } else { long[] array = lgetArray(); System.arraycopy(array, origin, dest, 0, n); } return dest; } } // Bounds check a range void boundsCheck(int lo, int hi) { if (lo > hi) throw new IllegalArgumentException(origin + " > " + fence); if (lo < 0) throw new ArrayIndexOutOfBoundsException(origin); if (hi - lo > this.fence - this.origin) throw new ArrayIndexOutOfBoundsException(fence); } /* * The following methods can be called only for classes * supporting in-place replacements (currently, those classes * without mappings). They are declared as no-ops here, and * overridden only where applicable. */ void leafTransform(int l, int h, Op op) {} void leafIndexMap(int l, int h, IntToObject op) {} void leafBinaryIndexMap(int l, int h, IntAndObjectToObject op) {} void leafGenerate(int l, int h, Generator generator) {} void leafFill(int l, int h, Object value) {} void leafCombineInPlace(int lo, int hi, Object[] other, int otherOffset, BinaryOp combiner) {} void leafCombineInPlace(int lo, int hi, ParallelArrayWithMapping other, int otherOffset, BinaryOp combiner) {} void leafTransform(int l, int h, DoubleOp op) {} void leafIndexMap(int l, int h, IntToDouble array) {} void leafBinaryIndexMap(int l, int h, IntAndDoubleToDouble op) {} void leafGenerate(int l, int h, DoubleGenerator generator) {} void leafFill(int l, int h, double value) {} void leafCombineInPlace(int lo, int hi, double[] other, int otherOffset, BinaryDoubleOp combiner) {} void leafCombineInPlace(int lo, int hi, ParallelDoubleArrayWithDoubleMapping other, int otherOffset, BinaryDoubleOp combiner) {} void leafTransform(int l, int h, LongOp op) {} void leafIndexMap(int l, int h, IntToLong array) {} void leafBinaryIndexMap(int l, int h, IntAndLongToLong op) {} void leafGenerate(int l, int h, LongGenerator generator) {} void leafFill(int l, int h, long value) {} void leafCombineInPlace(int lo, int hi, long[] other, int otherOffset, BinaryLongOp combiner) {} void leafCombineInPlace(int lo, int hi, ParallelLongArrayWithLongMapping other, int otherOffset, BinaryLongOp combiner) {} // Base of object ref array classes abstract static class OPap extends AbstractParallelAnyArray { T[] array; OPap(ForkJoinPool ex, int origin, int fence, T[] array) { super(ex, origin, fence); this.array = array; } final Object[] ogetArray() { return this.array; } double dget(int i) { return ((Number)oget(i)).doubleValue(); } long lget(int i) { return ((Number)oget(i)).longValue(); } final void leafMoveByIndex(int[] indices, int loIdx, int hiIdx, int offset) { final Object[] array = this.array; for (int i = loIdx; i < hiIdx; ++i) array[offset++] = array[indices[i]]; } final int leafMoveSelected(int lo, int hi, int offset, boolean positive) { final Object[] array = this.array; for (int i = lo; i < hi; ++i) { if (isSelected(i) == positive) array[offset++] = array[i]; } return offset; } } // Base of double array classes abstract static class DPap extends AbstractParallelAnyArray { double[] array; DPap(ForkJoinPool ex, int origin, int fence, double[] array) { super(ex, origin, fence); this.array = array; } final double[] dgetArray() { return this.array; } Object oget(int i) { return Double.valueOf(dget(i)); } long lget(int i) { return (long)(dget(i)); } final void leafMoveByIndex(int[] indices, int loIdx, int hiIdx, int offset) { final double[] array = this.array; for (int i = loIdx; i < hiIdx; ++i) array[offset++] = array[indices[i]]; } final int leafMoveSelected(int lo, int hi, int offset, boolean positive) { final double[] array = this.array; for (int i = lo; i < hi; ++i) { if (isSelected(i) == positive) array[offset++] = array[i]; } return offset; } } // Base of long array classes abstract static class LPap extends AbstractParallelAnyArray { long[] array; LPap(ForkJoinPool ex, int origin, int fence, long[] array) { super(ex, origin, fence); this.array = array; } final long[] lgetArray() { return this.array; } Object oget(int i) { return Long.valueOf(lget(i)); } double dget(int i) { return (double)(lget(i)); } final void leafMoveByIndex(int[] indices, int loIdx, int hiIdx, int offset) { final long[] array = this.array; for (int i = loIdx; i < hiIdx; ++i) array[offset++] = array[indices[i]]; } final int leafMoveSelected(int lo, int hi, int offset, boolean positive) { final long[] array = this.array; for (int i = lo; i < hi; ++i) { if (isSelected(i) == positive) array[offset++] = array[i]; } return offset; } } // Plain (unfiltered, unmapped) classes static class OUPap extends ParallelArrayWithBounds { OUPap(ForkJoinPool ex, int origin, int fence, T[] array) { super(ex, origin, fence, array); } public ParallelArrayWithBounds withBounds(int lo, int hi) { boundsCheck(lo, hi); return new OUPap(ex, origin + lo, origin + hi, array); } public ParallelArrayWithFilter withFilter (Predicate selector) { return new OFPap(ex, origin, fence, array, selector); } public ParallelArrayWithFilter withIndexedFilter (IntAndObjectPredicate selector) { return new ORPap(ex, origin, fence, array, selector); } public ParallelArrayWithMapping withMapping (Op op) { return new OUOMPap(ex, origin, fence, array, op); } public ParallelArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new OUDMPap(ex, origin, fence, array, op); } public ParallelArrayWithLongMapping withMapping (ObjectToLong op) { return new OULMPap(ex, origin, fence, array, op); } public ParallelArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new OUOCPap(ex, origin, fence, array, mapper); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new OUDCPap(ex, origin, fence, array, mapper); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new OULCPap(ex, origin, fence, array, mapper); } public int indexOf(T target) { AtomicInteger result = new AtomicInteger(-1); PAS.FJOIndexOf f = new PAS.FJOIndexOf (this, origin, fence, null, result, target); ex.invoke(f); return result.get(); } public int binarySearch(T target) { final Object[] a = this.array; int lo = origin; int hi = fence - 1; while (lo <= hi) { int mid = (lo + hi) >>> 1; int c = ((Comparable)target).compareTo((Comparable)a[mid]); if (c == 0) return mid; else if (c < 0) hi = mid - 1; else lo = mid + 1; } return -1; } public int binarySearch(T target, Comparator comparator) { Comparator cmp = comparator; final Object[] a = this.array; int lo = origin; int hi = fence - 1; while (lo <= hi) { int mid = (lo + hi) >>> 1; int c = cmp.compare(target, a[mid]); if (c == 0) return mid; else if (c < 0) hi = mid - 1; else lo = mid + 1; } return -1; } public ParallelArrayWithBounds cumulate(Reducer reducer, T base) { PAS.FJOCumulateOp op = new PAS.FJOCumulateOp(this, reducer, base); PAS.FJOScan r = new PAS.FJOScan(null, op, origin, fence); ex.invoke(r); return this; } public T precumulate(Reducer reducer, T base) { PAS.FJOPrecumulateOp op = new PAS.FJOPrecumulateOp (this, reducer, base); PAS.FJOScan r = new PAS.FJOScan(null, op, origin, fence); ex.invoke(r); return (T)(r.out); } public ParallelArrayWithBounds sort (Comparator cmp) { final Object[] a = this.array; Class tc = array.getClass().getComponentType(); T[] ws = (T[])Array.newInstance(tc, fence); ex.invoke(new PAS.FJOSorter (cmp, array, ws, origin, fence - origin, getThreshold())); return this; } public ParallelArrayWithBounds sort() { final Object[] a = this.array; Class tc = array.getClass().getComponentType(); if (!Comparable.class.isAssignableFrom(tc)) { sort(CommonOps.castedComparator()); } else { Comparable[] ca = (Comparable[])array; Comparable[] ws = (Comparable[])Array.newInstance(tc, fence); ex.invoke(new PAS.FJOCSorter (ca, ws, origin, fence - origin, getThreshold())); } return this; } final void leafApply(int lo, int hi, Procedure procedure) { final Object[] a = this.array; for (int i = lo; i < hi; ++i) procedure.op(a[i]); } final Object leafReduce(int lo, int hi, Reducer reducer, Object base) { if (lo >= hi) return base; final Object[] a = this.array; Object r = a[lo]; for (int i = lo+1; i < hi; ++i) r = reducer.op(r, a[i]); return r; } final void leafTransform(int l, int h, Op op) { final Object[] a = this.array; for (int i = l; i < h; ++i) a[i] = op.op(a[i]); } final void leafIndexMap(int l, int h, IntToObject op) { final Object[] a = this.array; for (int i = l; i < h; ++i) a[i] = op.op(i); } final void leafBinaryIndexMap(int l, int h, IntAndObjectToObject op) { final Object[] a = this.array; for (int i = l; i < h; ++i) a[i] = op.op(i, a[i]); } final void leafGenerate(int l, int h, Generator generator) { final Object[] a = this.array; for (int i = l; i < h; ++i) a[i] = generator.op(); } final void leafFill(int l, int h, Object value) { final Object[] a = this.array; for (int i = l; i < h; ++i) a[i] = value; } final void leafCombineInPlace(int l, int h, Object[] other, int otherOffset, BinaryOp combiner) { final Object[] a = this.array; int k = l + otherOffset; for (int i = l; i < h; ++i) a[i] = combiner.op(a[i], other[k++]); } final void leafCombineInPlace(int l, int h, ParallelArrayWithMapping other, int otherOffset, BinaryOp combiner) { final Object[] a = this.array; int k = l + otherOffset; if (other.hasFilter()) { for (int i = l; i < h; ++i) { if (other.isSelected(k)) a[i] = combiner.op(a[i], other.oget(k)); k++; } } else if (other.hasMap()) { for (int i = l; i < h; ++i) a[i] = combiner.op(a[i], other.oget(k++)); } else { Object[] b = other.array; for (int i = l; i < h; ++i) a[i] = combiner.op(a[i], b[k++]); } } } static class DUPap extends ParallelDoubleArrayWithBounds { DUPap(ForkJoinPool ex, int origin, int fence, double[] array) { super(ex, origin, fence, array); } public ParallelDoubleArrayWithBounds withBounds(int lo, int hi) { boundsCheck(lo, hi); return new DUPap(ex, origin + lo, origin + hi, array); } public ParallelDoubleArrayWithFilter withFilter(DoublePredicate selector) { return new DFPap(ex, origin, fence, array, selector); } public ParallelDoubleArrayWithFilter withIndexedFilter (IntAndDoublePredicate selector) { return new DRPap(ex, origin, fence, array, selector); } public ParallelDoubleArrayWithMapping withMapping (DoubleToObject op) { return new DUOMPap(ex, origin, fence, array, op); } public ParallelDoubleArrayWithDoubleMapping withMapping(DoubleOp op) { return new DUDMPap(ex, origin, fence, array, op); } public ParallelDoubleArrayWithLongMapping withMapping(DoubleToLong op) { return new DULMPap(ex, origin, fence, array, op); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new DUOCPap(ex, origin, fence, array, mapper); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new DUDCPap(ex, origin, fence, array, mapper); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new DULCPap(ex, origin, fence, array, mapper); } public int indexOf(double target) { AtomicInteger result = new AtomicInteger(-1); PAS.FJDIndexOf f = new PAS.FJDIndexOf (this, origin, fence, null, result, target); ex.invoke(f); return result.get(); } public int binarySearch(double target) { final double[] a = this.array; int lo = origin; int hi = fence - 1; while (lo <= hi) { int mid = (lo + hi) >>> 1; double m = a[mid]; if (target == m) return mid; else if (target < m) hi = mid - 1; else lo = mid + 1; } return -1; } public int binarySearch(double target, DoubleComparator comparator) { final double[] a = this.array; int lo = origin; int hi = fence - 1; while (lo <= hi) { int mid = (lo + hi) >>> 1; int c = comparator.compare(target, a[mid]); if (c == 0) return mid; else if (c < 0) hi = mid - 1; else lo = mid + 1; } return -1; } public ParallelDoubleArrayWithBounds cumulate(DoubleReducer reducer, double base) { PAS.FJDCumulateOp op = new PAS.FJDCumulateOp(this, reducer, base); PAS.FJDScan r = new PAS.FJDScan(null, op, origin, fence); ex.invoke(r); return this; } public ParallelDoubleArrayWithBounds cumulateSum() { PAS.FJDCumulatePlusOp op = new PAS.FJDCumulatePlusOp(this); PAS.FJDScan r = new PAS.FJDScan(null, op, origin, fence); ex.invoke(r); return this; } public double precumulate(DoubleReducer reducer, double base) { PAS.FJDPrecumulateOp op = new PAS.FJDPrecumulateOp(this, reducer, base); PAS.FJDScan r = new PAS.FJDScan(null, op, origin, fence); ex.invoke(r); return r.out; } public double precumulateSum() { PAS.FJDPrecumulatePlusOp op = new PAS.FJDPrecumulatePlusOp(this); PAS.FJDScan r = new PAS.FJDScan(null, op, origin, fence); ex.invoke(r); return r.out; } public ParallelDoubleArrayWithBounds sort(DoubleComparator cmp) { ex.invoke(new PAS.FJDSorter (cmp, this.array, new double[fence], origin, fence - origin, getThreshold())); return this; } public ParallelDoubleArrayWithBounds sort() { ex.invoke(new PAS.FJDCSorter (this.array, new double[fence], origin, fence - origin, getThreshold())); return this; } final void leafApply(int lo, int hi, DoubleProcedure procedure) { final double[] a = this.array; for (int i = lo; i < hi; ++i) procedure.op(a[i]); } final double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { if (lo >= hi) return base; final double[] a = this.array; double r = a[lo]; for (int i = lo+1; i < hi; ++i) r = reducer.op(r, a[i]); return r; } final void leafTransform(int l, int h, DoubleOp op) { final double[] a = this.array; for (int i = l; i < h; ++i) a[i] = op.op(a[i]); } final void leafIndexMap(int l, int h, IntToDouble op) { final double[] a = this.array; for (int i = l; i < h; ++i) a[i] = op.op(i); } final void leafBinaryIndexMap(int l, int h, IntAndDoubleToDouble op) { final double[] a = this.array; for (int i = l; i < h; ++i) a[i] = op.op(i, a[i]); } final void leafGenerate(int l, int h, DoubleGenerator generator) { final double[] a = this.array; for (int i = l; i < h; ++i) a[i] = generator.op(); } final void leafFill(int l, int h, double value) { final double[] a = this.array; for (int i = l; i < h; ++i) a[i] = value; } final void leafCombineInPlace (int l, int h, double[] other, int otherOffset, BinaryDoubleOp combiner) { final double[] a = this.array; int k = l + otherOffset; for (int i = l; i < h; ++i) a[i] = combiner.op(a[i], other[k++]); } final void leafCombineInPlace (int l, int h, ParallelDoubleArrayWithDoubleMapping other, int otherOffset, BinaryDoubleOp combiner) { final double[] a = this.array; int k = l + otherOffset; if (other.hasFilter()) { for (int i = l; i < h; ++i) { if (other.isSelected(k)) a[i] = combiner.op(a[i], other.dget(k)); k++; } } else if (other.hasMap()) { for (int i = l; i < h; ++i) a[i] = combiner.op(a[i], other.dget(k++)); } else { double[] b = other.array; for (int i = l; i < h; ++i) a[i] = combiner.op(a[i], b[k++]); } } } static class LUPap extends ParallelLongArrayWithBounds { LUPap(ForkJoinPool ex, int origin, int fence, long[] array) { super(ex, origin, fence, array); } public ParallelLongArrayWithBounds withBounds(int lo, int hi) { boundsCheck(lo, hi); return new LUPap(ex, origin + lo, origin + hi, array); } public ParallelLongArrayWithFilter withFilter(LongPredicate selector) { return new LFPap(ex, origin, fence, array, selector); } public ParallelLongArrayWithFilter withIndexedFilter (IntAndLongPredicate selector) { return new LRPap(ex, origin, fence, array, selector); } public ParallelLongArrayWithMapping withMapping (LongToObject op) { return new LUOMPap(ex, origin, fence, array, op); } public ParallelLongArrayWithLongMapping withMapping(LongOp op) { return new LULMPap(ex, origin, fence, array, op); } public ParallelLongArrayWithDoubleMapping withMapping(LongToDouble op) { return new LUDMPap(ex, origin, fence, array, op); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new LUOCPap(ex, origin, fence, array, mapper); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new LUDCPap(ex, origin, fence, array, mapper); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new LULCPap(ex, origin, fence, array, mapper); } public int indexOf(long target) { AtomicInteger result = new AtomicInteger(-1); PAS.FJLIndexOf f = new PAS.FJLIndexOf (this, origin, fence, null, result, target); ex.invoke(f); return result.get(); } public int binarySearch(long target) { final long[] a = this.array; int lo = origin; int hi = fence - 1; while (lo <= hi) { int mid = (lo + hi) >>> 1; long m = a[mid]; if (target == m) return mid; else if (target < m) hi = mid - 1; else lo = mid + 1; } return -1; } public int binarySearch(long target, LongComparator comparator) { final long[] a = this.array; int lo = origin; int hi = fence - 1; while (lo <= hi) { int mid = (lo + hi) >>> 1; int c = comparator.compare(target, a[mid]); if (c == 0) return mid; else if (c < 0) hi = mid - 1; else lo = mid + 1; } return -1; } public ParallelLongArrayWithBounds cumulate(LongReducer reducer, long base) { PAS.FJLCumulateOp op = new PAS.FJLCumulateOp(this, reducer, base); PAS.FJLScan r = new PAS.FJLScan(null, op, origin, fence); ex.invoke(r); return this; } public ParallelLongArrayWithBounds cumulateSum() { PAS.FJLCumulatePlusOp op = new PAS.FJLCumulatePlusOp(this); PAS.FJLScan r = new PAS.FJLScan(null, op, origin, fence); ex.invoke(r); return this; } public long precumulate(LongReducer reducer, long base) { PAS.FJLPrecumulateOp op = new PAS.FJLPrecumulateOp (this, reducer, base); PAS.FJLScan r = new PAS.FJLScan(null, op, origin, fence); ex.invoke(r); return r.out; } public long precumulateSum() { PAS.FJLPrecumulatePlusOp op = new PAS.FJLPrecumulatePlusOp(this); PAS.FJLScan r = new PAS.FJLScan(null, op, origin, fence); ex.invoke(r); return r.out; } public ParallelLongArrayWithBounds sort(LongComparator cmp) { ex.invoke(new PAS.FJLSorter (cmp, this.array, new long[fence], origin, fence - origin, getThreshold())); return this; } public ParallelLongArrayWithBounds sort() { ex.invoke(new PAS.FJLCSorter (this.array, new long[fence], origin, fence - origin, getThreshold())); return this; } final void leafApply(int lo, int hi, LongProcedure procedure) { final long[] a = this.array; for (int i = lo; i < hi; ++i) procedure.op(a[i]); } final long leafReduce(int lo, int hi, LongReducer reducer, long base) { if (lo >= hi) return base; final long[] a = this.array; long r = a[lo]; for (int i = lo+1; i < hi; ++i) r = reducer.op(r, a[i]); return r; } final void leafTransform(int l, int h, LongOp op) { final long[] a = this.array; for (int i = l; i < h; ++i) a[i] = op.op(a[i]); } final void leafIndexMap(int l, int h, IntToLong op) { final long[] a = this.array; for (int i = l; i < h; ++i) a[i] = op.op(i); } final void leafBinaryIndexMap(int l, int h, IntAndLongToLong op) { final long[] a = this.array; for (int i = l; i < h; ++i) a[i] = op.op(i, a[i]); } final void leafGenerate(int l, int h, LongGenerator generator) { final long[] a = this.array; for (int i = l; i < h; ++i) a[i] = generator.op(); } final void leafFill(int l, int h, long value) { final long[] a = this.array; for (int i = l; i < h; ++i) a[i] = value; } final void leafCombineInPlace (int l, int h, long[] other, int otherOffset, BinaryLongOp combiner) { final long[] a = this.array; int k = l + otherOffset; for (int i = l; i < h; ++i) a[i] = combiner.op(a[i], other[k++]); } final void leafCombineInPlace (int l, int h, ParallelLongArrayWithLongMapping other, int otherOffset, BinaryLongOp combiner) { final long[] a = this.array; int k = l + otherOffset; if (other.hasFilter()) { for (int i = l; i < h; ++i) { if (other.isSelected(k)) a[i] = combiner.op(a[i], other.lget(k)); k++; } } else if (other.hasMap()) { for (int i = l; i < h; ++i) a[i] = combiner.op(a[i], other.lget(k++)); } else { long[] b = other.array; for (int i = l; i < h; ++i) a[i] = combiner.op(a[i], b[k++]); } } } static final class AndPredicate implements Predicate { final Predicate first; final Predicate second; AndPredicate(Predicate first, Predicate second) { this.first = first; this.second = second; } public final boolean op(T x) { return first.op(x) && second.op(x); } } // Filtered (but unmapped) classes static final class OFPap extends ParallelArrayWithFilter { final Predicate selector; OFPap(ForkJoinPool ex, int origin, int fence, T[] array, Predicate selector) { super(ex, origin, fence, array); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelArrayWithFilter withFilter (Predicate selector) { return new OFPap(ex, origin, fence, array, new AndPredicate(this.selector, selector)); } public ParallelArrayWithFilter withIndexedFilter (IntAndObjectPredicate selector) { return new ORPap (ex, origin, fence, array, compoundIndexedSelector(this.selector, selector)); } public ParallelArrayWithMapping withMapping (Op op) { return new OFOMPap(ex, origin, fence, array, selector, op); } public ParallelArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new OFDMPap(ex, origin, fence, array, selector, op); } public ParallelArrayWithLongMapping withMapping (ObjectToLong op) { return new OFLMPap(ex, origin, fence, array, selector, op); } public ParallelArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new OFOCPap(ex, origin, fence, array, selector, mapper); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new OFDCPap(ex, origin, fence, array, selector, mapper); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new OFLCPap(ex, origin, fence, array, selector, mapper); } void leafApply(int lo, int hi, Procedure procedure) { final Predicate s = selector; final Object[] a = this.array; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(x)) procedure.op(x); } } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { final Predicate s = selector; boolean gotFirst = false; Object r = base; final Object[] a = this.array; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(x)) { if (!gotFirst) { gotFirst = true; r = x; } else r = reducer.op(r, x); } } return r; } final void leafTransform(int l, int h, Op op) { final Object[] a = this.array; final Predicate s = selector; for (int i = l; i < h; ++i) { Object x = a[i]; if (s.op(x)) a[i] = op.op(x); } } final void leafIndexMap(int l, int h, IntToObject op) { final Object[] a = this.array; final Predicate s = selector; for (int i = l; i < h; ++i) { Object x = a[i]; if (s.op(x)) a[i] = op.op(i); } } final void leafBinaryIndexMap(int l, int h, IntAndObjectToObject op) { final Object[] a = this.array; final Predicate s = selector; for (int i = l; i < h; ++i) { Object x = a[i]; if (s.op(x)) a[i] = op.op(i, x); } } final void leafGenerate(int l, int h, Generator generator) { final Object[] a = this.array; final Predicate s = selector; for (int i = l; i < h; ++i) { if (s.op(a[i])) a[i] = generator.op(); } } final void leafFill(int l, int h, Object value) { final Object[] a = this.array; final Predicate s = selector; for (int i = l; i < h; ++i) { if (s.op(a[i])) a[i] = value; } } final void leafCombineInPlace (int l, int h, Object[] other, int otherOffset, BinaryOp combiner) { final Object[] a = this.array; final Predicate s = selector; int k = l + otherOffset; for (int i = l; i < h; ++i) { Object x = a[i]; if (s.op(x)) a[i] = combiner.op(x, other[k]); k++; } } final void leafCombineInPlace (int l, int h, ParallelArrayWithMapping other, int otherOffset, BinaryOp combiner) { final Object[] a = this.array; final Predicate s = selector; int k = l + otherOffset; if (other.hasFilter()) { for (int i = l; i < h; ++i) { Object x = a[i]; if (s.op(x) && other.isSelected(k)) a[i] = combiner.op(x, other.oget(k)); k++; } } else if (other.hasMap()) { for (int i = l; i < h; ++i) { Object x = a[i]; if (s.op(x)) a[i] = combiner.op(x, other.oget(k)); k++; } } else { Object[] b = other.array; for (int i = l; i < h; ++i) { Object x = a[i]; if (s.op(x)) a[i] = combiner.op(x, b[k]); k++; } } } } static final class DFPap extends ParallelDoubleArrayWithFilter { final DoublePredicate selector; DFPap(ForkJoinPool ex, int origin, int fence, double[] array, DoublePredicate selector) { super(ex, origin, fence, array); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelDoubleArrayWithFilter withFilter(DoublePredicate selector) { return new DFPap(ex, origin, fence, array, CommonOps.andPredicate(this.selector, selector)); } public ParallelDoubleArrayWithFilter withIndexedFilter (IntAndDoublePredicate selector) { return new DRPap (ex, origin, fence, array, compoundIndexedSelector(this.selector, selector)); } public ParallelDoubleArrayWithMapping withMapping (DoubleToObject op) { return new DFOMPap(ex, origin, fence, array, selector, op); } public ParallelDoubleArrayWithDoubleMapping withMapping(DoubleOp op) { return new DFDMPap(ex, origin, fence, array, selector, op); } public ParallelDoubleArrayWithLongMapping withMapping(DoubleToLong op) { return new DFLMPap(ex, origin, fence, array, selector, op); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new DFOCPap(ex, origin, fence, array, selector, mapper); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new DFDCPap(ex, origin, fence, array, selector, mapper); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new DFLCPap(ex, origin, fence, array, selector, mapper); } final void leafApply(int lo, int hi, DoubleProcedure procedure) { final DoublePredicate s = selector; final double[] a = this.array; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(x)) procedure.op(x); } } final double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { final DoublePredicate s = selector; boolean gotFirst = false; double r = base; final double[] a = this.array; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(x)) { if (!gotFirst) { gotFirst = true; r = x; } else r = reducer.op(r, x); } } return r; } final void leafTransform(int l, int h, DoubleOp op) { final double[] a = this.array; final DoublePredicate s = selector; for (int i = l; i < h; ++i) { double x = a[i]; if (s.op(x)) a[i] = op.op(x); } } final void leafIndexMap(int l, int h, IntToDouble op) { final double[] a = this.array; final DoublePredicate s = selector; for (int i = l; i < h; ++i) { double x = a[i]; if (s.op(x)) a[i] = op.op(i); } } final void leafBinaryIndexMap(int l, int h, IntAndDoubleToDouble op) { final double[] a = this.array; final DoublePredicate s = selector; for (int i = l; i < h; ++i) { double x = a[i]; if (s.op(x)) a[i] = op.op(i, x); } } final void leafGenerate(int l, int h, DoubleGenerator generator) { final double[] a = this.array; final DoublePredicate s = selector; for (int i = l; i < h; ++i) { if (s.op(a[i])) a[i] = generator.op(); } } final void leafFill(int l, int h, double value) { final double[] a = this.array; final DoublePredicate s = selector; for (int i = l; i < h; ++i) { if (s.op(a[i])) a[i] = value; } } final void leafCombineInPlace (int l, int h, double[] other, int otherOffset, BinaryDoubleOp combiner) { final double[] a = this.array; final DoublePredicate s = selector; int k = l + otherOffset; for (int i = l; i < h; ++i) { double x = a[i]; if (s.op(x)) a[i] = combiner.op(x, other[k]); k++; } } final void leafCombineInPlace (int l, int h, ParallelDoubleArrayWithDoubleMapping other, int otherOffset, BinaryDoubleOp combiner) { final double[] a = this.array; final DoublePredicate s = selector; int k = l + otherOffset; if (other.hasFilter()) { for (int i = l; i < h; ++i) { double x = a[i]; if (s.op(x) && other.isSelected(k)) a[i] = combiner.op(x, other.dget(k)); k++; } } else if (other.hasMap()) { for (int i = l; i < h; ++i) { double x = a[i]; if (s.op(x)) a[i] = combiner.op(x, other.dget(k)); k++; } } else { double[] b = other.array; for (int i = l; i < h; ++i) { double x = a[i]; if (s.op(x)) a[i] = combiner.op(x, b[k]); k++; } } } } static final class LFPap extends ParallelLongArrayWithFilter { final LongPredicate selector; LFPap(ForkJoinPool ex, int origin, int fence, long[] array, LongPredicate selector) { super(ex, origin, fence, array); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelLongArrayWithFilter withFilter(LongPredicate selector) { return new LFPap(ex, origin, fence, array, CommonOps.andPredicate(this.selector, selector)); } public ParallelLongArrayWithFilter withIndexedFilter (IntAndLongPredicate selector) { return new LRPap (ex, origin, fence, array, compoundIndexedSelector(this.selector, selector)); } public ParallelLongArrayWithMapping withMapping (LongToObject op) { return new LFOMPap(ex, origin, fence, array, selector, op); } public ParallelLongArrayWithLongMapping withMapping (LongOp op) { return new LFLMPap(ex, origin, fence, array, selector, op); } public ParallelLongArrayWithDoubleMapping withMapping (LongToDouble op) { return new LFDMPap(ex, origin, fence, array, selector, op); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new LFOCPap(ex, origin, fence, array, selector, mapper); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new LFDCPap(ex, origin, fence, array, selector, mapper); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new LFLCPap(ex, origin, fence, array, selector, mapper); } final void leafApply(int lo, int hi, LongProcedure procedure) { final LongPredicate s = selector; final long[] a = this.array; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(x)) procedure.op(x); } } final long leafReduce(int lo, int hi, LongReducer reducer, long base) { final LongPredicate s = selector; boolean gotFirst = false; long r = base; final long[] a = this.array; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(x)) { if (!gotFirst) { gotFirst = true; r = x; } else r = reducer.op(r, x); } } return r; } final void leafTransform(int l, int h, LongOp op) { final long[] a = this.array; final LongPredicate s = selector; for (int i = l; i < h; ++i) { long x = a[i]; if (s.op(x)) a[i] = op.op(x); } } final void leafIndexMap(int l, int h, IntToLong op) { final long[] a = this.array; final LongPredicate s = selector; for (int i = l; i < h; ++i) { long x = a[i]; if (s.op(x)) a[i] = op.op(i); } } final void leafBinaryIndexMap(int l, int h, IntAndLongToLong op) { final long[] a = this.array; final LongPredicate s = selector; for (int i = l; i < h; ++i) { long x = a[i]; if (s.op(x)) a[i] = op.op(i, x); } } final void leafGenerate(int l, int h, LongGenerator generator) { final long[] a = this.array; final LongPredicate s = selector; for (int i = l; i < h; ++i) { if (s.op(a[i])) a[i] = generator.op(); } } final void leafFill(int l, int h, long value) { final long[] a = this.array; final LongPredicate s = selector; for (int i = l; i < h; ++i) { if (s.op(a[i])) a[i] = value; } } final void leafCombineInPlace (int l, int h, long[] other, int otherOffset, BinaryLongOp combiner) { final long[] a = this.array; final LongPredicate s = selector; int k = l + otherOffset; for (int i = l; i < h; ++i) { long x = a[i]; if (s.op(x)) a[i] = combiner.op(x, other[k]); k++; } } final void leafCombineInPlace (int l, int h, ParallelLongArrayWithLongMapping other, int otherOffset, BinaryLongOp combiner) { final long[] a = this.array; final LongPredicate s = selector; int k = l + otherOffset; if (other.hasFilter()) { for (int i = l; i < h; ++i) { long x = a[i]; if (s.op(x) && other.isSelected(k)) a[i] = combiner.op(x, other.lget(k)); k++; } } else if (other.hasMap()) { for (int i = l; i < h; ++i) { long x = a[i]; if (s.op(x)) a[i] = combiner.op(x, other.lget(k)); k++; } } else { long[] b = other.array; for (int i = l; i < h; ++i) { long x = a[i]; if (s.op(x)) a[i] = combiner.op(x, b[k]); k++; } } } } // Relationally Filtered (but unmapped) classes static final class ORPap extends ParallelArrayWithFilter { final IntAndObjectPredicate selector; ORPap(ForkJoinPool ex, int origin, int fence, T[] array, IntAndObjectPredicate selector) { super(ex, origin, fence, array); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelArrayWithFilter withFilter (Predicate selector) { return new ORPap (ex, origin, fence, array, compoundIndexedSelector(this.selector, selector)); } public ParallelArrayWithFilter withIndexedFilter (IntAndObjectPredicate selector) { return new ORPap (ex, origin, fence, array, compoundIndexedSelector(this.selector, selector)); } public ParallelArrayWithMapping withMapping (Op op) { return new OROMPap(ex, origin, fence, array, selector, op); } public ParallelArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new ORDMPap(ex, origin, fence, array, selector, op); } public ParallelArrayWithLongMapping withMapping (ObjectToLong op) { return new ORLMPap(ex, origin, fence, array, selector, op); } public ParallelArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new OROCPap(ex, origin, fence, array, selector, mapper); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new ORDCPap(ex, origin, fence, array, selector, mapper); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new ORLCPap(ex, origin, fence, array, selector, mapper); } void leafApply(int lo, int hi, Procedure procedure) { final IntAndObjectPredicate s = selector; final Object[] a = this.array; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(i, x)) procedure.op(x); } } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { final IntAndObjectPredicate s = selector; boolean gotFirst = false; Object r = base; final Object[] a = this.array; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(i, x)) { if (!gotFirst) { gotFirst = true; r = x; } else r = reducer.op(r, x); } } return r; } final void leafTransform(int l, int h, Op op) { final Object[] a = this.array; final IntAndObjectPredicate s = selector; for (int i = l; i < h; ++i) { Object x = a[i]; if (s.op(i, x)) a[i] = op.op(x); } } final void leafIndexMap(int l, int h, IntToObject op) { final Object[] a = this.array; final IntAndObjectPredicate s = selector; for (int i = l; i < h; ++i) { Object x = a[i]; if (s.op(i, x)) a[i] = op.op(i); } } final void leafBinaryIndexMap(int l, int h, IntAndObjectToObject op) { final Object[] a = this.array; final IntAndObjectPredicate s = selector; for (int i = l; i < h; ++i) { Object x = a[i]; if (s.op(i, x)) a[i] = op.op(i, x); } } final void leafGenerate(int l, int h, Generator generator) { final Object[] a = this.array; final IntAndObjectPredicate s = selector; for (int i = l; i < h; ++i) { if (s.op(i, a[i])) a[i] = generator.op(); } } final void leafFill(int l, int h, Object value) { final Object[] a = this.array; final IntAndObjectPredicate s = selector; for (int i = l; i < h; ++i) { if (s.op(i, a[i])) a[i] = value; } } final void leafCombineInPlace (int l, int h, Object[] other, int otherOffset, BinaryOp combiner) { final Object[] a = this.array; final IntAndObjectPredicate s = selector; int k = l + otherOffset; for (int i = l; i < h; ++i) { Object x = a[i]; if (s.op(i, x)) a[i] = combiner.op(x, other[k]); k++; } } final void leafCombineInPlace (int l, int h, ParallelArrayWithMapping other, int otherOffset, BinaryOp combiner) { final Object[] a = this.array; final IntAndObjectPredicate s = selector; int k = l + otherOffset; if (other.hasFilter()) { for (int i = l; i < h; ++i) { Object x = a[i]; if (s.op(i, x) && other.isSelected(k)) a[i] = combiner.op(x, other.oget(k)); k++; } } else if (other.hasMap()) { for (int i = l; i < h; ++i) { Object x = a[i]; if (s.op(i, x)) a[i] = combiner.op(x, other.oget(k)); k++; } } else { Object[] b = other.array; for (int i = l; i < h; ++i) { Object x = a[i]; if (s.op(i, x)) a[i] = combiner.op(x, b[k]); k++; } } } } static final class DRPap extends ParallelDoubleArrayWithFilter { final IntAndDoublePredicate selector; DRPap(ForkJoinPool ex, int origin, int fence, double[] array, IntAndDoublePredicate selector) { super(ex, origin, fence, array); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelDoubleArrayWithFilter withFilter (DoublePredicate selector) { return new DRPap (ex, origin, fence, array, compoundIndexedSelector(this.selector, selector)); } public ParallelDoubleArrayWithFilter withIndexedFilter (IntAndDoublePredicate selector) { return new DRPap (ex, origin, fence, array, compoundIndexedSelector(this.selector, selector)); } public ParallelDoubleArrayWithMapping withMapping (DoubleToObject op) { return new DROMPap(ex, origin, fence, array, selector, op); } public ParallelDoubleArrayWithDoubleMapping withMapping(DoubleOp op) { return new DRDMPap(ex, origin, fence, array, selector, op); } public ParallelDoubleArrayWithLongMapping withMapping(DoubleToLong op) { return new DRLMPap(ex, origin, fence, array, selector, op); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new DROCPap(ex, origin, fence, array, selector, mapper); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new DRDCPap(ex, origin, fence, array, selector, mapper); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new DRLCPap(ex, origin, fence, array, selector, mapper); } final void leafApply(int lo, int hi, DoubleProcedure procedure) { final IntAndDoublePredicate s = selector; final double[] a = this.array; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(i, x)) procedure.op(x); } } final double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { final IntAndDoublePredicate s = selector; boolean gotFirst = false; double r = base; final double[] a = this.array; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(i, x)) { if (!gotFirst) { gotFirst = true; r = x; } else r = reducer.op(r, x); } } return r; } final void leafTransform(int l, int h, DoubleOp op) { final double[] a = this.array; final IntAndDoublePredicate s = selector; for (int i = l; i < h; ++i) { double x = a[i]; if (s.op(i, x)) a[i] = op.op(x); } } final void leafIndexMap(int l, int h, IntToDouble op) { final double[] a = this.array; final IntAndDoublePredicate s = selector; for (int i = l; i < h; ++i) { double x = a[i]; if (s.op(i, x)) a[i] = op.op(i); } } final void leafBinaryIndexMap(int l, int h, IntAndDoubleToDouble op) { final double[] a = this.array; final IntAndDoublePredicate s = selector; for (int i = l; i < h; ++i) { double x = a[i]; if (s.op(i, x)) a[i] = op.op(i, x); } } final void leafGenerate(int l, int h, DoubleGenerator generator) { final double[] a = this.array; final IntAndDoublePredicate s = selector; for (int i = l; i < h; ++i) { if (s.op(i, a[i])) a[i] = generator.op(); } } final void leafFill(int l, int h, double value) { final double[] a = this.array; final IntAndDoublePredicate s = selector; for (int i = l; i < h; ++i) { if (s.op(i, a[i])) a[i] = value; } } final void leafCombineInPlace (int l, int h, double[] other, int otherOffset, BinaryDoubleOp combiner) { final double[] a = this.array; final IntAndDoublePredicate s = selector; int k = l + otherOffset; for (int i = l; i < h; ++i) { double x = a[i]; if (s.op(i, x)) a[i] = combiner.op(x, other[k]); k++; } } final void leafCombineInPlace (int l, int h, ParallelDoubleArrayWithDoubleMapping other, int otherOffset, BinaryDoubleOp combiner) { final double[] a = this.array; final IntAndDoublePredicate s = selector; int k = l + otherOffset; if (other.hasFilter()) { for (int i = l; i < h; ++i) { double x = a[i]; if (s.op(i, x) && other.isSelected(k)) a[i] = combiner.op(x, other.dget(k)); k++; } } else if (other.hasMap()) { for (int i = l; i < h; ++i) { double x = a[i]; if (s.op(i, x)) a[i] = combiner.op(x, other.dget(k)); k++; } } else { double[] b = other.array; for (int i = l; i < h; ++i) { double x = a[i]; if (s.op(i, x)) a[i] = combiner.op(x, b[k]); k++; } } } } static final class LRPap extends ParallelLongArrayWithFilter { final IntAndLongPredicate selector; LRPap(ForkJoinPool ex, int origin, int fence, long[] array, IntAndLongPredicate selector) { super(ex, origin, fence, array); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelLongArrayWithFilter withFilter(LongPredicate selector) { return new LRPap(ex, origin, fence, array, compoundIndexedSelector(this.selector, selector)); } public ParallelLongArrayWithFilter withIndexedFilter (IntAndLongPredicate selector) { return new LRPap (ex, origin, fence, array, compoundIndexedSelector(this.selector, selector)); } public ParallelLongArrayWithMapping withMapping (LongToObject op) { return new LROMPap(ex, origin, fence, array, selector, op); } public ParallelLongArrayWithLongMapping withMapping (LongOp op) { return new LRLMPap(ex, origin, fence, array, selector, op); } public ParallelLongArrayWithDoubleMapping withMapping (LongToDouble op) { return new LRDMPap(ex, origin, fence, array, selector, op); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new LROCPap(ex, origin, fence, array, selector, mapper); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new LRDCPap(ex, origin, fence, array, selector, mapper); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new LRLCPap(ex, origin, fence, array, selector, mapper); } final void leafApply(int lo, int hi, LongProcedure procedure) { final IntAndLongPredicate s = selector; final long[] a = this.array; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(i, x)) procedure.op(x); } } final long leafReduce(int lo, int hi, LongReducer reducer, long base) { final IntAndLongPredicate s = selector; boolean gotFirst = false; long r = base; final long[] a = this.array; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(i, x)) { if (!gotFirst) { gotFirst = true; r = x; } else r = reducer.op(r, x); } } return r; } final void leafTransform(int l, int h, LongOp op) { final long[] a = this.array; final IntAndLongPredicate s = selector; for (int i = l; i < h; ++i) { long x = a[i]; if (s.op(i, x)) a[i] = op.op(x); } } final void leafIndexMap(int l, int h, IntToLong op) { final long[] a = this.array; final IntAndLongPredicate s = selector; for (int i = l; i < h; ++i) { long x = a[i]; if (s.op(i, x)) a[i] = op.op(i); } } final void leafBinaryIndexMap(int l, int h, IntAndLongToLong op) { final long[] a = this.array; final IntAndLongPredicate s = selector; for (int i = l; i < h; ++i) { long x = a[i]; if (s.op(i, x)) a[i] = op.op(i, x); } } final void leafGenerate(int l, int h, LongGenerator generator) { final long[] a = this.array; final IntAndLongPredicate s = selector; for (int i = l; i < h; ++i) { if (s.op(i, a[i])) a[i] = generator.op(); } } final void leafFill(int l, int h, long value) { final long[] a = this.array; final IntAndLongPredicate s = selector; for (int i = l; i < h; ++i) { if (s.op(i, a[i])) a[i] = value; } } final void leafCombineInPlace (int l, int h, long[] other, int otherOffset, BinaryLongOp combiner) { final long[] a = this.array; final IntAndLongPredicate s = selector; int k = l + otherOffset; for (int i = l; i < h; ++i) { long x = a[i]; if (s.op(i, x)) a[i] = combiner.op(x, other[k]); k++; } } final void leafCombineInPlace (int l, int h, ParallelLongArrayWithLongMapping other, int otherOffset, BinaryLongOp combiner) { final long[] a = this.array; final IntAndLongPredicate s = selector; int k = l + otherOffset; if (other.hasFilter()) { for (int i = l; i < h; ++i) { long x = a[i]; if (s.op(i, x) && other.isSelected(k)) a[i] = combiner.op(x, other.lget(k)); k++; } } else if (other.hasMap()) { for (int i = l; i < h; ++i) { long x = a[i]; if (s.op(i, x)) a[i] = combiner.op(x, other.lget(k)); k++; } } else { long[] b = other.array; for (int i = l; i < h; ++i) { long x = a[i]; if (s.op(i, x)) a[i] = combiner.op(x, b[k]); k++; } } } } // Object-mapped abstract static class OOMPap extends ParallelArrayWithMapping { final Op op; OOMPap(ForkJoinPool ex, int origin, int fence, T[] array, Op op) { super(ex, origin, fence, array); this.op = op; } final boolean hasMap() { return true; } final Object oget(int i) { return op.op(this.array[i]); } final double dget(int i) { return ((Number)oget(i)).doubleValue(); } final long lget(int i) { return ((Number)oget(i)).longValue(); } final void leafTransfer(int lo, int hi, Object[] dest, int offset) { final Op f = op; final Object[] a = this.array; for (int i = lo; i < hi; ++i) dest[offset++] = f.op(a[i]); } final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, Object[] dest, int offset) { final Object[] a = this.array; final Op f = op; for (int i = loIdx; i < hiIdx; ++i) dest[offset++] = f.op(a[indices[i]]); } } abstract static class DOMPap extends ParallelDoubleArrayWithMapping { final DoubleToObject op; DOMPap(ForkJoinPool ex, int origin, int fence, double[] array, DoubleToObject op) { super(ex, origin, fence, array); this.op = op; } final boolean hasMap() { return true; } final Object oget(int i) { return op.op(this.array[i]); } final double dget(int i) { return ((Number)oget(i)).doubleValue(); } final long lget(int i) { return ((Number)oget(i)).longValue(); } final void leafTransfer(int lo, int hi, Object[] dest, int offset) { final double[] a = this.array; final DoubleToObject f = op; for (int i = lo; i < hi; ++i) dest[offset++] = f.op(a[i]); } final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, Object[] dest, int offset) { final double[] a = this.array; final DoubleToObject f = op; for (int i = loIdx; i < hiIdx; ++i) dest[offset++] = f.op(a[indices[i]]); } } abstract static class LOMPap extends ParallelLongArrayWithMapping { final LongToObject op; LOMPap(ForkJoinPool ex, int origin, int fence, long[] array, LongToObject op) { super(ex, origin, fence, array); this.op = op; } final boolean hasMap() { return true; } final Object oget(int i) { return op.op(this.array[i]); } final double dget(int i) { return ((Number)oget(i)).doubleValue(); } final long lget(int i) { return ((Number)oget(i)).longValue(); } final void leafTransfer(int lo, int hi, Object[] dest, int offset) { final long[] a = this.array; final LongToObject f = op; for (int i = lo; i < hi; ++i) dest[offset++] = f.op(a[i]); } final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, Object[] dest, int offset) { final long[] a = this.array; final LongToObject f = op; for (int i = loIdx; i < hiIdx; ++i) dest[offset++] = f.op(a[indices[i]]); } } // Object mapped, unfiltered static final class OUOMPap extends OOMPap { OUOMPap(ForkJoinPool ex, int origin, int fence, T[] array, Op op) { super(ex, origin, fence, array, op); } public ParallelArrayWithMapping withMapping (Op op) { return new OUOMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new OUDMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithLongMapping withMapping (ObjectToLong op) { return new OULMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new OUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new OUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new OULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, Procedure procedure) { final Op f = op; final Object[] a = this.array; for (int i = lo; i < hi; ++i) procedure.op(f.op(a[i])); } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { if (lo >= hi) return base; final Object[] a = this.array; final Op f = op; Object r = f.op(a[lo]); for (int i = lo+1; i < hi; ++i) r = reducer.op(r, f.op(a[i])); return r; } } static final class DUOMPap extends DOMPap { DUOMPap(ForkJoinPool ex, int origin, int fence, double[] array, DoubleToObject op) { super(ex, origin, fence, array, op); } public ParallelDoubleArrayWithMapping withMapping (Op op) { return new DUOMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new DUDMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithLongMapping withMapping (ObjectToLong op) { return new DULMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new DUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new DUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new DULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, Procedure procedure) { final double[] a = this.array; final DoubleToObject f = op; for (int i = lo; i < hi; ++i) procedure.op(f.op(a[i])); } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { if (lo >= hi) return base; final double[] a = this.array; final DoubleToObject f = op; Object r = f.op(a[lo]); for (int i = lo+1; i < hi; ++i) r = reducer.op(r, f.op(a[i])); return r; } } static final class LUOMPap extends LOMPap { LUOMPap(ForkJoinPool ex, int origin, int fence, long[] array, LongToObject op) { super(ex, origin, fence, array, op); } public ParallelLongArrayWithMapping withMapping (Op op) { return new LUOMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithLongMapping withMapping (ObjectToLong op) { return new LULMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new LUDMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new LUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new LUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new LULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, Procedure procedure) { final long[] a = this.array; final LongToObject f = op; for (int i = lo; i < hi; ++i) procedure.op(f.op(a[i])); } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { if (lo >= hi) return base; final long[] a = this.array; final LongToObject f = op; Object r = f.op(a[lo]); for (int i = lo+1; i < hi; ++i) r = reducer.op(r, f.op(a[i])); return r; } } // Object-mapped, filtered static final class OFOMPap extends OOMPap { final Predicate selector; OFOMPap(ForkJoinPool ex, int origin, int fence, T[] array, Predicate selector, Op op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelArrayWithMapping withMapping (Op op) { return new OFOMPap (ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new OFDMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithLongMapping withMapping (ObjectToLong op) { return new OFLMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new OFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new OFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new OFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, Procedure procedure) { final Predicate s = selector; final Object[] a = this.array; final Op f = op; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(x)) procedure.op(f.op(x)); } } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { final Predicate s = selector; final Object[] a = this.array; final Op f = op; boolean gotFirst = false; Object r = base; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(x)) { Object y = f.op(x); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class DFOMPap extends DOMPap { final DoublePredicate selector; DFOMPap(ForkJoinPool ex, int origin, int fence, double[] array, DoublePredicate selector, DoubleToObject op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelArray all(Class elementType) { PAS.FJOSelectAllDriver r = new PAS.FJOSelectAllDriver (this, elementType); ex.invoke(r); return new ParallelArray(ex, (U[])(r.results)); } public ParallelDoubleArrayWithMapping withMapping (Op op) { return new DFOMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new DFDMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithLongMapping withMapping (ObjectToLong op) { return new DFLMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new DFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new DFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new DFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, Procedure procedure) { final DoublePredicate s = selector; final DoubleToObject f = op; final double[] a = this.array; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(x)) procedure.op(f.op(x)); } } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { boolean gotFirst = false; Object r = base; final DoublePredicate s = selector; final DoubleToObject f = op; final double[] a = this.array; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(x)) { Object y = f.op(x); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class LFOMPap extends LOMPap { final LongPredicate selector; LFOMPap(ForkJoinPool ex, int origin, int fence, long[] array, LongPredicate selector, LongToObject op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelLongArrayWithMapping withMapping (Op op) { return new LFOMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithLongMapping withMapping (ObjectToLong op) { return new LFLMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new LFDMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new LFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new LFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new LFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, Procedure procedure) { final LongPredicate s = selector; final LongToObject f = op; final long[] a = this.array; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(x)) procedure.op(f.op(x)); } } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { final LongPredicate s = selector; final LongToObject f = op; boolean gotFirst = false; Object r = base; final long[] a = this.array; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(x)) { Object y = f.op(x); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } // Object-mapped, relational static final class OROMPap extends OOMPap { final IntAndObjectPredicate selector; OROMPap(ForkJoinPool ex, int origin, int fence, T[] array, IntAndObjectPredicate selector, Op op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelArrayWithMapping withMapping (Op op) { return new OROMPap (ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithDoubleMapping withMapping(ObjectToDouble op) { return new ORDMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithLongMapping withMapping(ObjectToLong op) { return new ORLMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new OROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new ORDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new ORLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, Procedure procedure) { final IntAndObjectPredicate s = selector; final Object[] a = this.array; final Op f = op; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(i, x)) procedure.op(f.op(x)); } } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { final IntAndObjectPredicate s = selector; final Object[] a = this.array; final Op f = op; boolean gotFirst = false; Object r = base; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(i, x)) { Object y = f.op(x); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class DROMPap extends DOMPap { final IntAndDoublePredicate selector; DROMPap(ForkJoinPool ex, int origin, int fence, double[] array, IntAndDoublePredicate selector, DoubleToObject op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelArray all(Class elementType) { PAS.FJOSelectAllDriver r = new PAS.FJOSelectAllDriver (this, elementType); ex.invoke(r); return new ParallelArray(ex, (U[])(r.results)); } public ParallelDoubleArrayWithMapping withMapping (Op op) { return new DROMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new DRDMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithLongMapping withMapping (ObjectToLong op) { return new DRLMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new DROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new DRDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new DRLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, Procedure procedure) { final IntAndDoublePredicate s = selector; final DoubleToObject f = op; final double[] a = this.array; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(i, x)) procedure.op(f.op(x)); } } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { boolean gotFirst = false; Object r = base; final IntAndDoublePredicate s = selector; final DoubleToObject f = op; final double[] a = this.array; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(i, x)) { Object y = f.op(x); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class LROMPap extends LOMPap { final IntAndLongPredicate selector; LROMPap(ForkJoinPool ex, int origin, int fence, long[] array, IntAndLongPredicate selector, LongToObject op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelLongArrayWithMapping withMapping (Op op) { return new LROMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithLongMapping withMapping (ObjectToLong op) { return new LRLMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new LRDMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new LROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new LRDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new LRLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, Procedure procedure) { final IntAndLongPredicate s = selector; final LongToObject f = op; final long[] a = this.array; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(i, x)) procedure.op(f.op(x)); } } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { final IntAndLongPredicate s = selector; final LongToObject f = op; boolean gotFirst = false; Object r = base; final long[] a = this.array; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(i, x)) { Object y = f.op(x); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } // Object-combined abstract static class OOCPap extends ParallelArrayWithMapping { final IntAndObjectToObject op; OOCPap(ForkJoinPool ex, int origin, int fence, T[] array, IntAndObjectToObject op) { super(ex, origin, fence, array); this.op = op; } final boolean hasMap() { return true; } final Object oget(int i) { return op.op(i, this.array[i]); } final double dget(int i) { return ((Number)oget(i)).doubleValue(); } final long lget(int i) { return ((Number)oget(i)).longValue(); } final void leafTransfer(int lo, int hi, Object[] dest, int offset) { final IntAndObjectToObject f = op; final Object[] a = this.array; for (int i = lo; i < hi; ++i) dest[offset++] = f.op(i, a[i]); } final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, Object[] dest, int offset) { final Object[] a = this.array; final IntAndObjectToObject f = op; for (int i = loIdx; i < hiIdx; ++i) { int idx = indices[i]; dest[offset++] = f.op(idx, a[idx]); } } } abstract static class DOCPap extends ParallelDoubleArrayWithMapping { final IntAndDoubleToObject op; DOCPap(ForkJoinPool ex, int origin, int fence, double[] array, IntAndDoubleToObject op) { super(ex, origin, fence, array); this.op = op; } final boolean hasMap() { return true; } final Object oget(int i) { return op.op(i, this.array[i]); } final double dget(int i) { return ((Number)oget(i)).doubleValue(); } final long lget(int i) { return ((Number)oget(i)).longValue(); } final void leafTransfer(int lo, int hi, Object[] dest, int offset) { final IntAndDoubleToObject f = op; final double[] a = this.array; for (int i = lo; i < hi; ++i) dest[offset++] = f.op(i, a[i]); } final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, Object[] dest, int offset) { final double[] a = this.array; final IntAndDoubleToObject f = op; for (int i = loIdx; i < hiIdx; ++i) { int idx = indices[i]; dest[offset++] = f.op(idx, a[idx]); } } } abstract static class LOCPap extends ParallelLongArrayWithMapping { final IntAndLongToObject op; LOCPap(ForkJoinPool ex, int origin, int fence, long[] array, IntAndLongToObject op) { super(ex, origin, fence, array); this.op = op; } final boolean hasMap() { return true; } final Object oget(int i) { return op.op(i, this.array[i]); } final double dget(int i) { return ((Number)oget(i)).doubleValue(); } final long lget(int i) { return ((Number)oget(i)).longValue(); } final void leafTransfer(int lo, int hi, Object[] dest, int offset) { final IntAndLongToObject f = op; final long[] a = this.array; for (int i = lo; i < hi; ++i) dest[offset++] = f.op(i, a[i]); } final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, Object[] dest, int offset) { final long[] a = this.array; final IntAndLongToObject f = op; for (int i = loIdx; i < hiIdx; ++i) { int idx = indices[i]; dest[offset++] = f.op(idx, a[idx]); } } } // Object-combined, unfiltered static final class OUOCPap extends OOCPap { OUOCPap(ForkJoinPool ex, int origin, int fence, T[] array, IntAndObjectToObject op) { super(ex, origin, fence, array, op); } public ParallelArrayWithMapping withMapping (Op op) { return new OUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new OUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelArrayWithLongMapping withMapping (ObjectToLong op) { return new OULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new OUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new OUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new OULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, Procedure procedure) { final IntAndObjectToObject f = op; final Object[] a = this.array; for (int i = lo; i < hi; ++i) procedure.op(f.op(i, a[i])); } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { if (lo >= hi) return base; final Object[] a = this.array; final IntAndObjectToObject f = op; Object r = f.op(lo, a[lo]); for (int i = lo+1; i < hi; ++i) r = reducer.op(r, f.op(i, a[i])); return r; } } static final class DUOCPap extends DOCPap { DUOCPap(ForkJoinPool ex, int origin, int fence, double[] array, IntAndDoubleToObject op) { super(ex, origin, fence, array, op); } public ParallelDoubleArrayWithMapping< V> withMapping (Op op) { return new DUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new DUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithLongMapping withMapping (ObjectToLong op) { return new DULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new DUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new DUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new DULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, Procedure procedure) { final IntAndDoubleToObject f = op; final double[] a = this.array; for (int i = lo; i < hi; ++i) procedure.op(f.op(i, a[i])); } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { if (lo >= hi) return base; final double[] a = this.array; final IntAndDoubleToObject f = op; Object r = f.op(lo, a[lo]); for (int i = lo+1; i < hi; ++i) r = reducer.op(r, f.op(i, a[i])); return r; } } static final class LUOCPap extends LOCPap { LUOCPap(ForkJoinPool ex, int origin, int fence, long[] array, IntAndLongToObject op) { super(ex, origin, fence, array, op); } public ParallelLongArrayWithMapping< V> withMapping (Op op) { return new LUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new LUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithLongMapping withMapping (ObjectToLong op) { return new LULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new LUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new LUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new LULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, Procedure procedure) { final IntAndLongToObject f = op; final long[] a = this.array; for (int i = lo; i < hi; ++i) procedure.op(f.op(i, a[i])); } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { if (lo >= hi) return base; final long[] a = this.array; final IntAndLongToObject f = op; Object r = f.op(lo, a[lo]); for (int i = lo+1; i < hi; ++i) r = reducer.op(r, f.op(i, a[i])); return r; } } // object-combined filtered static final class OFOCPap extends OOCPap { final Predicate selector; OFOCPap(ForkJoinPool ex, int origin, int fence, T[] array, Predicate selector, IntAndObjectToObject op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelArrayWithMapping withMapping (Op op) { return new OFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new OFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelArrayWithLongMapping withMapping (ObjectToLong op) { return new OFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new OFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new OFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new OFLCPap (ex, origin, fence, array, selector, compoundIndexedOp (this.op, mapper)); } void leafApply(int lo, int hi, Procedure procedure) { final Predicate s = selector; final Object[] a = this.array; final IntAndObjectToObject f = op; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(x)) procedure.op(f.op(i, x)); } } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { final Predicate s = selector; final Object[] a = this.array; final IntAndObjectToObject f = op; boolean gotFirst = false; Object r = base; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(x)) { Object y = f.op(i, x); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class DFOCPap extends DOCPap { final DoublePredicate selector; DFOCPap(ForkJoinPool ex, int origin, int fence, double[] array, DoublePredicate selector, IntAndDoubleToObject op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelDoubleArrayWithMapping< V> withMapping (Op op) { return new DFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new DFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithLongMapping withMapping (ObjectToLong op) { return new DFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new DFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new DFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new DFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, Procedure procedure) { final DoublePredicate s = selector; final double[] a = this.array; final IntAndDoubleToObject f = op; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(x)) procedure.op(f.op(i, x)); } } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { final DoublePredicate s = selector; final double[] a = this.array; final IntAndDoubleToObject f = op; boolean gotFirst = false; Object r = base; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(x)) { Object y = f.op(i, x); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class LFOCPap extends LOCPap { final LongPredicate selector; LFOCPap(ForkJoinPool ex, int origin, int fence, long[] array, LongPredicate selector, IntAndLongToObject op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelLongArrayWithMapping< V> withMapping (Op op) { return new LFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new LFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithLongMapping withMapping (ObjectToLong op) { return new LFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new LFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new LFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new LFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, Procedure procedure) { final LongPredicate s = selector; final long[] a = this.array; final IntAndLongToObject f = op; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(x)) procedure.op(f.op(i, x)); } } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { final LongPredicate s = selector; final long[] a = this.array; final IntAndLongToObject f = op; boolean gotFirst = false; Object r = base; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(x)) { Object y = f.op(i, x); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } // Object-combined, relational static final class OROCPap extends OOCPap { final IntAndObjectPredicate selector; OROCPap(ForkJoinPool ex, int origin, int fence, T[] array, IntAndObjectPredicate selector, IntAndObjectToObject op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelArrayWithMapping withMapping (Op op) { return new OROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new ORDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelArrayWithLongMapping withMapping (ObjectToLong op) { return new ORLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new OROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new ORDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new ORLCPap (ex, origin, fence, array, selector, compoundIndexedOp (this.op, mapper)); } void leafApply(int lo, int hi, Procedure procedure) { final IntAndObjectPredicate s = selector; final Object[] a = this.array; final IntAndObjectToObject f = op; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(i, x)) procedure.op(f.op(i, x)); } } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { final IntAndObjectPredicate s = selector; final Object[] a = this.array; final IntAndObjectToObject f = op; boolean gotFirst = false; Object r = base; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(i, x)) { Object y = f.op(i, x); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class DROCPap extends DOCPap { final IntAndDoublePredicate selector; DROCPap(ForkJoinPool ex, int origin, int fence, double[] array, IntAndDoublePredicate selector, IntAndDoubleToObject op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelDoubleArrayWithMapping< V> withMapping (Op op) { return new DROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new DRDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithLongMapping withMapping (ObjectToLong op) { return new DRLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new DROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new DRDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new DRLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, Procedure procedure) { final IntAndDoublePredicate s = selector; final double[] a = this.array; final IntAndDoubleToObject f = op; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(i, x)) procedure.op(f.op(i, x)); } } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { final IntAndDoublePredicate s = selector; final double[] a = this.array; final IntAndDoubleToObject f = op; boolean gotFirst = false; Object r = base; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(i, x)) { Object y = f.op(i, x); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class LROCPap extends LOCPap { final IntAndLongPredicate selector; LROCPap(ForkJoinPool ex, int origin, int fence, long[] array, IntAndLongPredicate selector, IntAndLongToObject op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelLongArrayWithMapping< V> withMapping (Op op) { return new LROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithDoubleMapping withMapping (ObjectToDouble op) { return new LRDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithLongMapping withMapping (ObjectToLong op) { return new LRLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndObjectToObject mapper) { return new LROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndObjectToDouble mapper) { return new LRDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndObjectToLong mapper) { return new LRLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, Procedure procedure) { final IntAndLongPredicate s = selector; final long[] a = this.array; final IntAndLongToObject f = op; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(i, x)) procedure.op(f.op(i, x)); } } Object leafReduce(int lo, int hi, Reducer reducer, Object base) { final IntAndLongPredicate s = selector; final long[] a = this.array; final IntAndLongToObject f = op; boolean gotFirst = false; Object r = base; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(i, x)) { Object y = f.op(i, x); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } // Double-mapped abstract static class ODMPap extends ParallelArrayWithDoubleMapping { final ObjectToDouble op; ODMPap(ForkJoinPool ex, int origin, int fence, T[] array, ObjectToDouble op) { super(ex, origin, fence, array); this.op = op; } final boolean hasMap() { return true; } final double dget(int i) { return op.op(this.array[i]); } final Object oget(int i) { return Double.valueOf(dget(i)); } final long lget(int i) { return (long)(dget(i)); } final void leafTransfer(int lo, int hi, double[] dest, int offset) { final ObjectToDouble f = op; final Object[] a = this.array; for (int i = lo; i < hi; ++i) dest[offset++] = f.op(a[i]); } final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, double[] dest, int offset) { final Object[] a = this.array; final ObjectToDouble f = op; for (int i = loIdx; i < hiIdx; ++i) dest[offset++] = f.op(a[indices[i]]); } } abstract static class DDMPap extends ParallelDoubleArrayWithDoubleMapping { final DoubleOp op; DDMPap (ForkJoinPool ex, int origin, int fence, double[] array, DoubleOp op) { super(ex, origin, fence, array); this.op = op; } final boolean hasMap() { return true; } final double dget(int i) { return op.op(this.array[i]); } final Object oget(int i) { return Double.valueOf(dget(i)); } final long lget(int i) { return (long)(dget(i)); } final void leafTransfer(int lo, int hi, double[] dest, int offset) { final double[] a = this.array; final DoubleOp f = op; for (int i = lo; i < hi; ++i) dest[offset++] = f.op(a[i]); } final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, double[] dest, int offset) { final double[] a = this.array; final DoubleOp f = op; for (int i = loIdx; i < hiIdx; ++i) dest[offset++] = f.op(a[indices[i]]); } } abstract static class LDMPap extends ParallelLongArrayWithDoubleMapping { final LongToDouble op; LDMPap(ForkJoinPool ex, int origin, int fence, long[] array, LongToDouble op) { super(ex, origin, fence, array); this.op = op; } final boolean hasMap() { return true; } final double dget(int i) { return op.op(this.array[i]); } final Object oget(int i) { return Double.valueOf(dget(i)); } final long lget(int i) { return (long)(dget(i)); } final void leafTransfer(int lo, int hi, double[] dest, int offset) { final long[] a = this.array; final LongToDouble f = op; for (int i = lo; i < hi; ++i) dest[offset++] = f.op(a[i]); } final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, double[] dest, int offset) { final long[] a = this.array; final LongToDouble f = op; for (int i = loIdx; i < hiIdx; ++i) dest[offset++] = f.op(a[indices[i]]); } } // double-mapped, unfiltered static final class OUDMPap extends ODMPap { OUDMPap(ForkJoinPool ex, int origin, int fence, T[] array, ObjectToDouble op) { super(ex, origin, fence, array, op); } public ParallelArrayWithDoubleMapping withMapping(DoubleOp op) { return new OUDMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithLongMapping withMapping(DoubleToLong op) { return new OULMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithMapping withMapping (DoubleToObject op) { return new OUOMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new OUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new OUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new OULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, DoubleProcedure procedure) { final ObjectToDouble f = op; final Object[] a = this.array; for (int i = lo; i < hi; ++i) procedure.op(f.op(a[i])); } double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { if (lo >= hi) return base; final Object[] a = this.array; final ObjectToDouble f = op; double r = f.op(a[lo]); for (int i = lo+1; i < hi; ++i) r = reducer.op(r, f.op(a[i])); return r; } } static final class DUDMPap extends DDMPap { DUDMPap(ForkJoinPool ex, int origin, int fence, double[] array, DoubleOp op) { super(ex, origin, fence, array, op); } public ParallelDoubleArrayWithDoubleMapping withMapping(DoubleOp op) { return new DUDMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithLongMapping withMapping(DoubleToLong op) { return new DULMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithMapping withMapping (DoubleToObject op) { return new DUOMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new DUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new DUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new DULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, DoubleProcedure procedure) { final double[] a = this.array; final DoubleOp f = op; for (int i = lo; i < hi; ++i) procedure.op(f.op(a[i])); } double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { if (lo >= hi) return base; final double[] a = this.array; final DoubleOp f = op; double r = f.op(a[lo]); for (int i = lo+1; i < hi; ++i) r = reducer.op(r, f.op(a[i])); return r; } } static final class LUDMPap extends LDMPap { LUDMPap(ForkJoinPool ex, int origin, int fence, long[] array, LongToDouble op) { super(ex, origin, fence, array, op); } public ParallelLongArrayWithLongMapping withMapping(DoubleToLong op) { return new LULMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithDoubleMapping withMapping(DoubleOp op) { return new LUDMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithMapping withMapping (DoubleToObject op) { return new LUOMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new LUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new LUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new LULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, DoubleProcedure procedure) { final LongToDouble f = op; final long[] a = this.array; for (int i = lo; i < hi; ++i) procedure.op(f.op(a[i])); } double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { if (lo >= hi) return base; final long[] a = this.array; final LongToDouble f = op; double r = f.op(a[lo]); for (int i = lo+1; i < hi; ++i) r = reducer.op(r, f.op(a[i])); return r; } } // double-mapped, filtered static final class OFDMPap extends ODMPap { final Predicate selector; OFDMPap(ForkJoinPool ex, int origin, int fence, T[] array, Predicate selector, ObjectToDouble op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelArrayWithDoubleMapping withMapping(DoubleOp op) { return new OFDMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithLongMapping withMapping(DoubleToLong op) { return new OFLMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithMapping withMapping (DoubleToObject op) { return new OFOMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new OFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new OFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new OFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, DoubleProcedure procedure) { final Predicate s = selector; final Object[] a = this.array; final ObjectToDouble f = op; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(x)) procedure.op(f.op(x)); } } double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { final Predicate s = selector; final ObjectToDouble f = op; boolean gotFirst = false; double r = base; final Object[] a = this.array; for (int i = lo; i < hi; ++i) { Object t = a[i]; if (s.op(t)) { double y = f.op(t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class DFDMPap extends DDMPap { final DoublePredicate selector; DFDMPap(ForkJoinPool ex, int origin, int fence, double[] array, DoublePredicate selector, DoubleOp op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelDoubleArrayWithDoubleMapping withMapping(DoubleOp op) { return new DFDMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithLongMapping withMapping(DoubleToLong op) { return new DFLMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithMapping withMapping (DoubleToObject op) { return new DFOMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new DFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new DFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new DFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, DoubleProcedure procedure) { final DoublePredicate s = selector; final DoubleOp f = op; final double[] a = this.array; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(x)) procedure.op(f.op(x)); } } double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { final DoublePredicate s = selector; boolean gotFirst = false; double r = base; final double[] a = this.array; final DoubleOp f = op; for (int i = lo; i < hi; ++i) { double t = a[i]; if (s.op(t)) { double y = f.op(t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class LFDMPap extends LDMPap { final LongPredicate selector; LFDMPap(ForkJoinPool ex, int origin, int fence, long[] array, LongPredicate selector, LongToDouble op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelLongArrayWithLongMapping withMapping(DoubleToLong op) { return new LFLMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithDoubleMapping withMapping(DoubleOp op) { return new LFDMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithMapping withMapping (DoubleToObject op) { return new LFOMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new LFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new LFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new LFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, DoubleProcedure procedure) { final LongPredicate s = selector; final long[] a = this.array; final LongToDouble f = op; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(x)) procedure.op(f.op(x)); } } double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { final LongPredicate s = selector; final LongToDouble f = op; boolean gotFirst = false; double r = base; final long[] a = this.array; for (int i = lo; i < hi; ++i) { long t = a[i]; if (s.op(t)) { double y = f.op(t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } // double-mapped, relational static final class ORDMPap extends ODMPap { final IntAndObjectPredicate selector; ORDMPap(ForkJoinPool ex, int origin, int fence, T[] array, IntAndObjectPredicate selector, ObjectToDouble op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelArrayWithDoubleMapping withMapping(DoubleOp op) { return new ORDMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithLongMapping withMapping(DoubleToLong op) { return new ORLMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithMapping withMapping (DoubleToObject op) { return new OROMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new OROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new ORDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new ORLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, DoubleProcedure procedure) { final IntAndObjectPredicate s = selector; final Object[] a = this.array; final ObjectToDouble f = op; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(i, x)) procedure.op(f.op(x)); } } double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { final IntAndObjectPredicate s = selector; final ObjectToDouble f = op; boolean gotFirst = false; double r = base; final Object[] a = this.array; for (int i = lo; i < hi; ++i) { Object t = a[i]; if (s.op(i, t)) { double y = f.op(t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class DRDMPap extends DDMPap { final IntAndDoublePredicate selector; DRDMPap(ForkJoinPool ex, int origin, int fence, double[] array, IntAndDoublePredicate selector, DoubleOp op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelDoubleArrayWithDoubleMapping withMapping(DoubleOp op) { return new DRDMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithLongMapping withMapping(DoubleToLong op) { return new DRLMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithMapping withMapping (DoubleToObject op) { return new DROMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new DROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new DRDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new DRLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, DoubleProcedure procedure) { final IntAndDoublePredicate s = selector; final DoubleOp f = op; final double[] a = this.array; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(i, x)) procedure.op(f.op(x)); } } double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { final IntAndDoublePredicate s = selector; boolean gotFirst = false; double r = base; final double[] a = this.array; final DoubleOp f = op; for (int i = lo; i < hi; ++i) { double t = a[i]; if (s.op(i, t)) { double y = f.op(t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class LRDMPap extends LDMPap { final IntAndLongPredicate selector; LRDMPap(ForkJoinPool ex, int origin, int fence, long[] array, IntAndLongPredicate selector, LongToDouble op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelLongArrayWithLongMapping withMapping(DoubleToLong op) { return new LRLMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithDoubleMapping withMapping(DoubleOp op) { return new LRDMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithMapping withMapping (DoubleToObject op) { return new LROMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new LROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new LRDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new LRLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, DoubleProcedure procedure) { final IntAndLongPredicate s = selector; final long[] a = this.array; final LongToDouble f = op; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(i, x)) procedure.op(f.op(x)); } } double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { final IntAndLongPredicate s = selector; final LongToDouble f = op; boolean gotFirst = false; double r = base; final long[] a = this.array; for (int i = lo; i < hi; ++i) { long t = a[i]; if (s.op(i, t)) { double y = f.op(t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } // double-combined abstract static class ODCPap extends ParallelArrayWithDoubleMapping { final IntAndObjectToDouble op; ODCPap(ForkJoinPool ex, int origin, int fence, T[] array, IntAndObjectToDouble op) { super(ex, origin, fence, array); this.op = op; } final boolean hasMap() { return true; } final double dget(int i) { return op.op(i, this.array[i]); } final Object oget(int i) { return Double.valueOf(dget(i)); } final long lget(int i) { return (long)(dget(i)); } final void leafTransfer(int lo, int hi, double[] dest, int offset) { final IntAndObjectToDouble f = op; final Object[] a = this.array; for (int i = lo; i < hi; ++i) dest[offset++] = f.op(i, a[i]); } final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, double[] dest, int offset) { final Object[] a = this.array; final IntAndObjectToDouble f = op; for (int i = loIdx; i < hiIdx; ++i) { int idx = indices[i]; dest[offset++] = f.op(idx, a[idx]); } } } abstract static class DDCPap extends ParallelDoubleArrayWithDoubleMapping { final IntAndDoubleToDouble op; DDCPap(ForkJoinPool ex, int origin, int fence, double[] array, IntAndDoubleToDouble op) { super(ex, origin, fence, array); this.op = op; } final boolean hasMap() { return true; } final double dget(int i) { return op.op(i, this.array[i]); } final Object oget(int i) { return Double.valueOf(dget(i)); } final long lget(int i) { return (long)(dget(i)); } final void leafTransfer(int lo, int hi, double[] dest, int offset) { final IntAndDoubleToDouble f = op; final double[] a = this.array; for (int i = lo; i < hi; ++i) dest[offset++] = f.op(i, a[i]); } final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, double[] dest, int offset) { final double[] a = this.array; final IntAndDoubleToDouble f = op; for (int i = loIdx; i < hiIdx; ++i) { int idx = indices[i]; dest[offset++] = f.op(idx, a[idx]); } } } abstract static class LDCPap extends ParallelLongArrayWithDoubleMapping { final IntAndLongToDouble op; LDCPap(ForkJoinPool ex, int origin, int fence, long[] array, IntAndLongToDouble op) { super(ex, origin, fence, array); this.op = op; } final boolean hasMap() { return true; } final double dget(int i) { return op.op(i, this.array[i]); } final Object oget(int i) { return Double.valueOf(dget(i)); } final long lget(int i) { return (long)(dget(i)); } final void leafTransfer(int lo, int hi, double[] dest, int offset) { final IntAndLongToDouble f = op; final long[] a = this.array; for (int i = lo; i < hi; ++i) dest[offset++] = f.op(i, a[i]); } final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, double[] dest, int offset) { final long[] a = this.array; final IntAndLongToDouble f = op; for (int i = loIdx; i < hiIdx; ++i) { int idx = indices[i]; dest[offset++] = f.op(idx, a[idx]); } } } // double-combined, unfiltered static final class OUDCPap extends ODCPap { OUDCPap(ForkJoinPool ex, int origin, int fence, T[] array, IntAndObjectToDouble op) { super(ex, origin, fence, array, op); } public ParallelArrayWithDoubleMapping withMapping(DoubleOp op) { return new OUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelArrayWithLongMapping withMapping(DoubleToLong op) { return new OULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelArrayWithMapping withMapping (DoubleToObject op) { return new OUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new OUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new OUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new OULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, DoubleProcedure procedure) { final IntAndObjectToDouble f = op; final Object[] a = this.array; for (int i = lo; i < hi; ++i) procedure.op(f.op(i, a[i])); } double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { if (lo >= hi) return base; final Object[] a = this.array; final IntAndObjectToDouble f = op; double r = f.op(lo, a[lo]); for (int i = lo+1; i < hi; ++i) r = reducer.op(r, f.op(i, a[i])); return r; } } static final class DUDCPap extends DDCPap { DUDCPap(ForkJoinPool ex, int origin, int fence, double[] array, IntAndDoubleToDouble op) { super(ex, origin, fence, array, op); } public ParallelDoubleArrayWithDoubleMapping withMapping(DoubleOp op) { return new DUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithLongMapping withMapping(DoubleToLong op) { return new DULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithMapping< U> withMapping (DoubleToObject op) { return new DUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new DUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new DUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new DULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, DoubleProcedure procedure) { final IntAndDoubleToDouble f = op; final double[] a = this.array; for (int i = lo; i < hi; ++i) procedure.op(f.op(i, a[i])); } double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { if (lo >= hi) return base; final double[] a = this.array; final IntAndDoubleToDouble f = op; double r = f.op(lo, a[lo]); for (int i = lo+1; i < hi; ++i) r = reducer.op(r, f.op(i, a[i])); return r; } } static final class LUDCPap extends LDCPap { LUDCPap(ForkJoinPool ex, int origin, int fence, long[] array, IntAndLongToDouble op) { super(ex, origin, fence, array, op); } public ParallelLongArrayWithDoubleMapping withMapping(DoubleOp op) { return new LUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithLongMapping withMapping(DoubleToLong op) { return new LULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithMapping< U> withMapping (DoubleToObject op) { return new LUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new LUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new LUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new LULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, DoubleProcedure procedure) { final IntAndLongToDouble f = op; final long[] a = this.array; for (int i = lo; i < hi; ++i) procedure.op(f.op(i, a[i])); } double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { if (lo >= hi) return base; final long[] a = this.array; final IntAndLongToDouble f = op; double r = f.op(lo, a[lo]); for (int i = lo+1; i < hi; ++i) r = reducer.op(r, f.op(i, a[i])); return r; } } // double-combined, filtered static final class OFDCPap extends ODCPap { final Predicate selector; OFDCPap(ForkJoinPool ex, int origin, int fence, T[] array, Predicate selector, IntAndObjectToDouble op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelArrayWithDoubleMapping withMapping(DoubleOp op) { return new OFDCPap (ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelArrayWithLongMapping withMapping(DoubleToLong op) { return new OFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelArrayWithMapping withMapping (DoubleToObject op) { return new OFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new OFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new OFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new OFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, DoubleProcedure procedure) { final Predicate s = selector; final Object[] a = this.array; final IntAndObjectToDouble f = op; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(x)) procedure.op(f.op(i, x)); } } double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { final Predicate s = selector; final IntAndObjectToDouble f = op; boolean gotFirst = false; double r = base; final Object[] a = this.array; for (int i = lo; i < hi; ++i) { Object t = a[i]; if (s.op(t)) { double y = f.op(i, t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class DFDCPap extends DDCPap { final DoublePredicate selector; DFDCPap(ForkJoinPool ex, int origin, int fence, double[] array, DoublePredicate selector, IntAndDoubleToDouble op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelDoubleArrayWithDoubleMapping withMapping(DoubleOp op) { return new DFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithLongMapping withMapping(DoubleToLong op) { return new DFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithMapping< U> withMapping (DoubleToObject op) { return new DFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new DFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new DFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new DFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, DoubleProcedure procedure) { final DoublePredicate s = selector; final double[] a = this.array; final IntAndDoubleToDouble f = op; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(x)) procedure.op(f.op(i, x)); } } double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { final DoublePredicate s = selector; final IntAndDoubleToDouble f = op; boolean gotFirst = false; double r = base; final double[] a = this.array; for (int i = lo; i < hi; ++i) { double t = a[i]; if (s.op(t)) { double y = f.op(i, t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class LFDCPap extends LDCPap { final LongPredicate selector; LFDCPap(ForkJoinPool ex, int origin, int fence, long[] array, LongPredicate selector, IntAndLongToDouble op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelLongArrayWithDoubleMapping withMapping(DoubleOp op) { return new LFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithLongMapping withMapping(DoubleToLong op) { return new LFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithMapping< U> withMapping (DoubleToObject op) { return new LFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new LFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new LFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new LFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, DoubleProcedure procedure) { final LongPredicate s = selector; final long[] a = this.array; final IntAndLongToDouble f = op; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(x)) procedure.op(f.op(i, x)); } } double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { final LongPredicate s = selector; final IntAndLongToDouble f = op; boolean gotFirst = false; double r = base; final long[] a = this.array; for (int i = lo; i < hi; ++i) { long t = a[i]; if (s.op(t)) { double y = f.op(i, t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } // double-combined, relational static final class ORDCPap extends ODCPap { final IntAndObjectPredicate selector; ORDCPap(ForkJoinPool ex, int origin, int fence, T[] array, IntAndObjectPredicate selector, IntAndObjectToDouble op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelArrayWithDoubleMapping withMapping(DoubleOp op) { return new ORDCPap (ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelArrayWithLongMapping withMapping(DoubleToLong op) { return new ORLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelArrayWithMapping withMapping (DoubleToObject op) { return new OROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new OROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new ORDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new ORLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, DoubleProcedure procedure) { final IntAndObjectPredicate s = selector; final Object[] a = this.array; final IntAndObjectToDouble f = op; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(i, x)) procedure.op(f.op(i, x)); } } double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { final IntAndObjectPredicate s = selector; final IntAndObjectToDouble f = op; boolean gotFirst = false; double r = base; final Object[] a = this.array; for (int i = lo; i < hi; ++i) { Object t = a[i]; if (s.op(i, t)) { double y = f.op(i, t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class DRDCPap extends DDCPap { final IntAndDoublePredicate selector; DRDCPap(ForkJoinPool ex, int origin, int fence, double[] array, IntAndDoublePredicate selector, IntAndDoubleToDouble op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelDoubleArrayWithDoubleMapping withMapping(DoubleOp op) { return new DRDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithLongMapping withMapping(DoubleToLong op) { return new DRLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithMapping< U> withMapping (DoubleToObject op) { return new DROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new DROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new DRDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new DRLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, DoubleProcedure procedure) { final IntAndDoublePredicate s = selector; final double[] a = this.array; final IntAndDoubleToDouble f = op; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(i, x)) procedure.op(f.op(i, x)); } } double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { final IntAndDoublePredicate s = selector; final IntAndDoubleToDouble f = op; boolean gotFirst = false; double r = base; final double[] a = this.array; for (int i = lo; i < hi; ++i) { double t = a[i]; if (s.op(i, t)) { double y = f.op(i, t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class LRDCPap extends LDCPap { final IntAndLongPredicate selector; LRDCPap(ForkJoinPool ex, int origin, int fence, long[] array, IntAndLongPredicate selector, IntAndLongToDouble op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelLongArrayWithDoubleMapping withMapping(DoubleOp op) { return new LRDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithLongMapping withMapping(DoubleToLong op) { return new LRLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithMapping< U> withMapping (DoubleToObject op) { return new LROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndDoubleToObject mapper) { return new LROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndDoubleToDouble mapper) { return new LRDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndDoubleToLong mapper) { return new LRLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, DoubleProcedure procedure) { final IntAndLongPredicate s = selector; final long[] a = this.array; final IntAndLongToDouble f = op; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(i, x)) procedure.op(f.op(i, x)); } } double leafReduce(int lo, int hi, DoubleReducer reducer, double base) { final IntAndLongPredicate s = selector; final IntAndLongToDouble f = op; boolean gotFirst = false; double r = base; final long[] a = this.array; for (int i = lo; i < hi; ++i) { long t = a[i]; if (s.op(i, t)) { double y = f.op(i, t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } // long-combined abstract static class OLMPap extends ParallelArrayWithLongMapping { final ObjectToLong op; OLMPap(ForkJoinPool ex, int origin, int fence, T[] array, final ObjectToLong op) { super(ex, origin, fence, array); this.op = op; } final boolean hasMap() { return true; } final long lget(int i) { return op.op(this.array[i]); } final Object oget(int i) { return Long.valueOf(lget(i)); } final double dget(int i) { return (double)(lget(i)); } final void leafTransfer(int lo, int hi, long[] dest, int offset) { final ObjectToLong f = op; final Object[] a = this.array; for (int i = lo; i < hi; ++i) dest[offset++] = f.op(a[i]); } final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, long[] dest, int offset) { final Object[] a = this.array; final ObjectToLong f = op; for (int i = loIdx; i < hiIdx; ++i) dest[offset++] = f.op(a[indices[i]]); } } abstract static class DLMPap extends ParallelDoubleArrayWithLongMapping { final DoubleToLong op; DLMPap(ForkJoinPool ex, int origin, int fence, double[] array, DoubleToLong op) { super(ex, origin, fence, array); this.op = op; } final boolean hasMap() { return true; } final long lget(int i) { return op.op(this.array[i]); } final Object oget(int i) { return Long.valueOf(lget(i)); } final double dget(int i) { return (double)(lget(i)); } final void leafTransfer(int lo, int hi, long[] dest, int offset) { final double[] a = this.array; final DoubleToLong f = op; for (int i = lo; i < hi; ++i) dest[offset++] = f.op(a[i]); } final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, long[] dest, int offset) { final double[] a = this.array; final DoubleToLong f = op; for (int i = loIdx; i < hiIdx; ++i) dest[offset++] = f.op(a[indices[i]]); } } abstract static class LLMPap extends ParallelLongArrayWithLongMapping { final LongOp op; LLMPap(ForkJoinPool ex, int origin, int fence, long[] array, LongOp op) { super(ex, origin, fence, array); this.op = op; } final boolean hasMap() { return true; } final long lget(int i) { return op.op(this.array[i]); } final Object oget(int i) { return Long.valueOf(lget(i)); } final double dget(int i) { return (double)(lget(i)); } final void leafTransfer(int lo, int hi, long[] dest, int offset) { final long[] a = this.array; final LongOp f = op; for (int i = lo; i < hi; ++i) dest[offset++] = f.op(a[i]); } final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, long[] dest, int offset) { final long[] a = this.array; final LongOp f = op; for (int i = loIdx; i < hiIdx; ++i) dest[offset++] = f.op(a[indices[i]]); } } // long-combined, unfiltered static final class OULMPap extends OLMPap { OULMPap(ForkJoinPool ex, int origin, int fence, T[] array, ObjectToLong op) { super(ex, origin, fence, array, op); } public ParallelArrayWithDoubleMapping withMapping(LongToDouble op) { return new OUDMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithLongMapping withMapping(LongOp op) { return new OULMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithMapping withMapping (LongToObject op) { return new OUOMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new OUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new OUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new OULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, LongProcedure procedure) { final Object[] a = this.array; final ObjectToLong f = op; for (int i = lo; i < hi; ++i) procedure.op(f.op(a[i])); } long leafReduce(int lo, int hi, LongReducer reducer, long base) { if (lo >= hi) return base; final Object[] a = this.array; final ObjectToLong f = op; long r = f.op(a[lo]); for (int i = lo+1; i < hi; ++i) r = reducer.op(r, f.op(a[i])); return r; } } static final class DULMPap extends DLMPap { DULMPap(ForkJoinPool ex, int origin, int fence, double[] array, DoubleToLong op) { super(ex, origin, fence, array, op); } public ParallelDoubleArrayWithDoubleMapping withMapping (LongToDouble op) { return new DUDMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithLongMapping withMapping (LongOp op) { return new DULMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithMapping withMapping (LongToObject op) { return new DUOMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new DUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new DUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new DULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, LongProcedure procedure) { final double[] a = this.array; final DoubleToLong f = op; for (int i = lo; i < hi; ++i) procedure.op(f.op(a[i])); } long leafReduce(int lo, int hi, LongReducer reducer, long base) { if (lo >= hi) return base; final double[] a = this.array; final DoubleToLong f = op; long r = f.op(a[lo]); for (int i = lo+1; i < hi; ++i) r = reducer.op(r, f.op(a[i])); return r; } } static final class LULMPap extends LLMPap { LULMPap(ForkJoinPool ex, int origin, int fence, long[] array, LongOp op) { super(ex, origin, fence, array, op); } public ParallelLongArrayWithLongMapping withMapping(LongOp op) { return new LULMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithDoubleMapping withMapping(LongToDouble op) { return new LUDMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithMapping withMapping (LongToObject op) { return new LUOMPap(ex, origin, fence, array, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new LUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new LUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new LULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, LongProcedure procedure) { final LongOp f = op; final long[] a = this.array; for (int i = lo; i < hi; ++i) procedure.op(f.op(a[i])); } long leafReduce(int lo, int hi, LongReducer reducer, long base) { if (lo >= hi) return base; final long[] a = this.array; final LongOp f = op; long r = f.op(a[lo]); for (int i = lo+1; i < hi; ++i) r = reducer.op(r, f.op(a[i])); return r; } } // long-combined, filtered static final class OFLMPap extends OLMPap { final Predicate selector; OFLMPap(ForkJoinPool ex, int origin, int fence, T[] array, Predicate selector, ObjectToLong op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelArrayWithDoubleMapping withMapping (LongToDouble op) { return new OFDMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithLongMapping withMapping (LongOp op) { return new OFLMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithMapping withMapping (LongToObject op) { return new OFOMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new OFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new OFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new OFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, LongProcedure procedure) { final Predicate s = selector; final Object[] a = this.array; final ObjectToLong f = op; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(x)) procedure.op(f.op(x)); } } long leafReduce(int lo, int hi, LongReducer reducer, long base) { final Predicate s = selector; final ObjectToLong f = op; boolean gotFirst = false; long r = base; final Object[] a = this.array; for (int i = lo; i < hi; ++i) { Object t = a[i]; if (s.op(t)) { long y = f.op(t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class DFLMPap extends DLMPap { final DoublePredicate selector; DFLMPap(ForkJoinPool ex, int origin, int fence, double[] array, DoublePredicate selector, DoubleToLong op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelDoubleArrayWithDoubleMapping withMapping (LongToDouble op) { return new DFDMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithLongMapping withMapping (LongOp op) { return new DFLMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithMapping withMapping (LongToObject op) { return new DFOMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new DFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new DFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new DFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, LongProcedure procedure) { final DoublePredicate s = selector; final DoubleToLong f = op; final double[] a = this.array; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(x)) procedure.op(f.op(x)); } } long leafReduce(int lo, int hi, LongReducer reducer, long base) { boolean gotFirst = false; long r = base; final double[] a = this.array; final DoublePredicate s = selector; final DoubleToLong f = op; for (int i = lo; i < hi; ++i) { double t = a[i]; if (s.op(t)) { long y = f.op(t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class LFLMPap extends LLMPap { final LongPredicate selector; LFLMPap(ForkJoinPool ex, int origin, int fence, long[] array, LongPredicate selector, LongOp op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelLongArrayWithLongMapping withMapping(LongOp op) { return new LFLMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithDoubleMapping withMapping(LongToDouble op) { return new LFDMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithMapping withMapping (LongToObject op) { return new LFOMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new LFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new LFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new LFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, LongProcedure procedure) { final LongPredicate s = selector; final LongOp f = op; final long[] a = this.array; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(x)) procedure.op(f.op(x)); } } long leafReduce(int lo, int hi, LongReducer reducer, long base) { final LongPredicate s = selector; final LongOp f = op; boolean gotFirst = false; long r = base; final long[] a = this.array; for (int i = lo; i < hi; ++i) { long t = a[i]; if (s.op(t)) { long y = f.op(t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } // Long-mapped, relational static final class ORLMPap extends OLMPap { final IntAndObjectPredicate selector; ORLMPap(ForkJoinPool ex, int origin, int fence, T[] array, IntAndObjectPredicate selector, ObjectToLong op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelArrayWithDoubleMapping withMapping (LongToDouble op) { return new ORDMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithLongMapping withMapping (LongOp op) { return new ORLMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithMapping withMapping (LongToObject op) { return new OROMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new OROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new ORDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new ORLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, LongProcedure procedure) { final IntAndObjectPredicate s = selector; final Object[] a = this.array; final ObjectToLong f = op; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(i, x)) procedure.op(f.op(x)); } } long leafReduce(int lo, int hi, LongReducer reducer, long base) { final IntAndObjectPredicate s = selector; final ObjectToLong f = op; boolean gotFirst = false; long r = base; final Object[] a = this.array; for (int i = lo; i < hi; ++i) { Object t = a[i]; if (s.op(i, t)) { long y = f.op(t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class DRLMPap extends DLMPap { final IntAndDoublePredicate selector; DRLMPap(ForkJoinPool ex, int origin, int fence, double[] array, IntAndDoublePredicate selector, DoubleToLong op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelDoubleArrayWithDoubleMapping withMapping (LongToDouble op) { return new DRDMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithLongMapping withMapping (LongOp op) { return new DRLMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithMapping withMapping (LongToObject op) { return new DROMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new DROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new DRDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new DRLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, LongProcedure procedure) { final IntAndDoublePredicate s = selector; final DoubleToLong f = op; final double[] a = this.array; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(i, x)) procedure.op(f.op(x)); } } long leafReduce(int lo, int hi, LongReducer reducer, long base) { boolean gotFirst = false; long r = base; final double[] a = this.array; final IntAndDoublePredicate s = selector; final DoubleToLong f = op; for (int i = lo; i < hi; ++i) { double t = a[i]; if (s.op(i, t)) { long y = f.op(t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class LRLMPap extends LLMPap { final IntAndLongPredicate selector; LRLMPap(ForkJoinPool ex, int origin, int fence, long[] array, IntAndLongPredicate selector, LongOp op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelLongArrayWithLongMapping withMapping(LongOp op) { return new LRLMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithDoubleMapping withMapping(LongToDouble op) { return new LRDMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithMapping withMapping (LongToObject op) { return new LROMPap(ex, origin, fence, array, selector, CommonOps.compoundOp(this.op, op)); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new LROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new LRDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new LRLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, LongProcedure procedure) { final IntAndLongPredicate s = selector; final LongOp f = op; final long[] a = this.array; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(i, x)) procedure.op(f.op(x)); } } long leafReduce(int lo, int hi, LongReducer reducer, long base) { final IntAndLongPredicate s = selector; final LongOp f = op; boolean gotFirst = false; long r = base; final long[] a = this.array; for (int i = lo; i < hi; ++i) { long t = a[i]; if (s.op(i, t)) { long y = f.op(t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } // long-combined abstract static class OLCPap extends ParallelArrayWithLongMapping { final IntAndObjectToLong op; OLCPap(ForkJoinPool ex, int origin, int fence, T[] array, IntAndObjectToLong op) { super(ex, origin, fence, array); this.op = op; } final boolean hasMap() { return true; } final long lget(int i) { return op.op(i, this.array[i]); } final Object oget(int i) { return Long.valueOf(lget(i)); } final double dget(int i) { return (double)(lget(i)); } final void leafTransfer(int lo, int hi, long[] dest, int offset) { final IntAndObjectToLong f = op; final Object[] a = this.array; for (int i = lo; i < hi; ++i) dest[offset++] = f.op(i, a[i]); } final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, long[] dest, int offset) { final Object[] a = this.array; final IntAndObjectToLong f = op; for (int i = loIdx; i < hiIdx; ++i) { int idx = indices[i]; dest[offset++] = f.op(idx, a[idx]); } } } abstract static class DLCPap extends ParallelDoubleArrayWithLongMapping { final IntAndDoubleToLong op; DLCPap(ForkJoinPool ex, int origin, int fence, double[] array, IntAndDoubleToLong op) { super(ex, origin, fence, array); this.op = op; } final boolean hasMap() { return true; } final long lget(int i) { return op.op(i, this.array[i]); } final Object oget(int i) { return Long.valueOf(lget(i)); } final double dget(int i) { return (double)(lget(i)); } final void leafTransfer(int lo, int hi, long[] dest, int offset) { final IntAndDoubleToLong f = op; final double[] a = this.array; for (int i = lo; i < hi; ++i) dest[offset++] = f.op(i, a[i]); } final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, long[] dest, int offset) { final double[] a = this.array; final IntAndDoubleToLong f = op; for (int i = loIdx; i < hiIdx; ++i) { int idx = indices[i]; dest[offset++] = f.op(idx, a[idx]); } } } abstract static class LLCPap extends ParallelLongArrayWithLongMapping { final IntAndLongToLong op; LLCPap(ForkJoinPool ex, int origin, int fence, long[] array, IntAndLongToLong op) { super(ex, origin, fence, array); this.op = op; } final boolean hasMap() { return true; } final long lget(int i) { return op.op(i, this.array[i]); } final Object oget(int i) { return Long.valueOf(lget(i)); } final double dget(int i) { return (double)(lget(i)); } final void leafTransfer(int lo, int hi, long[] dest, int offset) { final IntAndLongToLong f = op; final long[] a = this.array; for (int i = lo; i < hi; ++i) dest[offset++] = f.op(i, a[i]); } final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, long[] dest, int offset) { final long[] a = this.array; final IntAndLongToLong f = op; for (int i = loIdx; i < hiIdx; ++i) { int idx = indices[i]; dest[offset++] = f.op(idx, a[idx]); } } } // long-combined, unfiltered static final class OULCPap extends OLCPap { OULCPap(ForkJoinPool ex, int origin, int fence, T[] array, IntAndObjectToLong op) { super(ex, origin, fence, array, op); } public ParallelArrayWithDoubleMapping withMapping(LongToDouble op) { return new OUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelArrayWithLongMapping withMapping(LongOp op) { return new OULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelArrayWithMapping withMapping (LongToObject op) { return new OUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new OUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new OUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new OULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, LongProcedure procedure) { final IntAndObjectToLong f = op; final Object[] a = this.array; for (int i = lo; i < hi; ++i) procedure.op(f.op(i, a[i])); } long leafReduce(int lo, int hi, LongReducer reducer, long base) { if (lo >= hi) return base; final Object[] a = this.array; final IntAndObjectToLong f = op; long r = f.op(lo, a[lo]); for (int i = lo+1; i < hi; ++i) r = reducer.op(r, f.op(i, a[i])); return r; } } static final class DULCPap extends DLCPap { DULCPap(ForkJoinPool ex, int origin, int fence, double[] array, IntAndDoubleToLong op) { super(ex, origin, fence, array, op); } public ParallelDoubleArrayWithDoubleMapping withMapping (LongToDouble op) { return new DUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithLongMapping withMapping(LongOp op) { return new DULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithMapping< U> withMapping (LongToObject op) { return new DUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new DUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new DUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new DULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, LongProcedure procedure) { final IntAndDoubleToLong f = op; final double[] a = this.array; for (int i = lo; i < hi; ++i) procedure.op(f.op(i, a[i])); } long leafReduce(int lo, int hi, LongReducer reducer, long base) { if (lo >= hi) return base; final double[] a = this.array; final IntAndDoubleToLong f = op; long r = f.op(lo, a[lo]); for (int i = lo+1; i < hi; ++i) r = reducer.op(r, f.op(i, a[i])); return r; } } static final class LULCPap extends LLCPap { LULCPap(ForkJoinPool ex, int origin, int fence, long[] array, IntAndLongToLong op) { super(ex, origin, fence, array, op); } public ParallelLongArrayWithDoubleMapping withMapping(LongToDouble op) { return new LUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithLongMapping withMapping(LongOp op) { return new LULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithMapping< U> withMapping (LongToObject op) { return new LUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new LUOCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new LUDCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new LULCPap(ex, origin, fence, array, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, LongProcedure procedure) { final IntAndLongToLong f = op; final long[] a = this.array; for (int i = lo; i < hi; ++i) procedure.op(f.op(i, a[i])); } long leafReduce(int lo, int hi, LongReducer reducer, long base) { if (lo >= hi) return base; final long[] a = this.array; final IntAndLongToLong f = op; long r = f.op(lo, a[lo]); for (int i = lo+1; i < hi; ++i) r = reducer.op(r, f.op(i, a[i])); return r; } } // long-combined, filtered static final class OFLCPap extends OLCPap { final Predicate selector; OFLCPap(ForkJoinPool ex, int origin, int fence, T[] array, Predicate selector, IntAndObjectToLong op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelArrayWithDoubleMapping withMapping(LongToDouble op) { return new OFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelArrayWithLongMapping withMapping(LongOp op) { return new OFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelArrayWithMapping withMapping (LongToObject op) { return new OFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new OFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new OFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new OFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, LongProcedure procedure) { final Predicate s = selector; final Object[] a = this.array; final IntAndObjectToLong f = op; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(x)) procedure.op(f.op(i, x)); } } long leafReduce(int lo, int hi, LongReducer reducer, long base) { final Predicate s = selector; final IntAndObjectToLong f = op; boolean gotFirst = false; long r = base; final Object[] a = this.array; for (int i = lo; i < hi; ++i) { Object t = a[i]; if (s.op(t)) { long y = f.op(i, t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class DFLCPap extends DLCPap { final DoublePredicate selector; DFLCPap(ForkJoinPool ex, int origin, int fence, double[] array, DoublePredicate selector, IntAndDoubleToLong op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelDoubleArrayWithDoubleMapping withMapping (LongToDouble op) { return new DFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithLongMapping withMapping(LongOp op) { return new DFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithMapping< U> withMapping (LongToObject op) { return new DFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new DFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new DFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new DFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, LongProcedure procedure) { final DoublePredicate s = selector; final double[] a = this.array; final IntAndDoubleToLong f = op; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(x)) procedure.op(f.op(i, x)); } } long leafReduce(int lo, int hi, LongReducer reducer, long base) { final DoublePredicate s = selector; final IntAndDoubleToLong f = op; boolean gotFirst = false; long r = base; final double[] a = this.array; for (int i = lo; i < hi; ++i) { double t = a[i]; if (s.op(t)) { long y = f.op(i, t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class LFLCPap extends LLCPap { final LongPredicate selector; LFLCPap(ForkJoinPool ex, int origin, int fence, long[] array, LongPredicate selector, IntAndLongToLong op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(this.array[i]); } public ParallelLongArrayWithDoubleMapping withMapping(LongToDouble op) { return new LFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithLongMapping withMapping(LongOp op) { return new LFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithMapping< U> withMapping (LongToObject op) { return new LFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new LFOCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new LFDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new LFLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, LongProcedure procedure) { final LongPredicate s = selector; final long[] a = this.array; final IntAndLongToLong f = op; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(x)) procedure.op(f.op(i, x)); } } long leafReduce(int lo, int hi, LongReducer reducer, long base) { final LongPredicate s = selector; final IntAndLongToLong f = op; boolean gotFirst = false; long r = base; final long[] a = this.array; for (int i = lo; i < hi; ++i) { long t = a[i]; if (s.op(t)) { long y = f.op(i, t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } // long-combined, relational static final class ORLCPap extends OLCPap { final IntAndObjectPredicate selector; ORLCPap(ForkJoinPool ex, int origin, int fence, T[] array, IntAndObjectPredicate selector, IntAndObjectToLong op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelArrayWithDoubleMapping withMapping(LongToDouble op) { return new ORDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelArrayWithLongMapping withMapping(LongOp op) { return new ORLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelArrayWithMapping withMapping (LongToObject op) { return new OROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new OROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new ORDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new ORLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, LongProcedure procedure) { final IntAndObjectPredicate s = selector; final Object[] a = this.array; final IntAndObjectToLong f = op; for (int i = lo; i < hi; ++i) { Object x = a[i]; if (s.op(i, x)) procedure.op(f.op(i, x)); } } long leafReduce(int lo, int hi, LongReducer reducer, long base) { final IntAndObjectPredicate s = selector; final IntAndObjectToLong f = op; boolean gotFirst = false; long r = base; final Object[] a = this.array; for (int i = lo; i < hi; ++i) { Object t = a[i]; if (s.op(i, t)) { long y = f.op(i, t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class DRLCPap extends DLCPap { final IntAndDoublePredicate selector; DRLCPap(ForkJoinPool ex, int origin, int fence, double[] array, IntAndDoublePredicate selector, IntAndDoubleToLong op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelDoubleArrayWithDoubleMapping withMapping (LongToDouble op) { return new DRDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithLongMapping withMapping(LongOp op) { return new DRLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithMapping< U> withMapping (LongToObject op) { return new DROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelDoubleArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new DROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new DRDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelDoubleArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new DRLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, LongProcedure procedure) { final IntAndDoublePredicate s = selector; final double[] a = this.array; final IntAndDoubleToLong f = op; for (int i = lo; i < hi; ++i) { double x = a[i]; if (s.op(i, x)) procedure.op(f.op(i, x)); } } long leafReduce(int lo, int hi, LongReducer reducer, long base) { final IntAndDoublePredicate s = selector; final IntAndDoubleToLong f = op; boolean gotFirst = false; long r = base; final double[] a = this.array; for (int i = lo; i < hi; ++i) { double t = a[i]; if (s.op(i, t)) { long y = f.op(i, t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } static final class LRLCPap extends LLCPap { final IntAndLongPredicate selector; LRLCPap(ForkJoinPool ex, int origin, int fence, long[] array, IntAndLongPredicate selector, IntAndLongToLong op) { super(ex, origin, fence, array, op); this.selector = selector; } boolean hasFilter() { return true; } boolean isSelected(int i) { return selector.op(i, this.array[i]); } public ParallelLongArrayWithDoubleMapping withMapping(LongToDouble op) { return new LRDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithLongMapping withMapping(LongOp op) { return new LRLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithMapping< U> withMapping (LongToObject op) { return new LROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, op)); } public ParallelLongArrayWithMapping withIndexedMapping (IntAndLongToObject mapper) { return new LROCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithDoubleMapping withIndexedMapping (IntAndLongToDouble mapper) { return new LRDCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } public ParallelLongArrayWithLongMapping withIndexedMapping (IntAndLongToLong mapper) { return new LRLCPap(ex, origin, fence, array, selector, compoundIndexedOp(this.op, mapper)); } void leafApply(int lo, int hi, LongProcedure procedure) { final IntAndLongPredicate s = selector; final long[] a = this.array; final IntAndLongToLong f = op; for (int i = lo; i < hi; ++i) { long x = a[i]; if (s.op(i, x)) procedure.op(f.op(i, x)); } } long leafReduce(int lo, int hi, LongReducer reducer, long base) { final IntAndLongPredicate s = selector; final IntAndLongToLong f = op; boolean gotFirst = false; long r = base; final long[] a = this.array; for (int i = lo; i < hi; ++i) { long t = a[i]; if (s.op(i, t)) { long y = f.op(i, t); if (!gotFirst) { gotFirst = true; r = y; } else r = reducer.op(r, y); } } return r; } } /* * Iterator support */ class SequentiallyAsDouble implements Iterable { public Iterator iterator() { if (hasFilter()) return new FilteredAsDoubleIterator(); else return new UnfilteredAsDoubleIterator(); } } class UnfilteredAsDoubleIterator implements Iterator { int cursor = origin; public boolean hasNext() { return cursor < fence; } public Double next() { if (cursor >= fence) throw new NoSuchElementException(); return Double.valueOf(dget(cursor++)); } public void remove() { throw new UnsupportedOperationException(); } } class FilteredAsDoubleIterator implements Iterator { double next; int cursor; FilteredAsDoubleIterator() { cursor = origin; advance(); } private void advance() { while (cursor < fence) { if (isSelected(cursor)) { next = dget(cursor); break; } cursor++; } } public boolean hasNext() { return cursor < fence; } public Double next() { if (cursor >= fence) throw new NoSuchElementException(); Double x = Double.valueOf(next); cursor++; advance(); return x; } public void remove() { throw new UnsupportedOperationException(); } } class SequentiallyAsLong implements Iterable { public Iterator iterator() { if (hasFilter()) return new FilteredAsLongIterator(); else return new UnfilteredAsLongIterator(); } } class UnfilteredAsLongIterator implements Iterator { int cursor = origin; public boolean hasNext() { return cursor < fence; } public Long next() { if (cursor >= fence) throw new NoSuchElementException(); return Long.valueOf(lget(cursor++)); } public void remove() { throw new UnsupportedOperationException(); } } class FilteredAsLongIterator implements Iterator { long next; int cursor; FilteredAsLongIterator() { cursor = origin; advance(); } private void advance() { while (cursor < fence) { if (isSelected(cursor)) { next = lget(cursor); break; } cursor++; } } public boolean hasNext() { return cursor < fence; } public Long next() { if (cursor >= fence) throw new NoSuchElementException(); Long x = Long.valueOf(next); cursor++; advance(); return x; } public void remove() { throw new UnsupportedOperationException(); } } class Sequentially implements Iterable { public Iterator iterator() { if (hasFilter()) return new FilteredIterator(); else return new UnfilteredIterator(); } } class UnfilteredIterator implements Iterator { int cursor = origin; public boolean hasNext() { return cursor < fence; } public U next() { if (cursor >= fence) throw new NoSuchElementException(); return (U)oget(cursor++); } public void remove() { throw new UnsupportedOperationException(); } } class FilteredIterator implements Iterator { Object next; int cursor; FilteredIterator() { cursor = origin; advance(); } private void advance() { while (cursor < fence) { if (isSelected(cursor)) { next = oget(cursor); break; } cursor++; } } public boolean hasNext() { return cursor < fence; } public U next() { if (cursor >= fence) throw new NoSuchElementException(); U x = (U)next; cursor++; advance(); return x; } public void remove() { throw new UnsupportedOperationException(); } } // Zillions of little classes to support binary ops // ToDo: specialize to flatten dispatch static IntAndObjectToObject indexedMapper (final BinaryOp combiner, final ParallelArrayWithMapping u, final int origin) { return new IntAndObjectToObject() { final int offset = u.origin - origin; public V op(int i, T a) { return combiner.op(a, (U)(u.oget(i+offset))); } }; } static IntAndObjectToDouble indexedMapper (final ObjectAndObjectToDouble combiner, final ParallelArrayWithMapping u, final int origin) { return new IntAndObjectToDouble() { final int offset = u.origin - origin; public double op(int i, T a) { return combiner.op(a, (U)(u.oget(i+offset))); } }; } static IntAndObjectToLong indexedMapper (final ObjectAndObjectToLong combiner, final ParallelArrayWithMapping u, final int origin) { return new IntAndObjectToLong() { final int offset = u.origin - origin; public long op(int i, T a) { return combiner.op(a, (U)(u.oget(i+offset))); } }; } static IntAndObjectToObject indexedMapper (final ObjectAndDoubleToObject combiner, final ParallelDoubleArrayWithDoubleMapping u, final int origin) { return new IntAndObjectToObject() { final int offset = u.origin - origin; public V op(int i, T a) { return combiner.op(a, u.dget(i+offset)); } }; } static IntAndObjectToDouble indexedMapper (final ObjectAndDoubleToDouble combiner, final ParallelDoubleArrayWithDoubleMapping u, final int origin) { return new IntAndObjectToDouble() { final int offset = u.origin - origin; public double op(int i, T a) { return combiner.op(a, u.dget(i+offset)); } }; } static IntAndObjectToLong indexedMapper (final ObjectAndDoubleToLong combiner, final ParallelDoubleArrayWithDoubleMapping u, final int origin) { return new IntAndObjectToLong() { final int offset = u.origin - origin; public long op(int i, T a) { return combiner.op(a, u.dget(i+offset)); } }; } static IntAndObjectToObject indexedMapper (final ObjectAndLongToObject combiner, final ParallelLongArrayWithLongMapping u, final int origin) { return new IntAndObjectToObject() { final int offset = u.origin - origin; public V op(int i, T a) { return combiner.op(a, u.lget(i+offset)); } }; } static IntAndObjectToDouble indexedMapper (final ObjectAndLongToDouble combiner, final ParallelLongArrayWithLongMapping u, final int origin) { return new IntAndObjectToDouble() { final int offset = u.origin - origin; public double op(int i, T a) { return combiner.op(a, u.lget(i+offset)); } }; } static IntAndObjectToLong indexedMapper (final ObjectAndLongToLong combiner, final ParallelLongArrayWithLongMapping u, final int origin) { return new IntAndObjectToLong() { final int offset = u.origin - origin; public long op(int i, T a) { return combiner.op(a, u.lget(i+offset)); } }; } static IntAndDoubleToObject indexedMapper (final DoubleAndObjectToObject combiner, final ParallelArrayWithMapping u, final int origin) { return new IntAndDoubleToObject() { final int offset = u.origin - origin; public V op(int i, double a) { return combiner.op(a, (U)(u.oget(i+offset))); } }; } static IntAndDoubleToDouble indexedMapper (final DoubleAndObjectToDouble combiner, final ParallelArrayWithMapping u, final int origin) { return new IntAndDoubleToDouble() { final int offset = u.origin - origin; public double op(int i, double a) { return combiner.op(a, (U)(u.oget(i+offset))); } }; } static IntAndDoubleToLong indexedMapper (final DoubleAndObjectToLong combiner, final ParallelArrayWithMapping u, final int origin) { return new IntAndDoubleToLong() { final int offset = u.origin - origin; public long op(int i, double a) { return combiner.op(a, (U)(u.oget(i+offset))); } }; } static IntAndDoubleToObject indexedMapper (final DoubleAndDoubleToObject combiner, final ParallelDoubleArrayWithDoubleMapping u, final int origin) { return new IntAndDoubleToObject() { final int offset = u.origin - origin; public V op(int i, double a) { return combiner.op(a, u.dget(i+offset)); } }; } static IntAndDoubleToDouble indexedMapper (final BinaryDoubleOp combiner, final ParallelDoubleArrayWithDoubleMapping u, final int origin) { return new IntAndDoubleToDouble() { final int offset = u.origin - origin; public double op(int i, double a) { return combiner.op(a, u.dget(i+offset)); } }; } static IntAndDoubleToLong indexedMapper (final DoubleAndDoubleToLong combiner, final ParallelDoubleArrayWithDoubleMapping u, final int origin) { return new IntAndDoubleToLong() { final int offset = u.origin - origin; public long op(int i, double a) { return combiner.op(a, u.dget(i+offset)); } }; } static IntAndDoubleToObject indexedMapper (final DoubleAndLongToObject combiner, final ParallelLongArrayWithLongMapping u, final int origin) { return new IntAndDoubleToObject() { final int offset = u.origin - origin; public V op(int i, double a) { return combiner.op(a, u.lget(i+offset)); } }; } static IntAndDoubleToDouble indexedMapper (final DoubleAndLongToDouble combiner, final ParallelLongArrayWithLongMapping u, final int origin) { return new IntAndDoubleToDouble() { final int offset = u.origin - origin; public double op(int i, double a) { return combiner.op(a, u.lget(i+offset)); } }; } static IntAndDoubleToLong indexedMapper (final DoubleAndLongToLong combiner, final ParallelLongArrayWithLongMapping u, final int origin) { return new IntAndDoubleToLong() { final int offset = u.origin - origin; public long op(int i, double a) { return combiner.op(a, u.lget(i+offset)); } }; } static IntAndLongToObject indexedMapper (final LongAndObjectToObject combiner, final ParallelArrayWithMapping u, final int origin) { return new IntAndLongToObject() { final int offset = u.origin - origin; public V op(int i, long a) { return combiner.op(a, (U)(u.oget(i+offset))); } }; } static IntAndLongToDouble indexedMapper (final LongAndObjectToDouble combiner, final ParallelArrayWithMapping u, final int origin) { return new IntAndLongToDouble() { final int offset = u.origin - origin; public double op(int i, long a) { return combiner.op(a, (U)(u.oget(i+offset))); } }; } static IntAndLongToLong indexedMapper (final LongAndObjectToLong combiner, final ParallelArrayWithMapping u, final int origin) { return new IntAndLongToLong() { final int offset = u.origin - origin; public long op(int i, long a) { return combiner.op(a, (U)(u.oget(i+offset))); } }; } static IntAndLongToObject indexedMapper (final LongAndDoubleToObject combiner, final ParallelDoubleArrayWithDoubleMapping u, final int origin) { return new IntAndLongToObject() { final int offset = u.origin - origin; public V op(int i, long a) { return combiner.op(a, u.dget(i+offset)); } }; } static IntAndLongToDouble indexedMapper (final LongAndDoubleToDouble combiner, final ParallelDoubleArrayWithDoubleMapping u, final int origin) { return new IntAndLongToDouble() { final int offset = u.origin - origin; public double op(int i, long a) { return combiner.op(a, u.dget(i+offset)); } }; } static IntAndLongToLong indexedMapper (final LongAndDoubleToLong combiner, final ParallelDoubleArrayWithDoubleMapping u, final int origin) { return new IntAndLongToLong() { final int offset = u.origin - origin; public long op(int i, long a) { return combiner.op(a, u.dget(i+offset)); } }; } static IntAndLongToObject indexedMapper (final LongAndLongToObject combiner, final ParallelLongArrayWithLongMapping u, final int origin) { return new IntAndLongToObject() { final int offset = u.origin - origin; public V op(int i, long a) { return combiner.op(a, u.lget(i+offset)); } }; } static IntAndLongToDouble indexedMapper (final LongAndLongToDouble combiner, final ParallelLongArrayWithLongMapping u, final int origin) { return new IntAndLongToDouble() { final int offset = u.origin - origin; public double op(int i, long a) { return combiner.op(a, u.lget(i+offset)); } }; } static IntAndLongToLong indexedMapper (final BinaryLongOp combiner, final ParallelLongArrayWithLongMapping u, final int origin) { return new IntAndLongToLong() { final int offset = u.origin - origin; public long op(int i, long a) { return combiner.op(a, u.lget(i+offset)); } }; } static IntAndObjectToObject compoundIndexedOp (final IntAndObjectToObject fst, final IntAndObjectToObject snd) { return new IntAndObjectToObject() { public V op(int i, T a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndObjectToDouble compoundIndexedOp (final IntAndObjectToObject fst, final IntAndObjectToDouble snd) { return new IntAndObjectToDouble() { public double op(int i, T a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndObjectToLong compoundIndexedOp (final IntAndObjectToObject fst, final IntAndObjectToLong snd) { return new IntAndObjectToLong() { public long op(int i, T a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndDoubleToObject compoundIndexedOp (final IntAndDoubleToObject fst, final IntAndObjectToObject snd) { return new IntAndDoubleToObject() { public V op(int i, double a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndDoubleToDouble compoundIndexedOp (final IntAndDoubleToObject fst, final IntAndObjectToDouble snd) { return new IntAndDoubleToDouble() { public double op(int i, double a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndDoubleToLong compoundIndexedOp (final IntAndDoubleToObject fst, final IntAndObjectToLong snd) { return new IntAndDoubleToLong() { public long op(int i, double a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndLongToObject compoundIndexedOp (final IntAndLongToObject fst, final IntAndObjectToObject snd) { return new IntAndLongToObject() { public V op(int i, long a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndLongToDouble compoundIndexedOp (final IntAndLongToObject fst, final IntAndObjectToDouble snd) { return new IntAndLongToDouble() { public double op(int i, long a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndLongToLong compoundIndexedOp (final IntAndLongToObject fst, final IntAndObjectToLong snd) { return new IntAndLongToLong() { public long op(int i, long a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndObjectToObject compoundIndexedOp (final IntAndObjectToDouble fst, final IntAndDoubleToObject snd) { return new IntAndObjectToObject() { public V op(int i, T a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndObjectToDouble compoundIndexedOp (final IntAndObjectToDouble fst, final IntAndDoubleToDouble snd) { return new IntAndObjectToDouble() { public double op(int i, T a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndObjectToLong compoundIndexedOp (final IntAndObjectToLong fst, final IntAndLongToLong snd) { return new IntAndObjectToLong() { public long op(int i, T a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndDoubleToObject compoundIndexedOp (final IntAndDoubleToLong fst, final IntAndLongToObject snd) { return new IntAndDoubleToObject() { public V op(int i, double a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndDoubleToDouble compoundIndexedOp (final IntAndDoubleToDouble fst, final IntAndDoubleToDouble snd) { return new IntAndDoubleToDouble() { public double op(int i, double a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndDoubleToLong compoundIndexedOp (final IntAndDoubleToDouble fst, final IntAndDoubleToLong snd) { return new IntAndDoubleToLong() { public long op(int i, double a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndLongToObject compoundIndexedOp (final IntAndLongToDouble fst, final IntAndDoubleToObject snd) { return new IntAndLongToObject() { public V op(int i, long a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndLongToDouble compoundIndexedOp (final IntAndLongToDouble fst, final IntAndDoubleToDouble snd) { return new IntAndLongToDouble() { public double op(int i, long a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndLongToLong compoundIndexedOp (final IntAndLongToDouble fst, final IntAndDoubleToLong snd) { return new IntAndLongToLong() { public long op(int i, long a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndObjectToObject compoundIndexedOp (final IntAndObjectToLong fst, final IntAndLongToObject snd) { return new IntAndObjectToObject() { public V op(int i, T a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndObjectToDouble compoundIndexedOp (final IntAndObjectToLong fst, final IntAndLongToDouble snd) { return new IntAndObjectToDouble() { public double op(int i, T a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndObjectToLong compoundIndexedOp (final IntAndObjectToDouble fst, final IntAndDoubleToLong snd) { return new IntAndObjectToLong() { public long op(int i, T a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndDoubleToObject compoundIndexedOp (final IntAndDoubleToDouble fst, final IntAndDoubleToObject snd) { return new IntAndDoubleToObject() { public V op(int i, double a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndDoubleToDouble compoundIndexedOp (final IntAndDoubleToLong fst, final IntAndLongToDouble snd) { return new IntAndDoubleToDouble() { public double op(int i, double a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndDoubleToLong compoundIndexedOp (final IntAndDoubleToLong fst, final IntAndLongToLong snd) { return new IntAndDoubleToLong() { public long op(int i, double a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndLongToObject compoundIndexedOp (final IntAndLongToLong fst, final IntAndLongToObject snd) { return new IntAndLongToObject() { public V op(int i, long a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndLongToDouble compoundIndexedOp (final IntAndLongToLong fst, final IntAndLongToDouble snd) { return new IntAndLongToDouble() { public double op(int i, long a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndLongToLong compoundIndexedOp (final IntAndLongToLong fst, final IntAndLongToLong snd) { return new IntAndLongToLong() { public long op(int i, long a) { return snd.op(i, fst.op(i, a)); } }; } static IntAndObjectToObject compoundIndexedOp (final IntAndObjectToObject fst, final Op snd) { return new IntAndObjectToObject() { public V op(int i, T a) { return snd.op(fst.op(i, a)); } }; } static IntAndObjectToDouble compoundIndexedOp (final IntAndObjectToObject fst, final ObjectToDouble snd) { return new IntAndObjectToDouble() { public double op(int i, T a) { return snd.op(fst.op(i, a)); } }; } static IntAndObjectToLong compoundIndexedOp (final IntAndObjectToObject fst, final ObjectToLong snd) { return new IntAndObjectToLong() { public long op(int i, T a) { return snd.op(fst.op(i, a)); } }; } static IntAndDoubleToObject compoundIndexedOp (final IntAndDoubleToObject fst, final Op snd) { return new IntAndDoubleToObject() { public V op(int i, double a) { return snd.op(fst.op(i, a)); } }; } static IntAndDoubleToDouble compoundIndexedOp (final IntAndDoubleToObject fst, final ObjectToDouble snd) { return new IntAndDoubleToDouble() { public double op(int i, double a) { return snd.op(fst.op(i, a)); } }; } static IntAndDoubleToLong compoundIndexedOp (final IntAndDoubleToObject fst, final ObjectToLong snd) { return new IntAndDoubleToLong() { public long op(int i, double a) { return snd.op(fst.op(i, a)); } }; } static IntAndLongToObject compoundIndexedOp (final IntAndLongToObject fst, final Op snd) { return new IntAndLongToObject() { public V op(int i, long a) { return snd.op(fst.op(i, a)); } }; } static IntAndLongToDouble compoundIndexedOp (final IntAndLongToObject fst, final ObjectToDouble snd) { return new IntAndLongToDouble() { public double op(int i, long a) { return snd.op(fst.op(i, a)); } }; } static IntAndLongToLong compoundIndexedOp (final IntAndLongToObject fst, final ObjectToLong snd) { return new IntAndLongToLong() { public long op(int i, long a) { return snd.op(fst.op(i, a)); } }; } static IntAndObjectToObject compoundIndexedOp (final IntAndObjectToDouble fst, final DoubleToObject snd) { return new IntAndObjectToObject() { public V op(int i, T a) { return snd.op(fst.op(i, a)); } }; } static IntAndObjectToDouble compoundIndexedOp (final IntAndObjectToDouble fst, final DoubleOp snd) { return new IntAndObjectToDouble() { public double op(int i, T a) { return snd.op(fst.op(i, a)); } }; } static IntAndObjectToLong compoundIndexedOp (final IntAndObjectToDouble fst, final DoubleToLong snd) { return new IntAndObjectToLong() { public long op(int i, T a) { return snd.op(fst.op(i, a)); } }; } static IntAndDoubleToObject compoundIndexedOp (final IntAndDoubleToDouble fst, final DoubleToObject snd) { return new IntAndDoubleToObject() { public V op(int i, double a) { return snd.op(fst.op(i, a)); } }; } static IntAndDoubleToDouble compoundIndexedOp (final IntAndDoubleToDouble fst, final DoubleOp snd) { return new IntAndDoubleToDouble() { public double op(int i, double a) { return snd.op(fst.op(i, a)); } }; } static IntAndDoubleToLong compoundIndexedOp (final IntAndDoubleToDouble fst, final DoubleToLong snd) { return new IntAndDoubleToLong() { public long op(int i, double a) { return snd.op(fst.op(i, a)); } }; } static IntAndLongToObject compoundIndexedOp (final IntAndLongToDouble fst, final DoubleToObject snd) { return new IntAndLongToObject() { public V op(int i, long a) { return snd.op(fst.op(i, a)); } }; } static IntAndLongToDouble compoundIndexedOp (final IntAndLongToDouble fst, final DoubleOp snd) { return new IntAndLongToDouble() { public double op(int i,long a) { return snd.op(fst.op(i, a)); } }; } static IntAndLongToLong compoundIndexedOp (final IntAndLongToDouble fst, final DoubleToLong snd) { return new IntAndLongToLong() { public long op(int i, long a) { return snd.op(fst.op(i, a)); } }; } static IntAndObjectToObject compoundIndexedOp (final IntAndObjectToLong fst, final LongToObject snd) { return new IntAndObjectToObject() { public V op(int i, T a) { return snd.op(fst.op(i, a)); } }; } static IntAndObjectToDouble compoundIndexedOp (final IntAndObjectToLong fst, final LongToDouble snd) { return new IntAndObjectToDouble() { public double op(int i, T a) { return snd.op(fst.op(i, a)); } }; } static IntAndObjectToLong compoundIndexedOp (final IntAndObjectToLong fst, final LongOp snd) { return new IntAndObjectToLong() { public long op(int i, T a) { return snd.op(fst.op(i, a)); } }; } static IntAndDoubleToObject compoundIndexedOp (final IntAndDoubleToLong fst, final LongToObject snd) { return new IntAndDoubleToObject() { public V op(int i, double a) { return snd.op(fst.op(i, a)); } }; } static IntAndDoubleToDouble compoundIndexedOp (final IntAndDoubleToLong fst, final LongToDouble snd) { return new IntAndDoubleToDouble() { public double op(int i, double a) { return snd.op(fst.op(i, a)); } }; } static IntAndDoubleToLong compoundIndexedOp (final IntAndDoubleToLong fst, final LongOp snd) { return new IntAndDoubleToLong() { public long op(int i, double a) { return snd.op(fst.op(i, a)); } }; } static IntAndLongToObject compoundIndexedOp (final IntAndLongToLong fst, final LongToObject snd) { return new IntAndLongToObject() { public V op(int i, long a) { return snd.op(fst.op(i, a)); } }; } static IntAndLongToDouble compoundIndexedOp (final IntAndLongToLong fst, final LongToDouble snd) { return new IntAndLongToDouble() { public double op(int i,long a) { return snd.op(fst.op(i, a)); } }; } static IntAndLongToLong compoundIndexedOp (final IntAndLongToLong fst, final LongOp snd) { return new IntAndLongToLong() { public long op(int i, long a) { return snd.op(fst.op(i, a)); } }; } static IntAndObjectToObject compoundIndexedOp (final Op fst, final IntAndObjectToObject snd) { return new IntAndObjectToObject() { public V op(int i, T a) { return snd.op(i, fst.op(a)); } }; } static IntAndObjectToDouble compoundIndexedOp (final Op fst, final IntAndObjectToDouble snd) { return new IntAndObjectToDouble() { public double op(int i, T a) { return snd.op(i, fst.op(a)); } }; } static IntAndObjectToLong compoundIndexedOp (final Op fst, final IntAndObjectToLong snd) { return new IntAndObjectToLong() { public long op(int i, T a) { return snd.op(i, fst.op(a)); } }; } static IntAndDoubleToObject compoundIndexedOp (final DoubleToObject fst, final IntAndObjectToObject snd) { return new IntAndDoubleToObject() { public V op(int i, double a) { return snd.op(i, fst.op(a)); } }; } static IntAndDoubleToDouble compoundIndexedOp (final DoubleToObject fst, final IntAndObjectToDouble snd) { return new IntAndDoubleToDouble() { public double op(int i, double a) { return snd.op(i, fst.op(a)); } }; } static IntAndDoubleToLong compoundIndexedOp (final DoubleToObject fst, final IntAndObjectToLong snd) { return new IntAndDoubleToLong() { public long op(int i, double a) { return snd.op(i, fst.op(a)); } }; } static IntAndLongToObject compoundIndexedOp (final LongToObject fst, final IntAndObjectToObject snd) { return new IntAndLongToObject() { public V op(int i, long a) { return snd.op(i, fst.op(a)); } }; } static IntAndLongToDouble compoundIndexedOp (final LongToObject fst, final IntAndObjectToDouble snd) { return new IntAndLongToDouble() { public double op(int i, long a) { return snd.op(i, fst.op(a)); } }; } static IntAndLongToLong compoundIndexedOp (final LongToObject fst, final IntAndObjectToLong snd) { return new IntAndLongToLong() { public long op(int i, long a) { return snd.op(i, fst.op(a)); } }; } static IntAndObjectToObject compoundIndexedOp (final ObjectToDouble fst, final IntAndDoubleToObject snd) { return new IntAndObjectToObject() { public V op(int i, T a) { return snd.op(i, fst.op(a)); } }; } static IntAndObjectToDouble compoundIndexedOp (final ObjectToDouble fst, final IntAndDoubleToDouble snd) { return new IntAndObjectToDouble() { public double op(int i, T a) { return snd.op(i, fst.op(a)); } }; } static IntAndObjectToLong compoundIndexedOp (final ObjectToDouble fst, final IntAndDoubleToLong snd) { return new IntAndObjectToLong() { public long op(int i, T a) { return snd.op(i, fst.op(a)); } }; } static IntAndDoubleToObject compoundIndexedOp (final DoubleOp fst, final IntAndDoubleToObject snd) { return new IntAndDoubleToObject() { public V op(int i, double a) { return snd.op(i, fst.op(a)); } }; } static IntAndDoubleToDouble compoundIndexedOp (final DoubleOp fst, final IntAndDoubleToDouble snd) { return new IntAndDoubleToDouble() { public double op(int i, double a) { return snd.op(i, fst.op(a)); } }; } static IntAndDoubleToLong compoundIndexedOp (final DoubleOp fst, final IntAndDoubleToLong snd) { return new IntAndDoubleToLong() { public long op(int i, double a) { return snd.op(i, fst.op(a)); } }; } static IntAndLongToObject compoundIndexedOp (final LongToDouble fst, final IntAndDoubleToObject snd) { return new IntAndLongToObject() { public V op(int i, long a) { return snd.op(i, fst.op(a)); } }; } static IntAndLongToDouble compoundIndexedOp (final LongToDouble fst, final IntAndDoubleToDouble snd) { return new IntAndLongToDouble() { public double op(int i, long a) { return snd.op(i, fst.op(a)); } }; } static IntAndLongToLong compoundIndexedOp (final LongToDouble fst, final IntAndDoubleToLong snd) { return new IntAndLongToLong() { public long op(int i, long a) { return snd.op(i, fst.op(a)); } }; } static IntAndObjectToObject compoundIndexedOp (final ObjectToLong fst, final IntAndLongToObject snd) { return new IntAndObjectToObject() { public V op(int i, T a) { return snd.op(i, fst.op(a)); } }; } static IntAndObjectToDouble compoundIndexedOp (final ObjectToLong fst, final IntAndLongToDouble snd) { return new IntAndObjectToDouble() { public double op(int i, T a) { return snd.op(i, fst.op(a)); } }; } static IntAndObjectToLong compoundIndexedOp (final ObjectToLong fst, final IntAndLongToLong snd) { return new IntAndObjectToLong() { public long op(int i, T a) { return snd.op(i, fst.op(a)); } }; } static IntAndDoubleToObject compoundIndexedOp (final DoubleToLong fst, final IntAndLongToObject snd) { return new IntAndDoubleToObject() { public V op(int i, double a) { return snd.op(i, fst.op(a)); } }; } static IntAndDoubleToDouble compoundIndexedOp (final DoubleToLong fst, final IntAndLongToDouble snd) { return new IntAndDoubleToDouble() { public double op(int i, double a) { return snd.op(i, fst.op(a)); } }; } static IntAndDoubleToLong compoundIndexedOp (final DoubleToLong fst, final IntAndLongToLong snd) { return new IntAndDoubleToLong() { public long op(int i, double a) { return snd.op(i, fst.op(a)); } }; } static IntAndLongToObject compoundIndexedOp (final LongOp fst, final IntAndLongToObject snd) { return new IntAndLongToObject() { public V op(int i, long a) { return snd.op(i, fst.op(a)); } }; } static IntAndLongToDouble compoundIndexedOp (final LongOp fst, final IntAndLongToDouble snd) { return new IntAndLongToDouble() { public double op(int i, long a) { return snd.op(i, fst.op(a)); } }; } static IntAndLongToLong compoundIndexedOp (final LongOp fst, final IntAndLongToLong snd) { return new IntAndLongToLong() { public long op(int i, long a) { return snd.op(i, fst.op(a)); } }; } // binary predicates static IntAndObjectPredicate indexedSelector (final BinaryPredicate bp, final ParallelArrayWithMapping u, final int origin) { return new IntAndObjectPredicate() { final int offset = u.origin - origin; public boolean op(int i, T a) { int k = i + offset; return u.isSelected(k) && bp.op(a, (U)(u.oget(k))); } }; } static IntAndDoublePredicate indexedSelector (final BinaryDoublePredicate bp, final ParallelDoubleArrayWithDoubleMapping u, final int origin) { return new IntAndDoublePredicate() { final int offset = u.origin - origin; public boolean op(int i, double a) { int k = i + offset; return u.isSelected(k) && bp.op(a, u.dget(k)); } }; } static IntAndLongPredicate indexedSelector (final BinaryLongPredicate bp, final ParallelLongArrayWithLongMapping u, final int origin) { return new IntAndLongPredicate() { final int offset = u.origin - origin; public boolean op(int i, long a) { int k = i + offset; return u.isSelected(k) && bp.op(a, u.lget(k)); } }; } static IntAndObjectPredicate compoundIndexedSelector (final Predicate fst, final IntAndObjectPredicate snd) { return new IntAndObjectPredicate() { public boolean op(int i, T a) { return fst.op(a) && snd.op(i, a); } }; } static IntAndObjectPredicate compoundIndexedSelector (final IntAndObjectPredicate fst, final IntAndObjectPredicate snd) { return new IntAndObjectPredicate() { public boolean op(int i, T a) { return fst.op(i, a) && snd.op(i, a); } }; } static IntAndObjectPredicate compoundIndexedSelector (final IntAndObjectPredicate fst, final Predicate snd) { return new IntAndObjectPredicate() { public boolean op(int i, T a) { return fst.op(i, a) && snd.op(a); } }; } static IntAndDoublePredicate compoundIndexedSelector (final DoublePredicate fst, final IntAndDoublePredicate snd) { return new IntAndDoublePredicate() { public boolean op(int i, double a) { return fst.op(a) && snd.op(i, a); } }; } static IntAndDoublePredicate compoundIndexedSelector (final IntAndDoublePredicate fst, final IntAndDoublePredicate snd) { return new IntAndDoublePredicate() { public boolean op(int i, double a) { return fst.op(i, a) && snd.op(i, a); } }; } static IntAndDoublePredicate compoundIndexedSelector (final IntAndDoublePredicate fst, final DoublePredicate snd) { return new IntAndDoublePredicate() { public boolean op(int i, double a) { return fst.op(i, a) && snd.op(a); } }; } static IntAndLongPredicate compoundIndexedSelector (final LongPredicate fst, final IntAndLongPredicate snd) { return new IntAndLongPredicate() { public boolean op(int i, long a) { return fst.op(a) && snd.op(i, a); } }; } static IntAndLongPredicate compoundIndexedSelector (final IntAndLongPredicate fst, final IntAndLongPredicate snd) { return new IntAndLongPredicate() { public boolean op(int i, long a) { return fst.op(i, a) && snd.op(i, a); } }; } static IntAndLongPredicate compoundIndexedSelector (final IntAndLongPredicate fst, final LongPredicate snd) { return new IntAndLongPredicate() { public boolean op(int i, long a) { return fst.op(i, a) && snd.op(a); } }; } }