/* * 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/licenses/publicdomain */ package jsr166y.forkjoin; import static jsr166y.forkjoin.Ops.*; import java.util.*; import java.util.concurrent.atomic.*; import java.lang.reflect.Array; /** * 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<T> extends ParallelArrayWithMapping<T,T>{ ParallelArrayWithFilter(ForkJoinExecutor 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<T> replaceWithMapping (Op<? super T, ? extends T> 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<T> replaceWithMappedIndex (IntToObject<? extends T> 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<T> replaceWithMappedIndex (IntAndObjectToObject<? super T, ? extends T> 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<T> replaceWithGeneratedValue (Generator<? extends T> 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<T> replaceWithValue(T value) { ex.invoke(new PAS.FJOFill(this, origin, fence, null, value)); return this; } /** * Replaces elements with results of applying * <tt>op(thisElement, otherElement)</tt> * @param other the other array * @param combiner the combiner * @return this (to simplify use in expressions) */ public <V,W> ParallelArrayWithFilter<T> replaceWithMapping (BinaryOp<? super T, ? super V, ? extends T> combiner, ParallelArrayWithMapping<W,V> other) { ex.invoke(new PAS.FJOPACombineInPlace (this, origin, fence, null, other, other.origin - origin, combiner)); return this; } /** * Replaces elements with results of applying * <tt>op(thisElement, otherElement)</tt> * @param other the other array * @param combiner the combiner * @return this (to simplify use in expressions) */ public ParallelArrayWithFilter<T> replaceWithMapping (BinaryOp<T,T,T> 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 <tt>equals</tt> method to test for * duplication. * @return the new ParallelArray */ public ParallelArray<T> 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<T>(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<T> 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<T>(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<T> withFilter (Predicate<? super T> 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 <V,W> ParallelArrayWithFilter<T> withFilter (BinaryPredicate<? super T, ? super V> selector, ParallelArrayWithMapping<W,V> 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<T> withIndexedFilter (IntAndObjectPredicate<? super T> 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 <U,V> boolean hasAllEqualElements (ParallelArrayWithMapping<U,V> 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 <U,V> boolean hasAllIdenticalElements (ParallelArrayWithMapping<U,V> 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]; } }