/* * 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.*; /** * A prefix view of ParallelArray that causes operations to apply * only to elements for which a selector returns true. * Instances of this class may be constructed only via prefix * methods of ParallelArray or its other prefix classes. */ public abstract class ParallelArrayWithFilter extends ParallelArrayWithMapping { ParallelArrayWithFilter(ForkJoinPool ex, int origin, int fence, T[] array) { super(ex, origin, fence, array); } /** * Replaces elements with the results of applying the given * op to their current values. * @param op the op * @return this (to simplify use in expressions) */ public ParallelArrayWithFilter replaceWithMapping (Op op) { ex.invoke(new PAS.FJOTransform(this, origin, fence, null, op)); return this; } /** * Replaces elements with the results of applying the given * op to their indices. * @param op the op * @return this (to simplify use in expressions) */ public ParallelArrayWithFilter replaceWithMappedIndex (IntToObject op) { ex.invoke(new PAS.FJOIndexMap(this, origin, fence, null, op)); return this; } /** * Replaces elements with the results of applying the given * mapping to each index and current element value. * @param op the op * @return this (to simplify use in expressions) */ public ParallelArrayWithFilter replaceWithMappedIndex (IntAndObjectToObject op) { ex.invoke(new PAS.FJOBinaryIndexMap (this, origin, fence, null, op)); return this; } /** * Replaces elements with results of applying the given generator. * @param generator the generator * @return this (to simplify use in expressions) */ public ParallelArrayWithFilter replaceWithGeneratedValue (Generator generator) { ex.invoke(new PAS.FJOGenerate (this, origin, fence, null, generator)); return this; } /** * Replaces elements with the given value. * @param value the value * @return this (to simplify use in expressions) */ public ParallelArrayWithFilter replaceWithValue(T value) { ex.invoke(new PAS.FJOFill(this, origin, fence, null, value)); return this; } /** * Replaces elements with results of applying * {@code op(thisElement, otherElement)}. * @param other the other array * @param combiner the combiner * @return this (to simplify use in expressions) */ public ParallelArrayWithFilter replaceWithMapping (BinaryOp combiner, ParallelArrayWithMapping other) { ex.invoke(new PAS.FJOPACombineInPlace (this, origin, fence, null, other, other.origin - origin, combiner)); return this; } /** * Replaces elements with results of applying * {@code op(thisElement, otherElement)}. * @param other the other array * @param combiner the combiner * @return this (to simplify use in expressions) */ public ParallelArrayWithFilter replaceWithMapping (BinaryOp combiner, T[] other) { ex.invoke(new PAS.FJOCombineInPlace (this, origin, fence, null, other, -origin, combiner)); return this; } /** * Returns a new ParallelArray containing only non-null unique * elements (that is, without any duplicates). This method * uses each element's {@code equals} method to test for * duplication. * @return the new ParallelArray */ public ParallelArray allUniqueElements() { PAS.UniquifierTable tab = new PAS.UniquifierTable (fence - origin, this, false); PAS.FJOUniquifier f = new PAS.FJOUniquifier (this, origin, fence, null, tab); ex.invoke(f); T[] res = (T[])(tab.uniqueObjects(f.count)); return new ParallelArray(ex, res); } /** * Returns a new ParallelArray containing only non-null unique * elements (that is, without any duplicates). This method * uses reference identity to test for duplication. * @return the new ParallelArray */ public ParallelArray allNonidenticalElements() { PAS.UniquifierTable tab = new PAS.UniquifierTable (fence - origin, this, true); PAS.FJOUniquifier f = new PAS.FJOUniquifier (this, origin, fence, null, tab); ex.invoke(f); T[] res = (T[])(tab.uniqueObjects(f.count)); return new ParallelArray(ex, res); } /** * Returns an operation prefix that causes a method to operate * only on elements for which the current selector (if * present) and the given selector returns true. * @param selector the selector * @return operation prefix */ public abstract ParallelArrayWithFilter withFilter (Predicate selector); /** * Returns an operation prefix that causes a method to operate * only on elements for which the current selector (if * present) and the given binary selector returns true. * @param selector the selector * @return operation prefix */ public ParallelArrayWithFilter withFilter (BinaryPredicate selector, ParallelArrayWithMapping other) { return withIndexedFilter(AbstractParallelAnyArray.indexedSelector(selector, other, origin)); } /** * Returns an operation prefix that causes a method to operate * only on elements for which the current selector (if * present) and the given indexed selector returns true. * @param selector the selector * @return operation prefix */ public abstract ParallelArrayWithFilter withIndexedFilter (IntAndObjectPredicate selector); /** * Returns true if all elements at the same relative positions * of this and other array are equal. * @param other the other array * @return true if equal */ public boolean hasAllEqualElements (ParallelArrayWithMapping other) { return withFilter(CommonOps.inequalityPredicate(), other).anyIndex() < 0; } /** * Returns true if all elements at the same relative positions * of this and other array are identical. * @param other the other array * @return true if equal */ public boolean hasAllIdenticalElements (ParallelArrayWithMapping other) { return withFilter(CommonOps.nonidentityPredicate(), other).anyIndex() < 0; } final void leafTransfer(int lo, int hi, Object[] dest, int offset) { final Object[] a = this.array; for (int i = lo; i < hi; ++i) dest[offset++] = (a[i]); } final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx, Object[] dest, int offset) { final Object[] a = this.array; for (int i = loIdx; i < hiIdx; ++i) dest[offset++] = (a[indices[i]]); } final Object oget(int i) { return this.array[i]; } }