ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/extra166y/ParallelArray.java
Revision: 1.18
Committed: Sun Jan 18 20:17:32 2015 UTC (9 years, 3 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.17: +1 -0 lines
Log Message:
exactly one blank line before and after package statements

File Contents

# User Rev Content
1 dl 1.1 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain, as explained at
4 jsr166 1.2 * http://creativecommons.org/publicdomain/zero/1.0/
5 dl 1.1 */
6    
7     package extra166y;
8 jsr166 1.18
9 dl 1.1 import jsr166y.*;
10     import static extra166y.Ops.*;
11     import java.util.*;
12     import java.util.concurrent.atomic.*;
13     import java.lang.reflect.Array;
14    
15     /**
16     * An array supporting parallel operations.
17     *
18     * <p>A ParallelArray maintains a {@link ForkJoinPool} and an
19     * array in order to provide parallel aggregate operations. The main
20     * operations are to <em>apply</em> some procedure to each element, to
21     * <em>map</em> each element to a new element, to <em>replace</em>
22     * each element, to <em>select</em> a subset of elements based on
23     * matching a predicate or ranges of indices, and to <em>reduce</em>
24     * all elements into a single value such as a sum.
25     *
26 jsr166 1.6 * <p>A ParallelArray is constructed by allocating, using, or copying
27 dl 1.1 * an array, using one of the static factory methods {@link #create},
28     * {@link #createEmpty}, {@link #createUsingHandoff} and {@link
29     * #createFromCopy}. Upon construction, the encapsulated array managed
30     * by the ParallelArray must not be shared between threads without
31     * external synchronization. In particular, as is the case with any
32     * array, access by another thread of an element of a ParallelArray
33     * while another operation is in progress has undefined effects.
34     *
35 jsr166 1.6 * <p>The ForkJoinPool used to construct a ParallelArray can be
36 dl 1.1 * shared safely by other threads (and used in other
37     * ParallelArrays). To avoid the overhead associated with creating
38     * multiple executors, it is often a good idea to use the {@link
39     * #defaultExecutor()} across all ParallelArrays. However, you might
40     * choose to use different ones for the sake of controlling processor
41     * usage, isolating faults, and/or ensuring progress.
42     *
43     * <p>A ParallelArray is not a List. It relies on random access across
44     * array elements to support efficient parallel operations. However,
45     * a ParallelArray can be viewed and manipulated as a List, via method
46 jsr166 1.9 * {@link ParallelArray#asList}. The {@code asList} view allows
47 dl 1.1 * incremental insertion and modification of elements while setting up
48     * a ParallelArray, generally before using it for parallel
49     * operations. Similarly, the list view may be useful when accessing
50     * the results of computations in sequential contexts. A
51     * ParallelArray may also be created using the elements of any other
52     * Collection, by constructing from the array returned by the
53 jsr166 1.9 * Collection's {@code toArray} method. The effects of mutative
54     * {@code asList} operations may also be achieved directly using
55 dl 1.1 * method {@link #setLimit} along with element-by-element access
56     * methods {@link #get}</tt> and {@link #set}.
57     *
58     * <p>While ParallelArrays can be based on any kind of an object
59     * array, including "boxed" types such as Long, parallel operations on
60     * scalar "unboxed" type are likely to be substantially more
61     * efficient. For this reason, classes {@link ParallelLongArray} and
62     * {@link ParallelDoubleArray} are also supplied, and designed to
63     * smoothly interoperate with ParallelArrays. You should also use a
64     * ParallelLongArray for processing other integral scalar data
65 jsr166 1.9 * ({@code int}, {@code short}, etc). And similarly use a
66     * ParallelDoubleArray for {@code float} data. (Further
67 dl 1.1 * specializations for these other types would add clutter without
68     * significantly improving performance beyond that of the Long and
69     * Double versions.)
70     *
71 jsr166 1.6 * <p>Most usages of ParallelArray involve sets of operations prefixed
72 dl 1.1 * with range bounds, filters, and mappings (including mappings that
73     * combine elements from other ParallelArrays), using
74 jsr166 1.9 * {@code withBounds}, {@code withFilter}, and {@code withMapping},
75 dl 1.1 * respectively. For example,
76 jsr166 1.9 * {@code aParallelArray.withFilter(aPredicate).all()} creates a new
77 dl 1.1 * ParallelArray containing only those elements matching the
78     * predicate. And for ParallelLongArrays a, b, and c,
79 jsr166 1.9 * {@code a.withMapping(CommonOps.longAdder(),b).withMapping(CommonOps.longAdder(),c).min()}
80 dl 1.1 * returns the minimum value of a[i]+b[i]+c[i] for all i. As
81     * illustrated below, a <em>mapping</em> often represents accessing
82     * some field or invoking some method of an element. These versions
83     * are typically more efficient than performing selections, then
84     * mappings, then other operations in multiple (parallel) steps. The
85     * basic ideas and usages of filtering and mapping are similar to
86     * those in database query systems such as SQL, but take a more
87     * restrictive form. Series of filter and mapping prefixes may each
88     * be cascaded, but all filter prefixes must precede all mapping
89     * prefixes, to ensure efficient execution in a single parallel step.
90     * In cases of combined mapping expressions, this rule is only
91 jsr166 1.9 * dynamically enforced. For example, {@code pa.withMapping(op,
92     * pb.withFilter(f))} will compile but throw an exception upon
93 dl 1.1 * execution because the filter precedes the mapping.
94     *
95     * <p>While series of filters and mappings are allowed, it is
96     * usually more efficient to combine them into single filters or
97     * mappings when possible. For example
98 jsr166 1.9 * {@code pa.withMapping(addOne).withMapping(addOne)} is generally
99     * less efficient than {@code pa.withMapping(addTwo)}. Methods
100     * {@code withIndexedFilter} and {@code withIndexedMapping} may be
101 dl 1.1 * useful when combining such expressions.
102     *
103 jsr166 1.9 * <p>This class includes some reductions, such as {@code min}, that
104 dl 1.1 * are commonly useful for most element types, as well as a combined
105 jsr166 1.9 * version, {@code summary}, that computes all of them in a single
106 dl 1.1 * parallel step, which is normally more efficient than computing each
107     * in turn.
108     *
109     * <p>The methods in this class are designed to perform efficiently
110     * with both large and small pools, even with single-thread pools on
111     * uniprocessors. However, there is some overhead in parallelizing
112     * operations, so short computations on small arrays might not execute
113     * faster than sequential versions, and might even be slower.
114     *
115     * <p><b>Sample usages</b>.
116     *
117     * The main difference between programming with plain arrays and
118     * programming with aggregates is that you must separately define each
119     * of the component functions on elements. For example, the following
120     * returns the maximum Grade Point Average across all senior students,
121 jsr166 1.9 * given a (fictional) {@code Student} class:
122 dl 1.1 *
123     * <pre>
124     * import static Ops.*;
125     * class StudentStatistics {
126     * ParallelArray&lt;Student&gt; students = ...
127     * // ...
128     * public double getMaxSeniorGpa() {
129     * return students.withFilter(isSenior).withMapping(gpaField).max();
130     * }
131     *
132     * // helpers:
133     * static final class IsSenior implements Predicate&lt;Student&gt; {
134     * public boolean op(Student s) { return s.credits &gt; 90; }
135     * }
136     * static final IsSenior isSenior = new IsSenior();
137 jsr166 1.15 * static final class GpaField implements ObjectToDouble&lt;Student&gt; {
138 dl 1.1 * public double op(Student s) { return s.gpa; }
139     * }
140     * static final GpaField gpaField = new GpaField();
141     * }
142     * </pre>
143     */
144     public class ParallelArray<T> extends AbstractParallelAnyArray.OUPap<T> implements Iterable<T> {
145     /*
146     * See classes PAS and AbstractParallelAnyArray for most of the underlying parallel execution
147     * code and explanation.
148     */
149    
150     /**
151     * Returns a common default executor for use in ParallelArrays.
152     * This executor arranges enough parallelism to use most, but not
153     * necessarily all, of the available processors on this system.
154     * @return the executor
155     */
156     public static ForkJoinPool defaultExecutor() {
157     return PAS.defaultExecutor();
158     }
159    
160     /** Lazily constructed list view */
161     AsList listView;
162    
163     /**
164     * Constructor for use by subclasses to create a new ParallelArray
165     * using the given executor, and initially using the supplied
166     * array, with effective size bound by the given limit. This
167     * constructor is designed to enable extensions via
168     * subclassing. To create a ParallelArray, use {@link #create},
169     * {@link #createEmpty}, {@link #createUsingHandoff} or {@link
170     * #createFromCopy}.
171     * @param executor the executor
172     * @param array the array
173     * @param limit the upper bound limit
174     */
175     protected ParallelArray(ForkJoinPool executor, T[] array, int limit) {
176     super(executor, 0, limit, array);
177     if (executor == null || array == null)
178     throw new NullPointerException();
179     if (limit < 0 || limit > array.length)
180     throw new IllegalArgumentException();
181     }
182    
183     /**
184     * Trusted internal version of protected constructor.
185     */
186     ParallelArray(ForkJoinPool executor, T[] array) {
187     super(executor, 0, array.length, array);
188     }
189    
190     /**
191     * Creates a new ParallelArray using the given executor and
192     * an array of the given size constructed using the
193     * indicated base element type.
194     * @param size the array size
195     * @param elementType the type of the elements
196     * @param executor the executor
197     */
198     public static <T> ParallelArray<T> create
199     (int size, Class<? super T> elementType,
200     ForkJoinPool executor) {
201     T[] array = (T[])Array.newInstance(elementType, size);
202     return new ParallelArray<T>(executor, array, size);
203     }
204    
205     /**
206     * Creates a new ParallelArray initially using the given array and
207     * executor. In general, the handed off array should not be used
208     * for other purposes once constructing this ParallelArray. The
209     * given array may be internally replaced by another array in the
210     * course of methods that add or remove elements.
211     * @param handoff the array
212     * @param executor the executor
213     */
214     public static <T> ParallelArray<T> createUsingHandoff
215     (T[] handoff, ForkJoinPool executor) {
216     return new ParallelArray<T>(executor, handoff, handoff.length);
217     }
218    
219     /**
220     * Creates a new ParallelArray using the given executor and
221     * initially holding copies of the given
222     * source elements.
223     * @param source the source of initial elements
224     * @param executor the executor
225     */
226     public static <T> ParallelArray<T> createFromCopy
227     (T[] source, ForkJoinPool executor) {
228     // For now, avoid copyOf so people can compile with Java5
229     int size = source.length;
230     T[] array = (T[])Array.newInstance
231     (source.getClass().getComponentType(), size);
232     System.arraycopy(source, 0, array, 0, size);
233     return new ParallelArray<T>(executor, array, size);
234     }
235    
236     /**
237     * Creates a new ParallelArray using an array of the given size,
238     * initially holding copies of the given source truncated or
239     * padded with nulls to obtain the specified length.
240     * @param source the source of initial elements
241     * @param size the array size
242     * @param executor the executor
243     */
244     public static <T> ParallelArray<T> createFromCopy
245     (int size, T[] source, ForkJoinPool executor) {
246     // For now, avoid copyOf so people can compile with Java5
247     T[] array = (T[])Array.newInstance
248     (source.getClass().getComponentType(), size);
249     System.arraycopy(source, 0, array, 0,
250     Math.min(source.length, size));
251     return new ParallelArray<T>(executor, array, size);
252     }
253    
254     /**
255     * Creates a new ParallelArray using the given executor and an
256     * array of the given size constructed using the indicated base
257     * element type, but with an initial effective size of zero,
258     * enabling incremental insertion via {@link ParallelArray#asList}
259     * operations.
260     * @param size the array size
261     * @param elementType the type of the elements
262     * @param executor the executor
263     */
264     public static <T> ParallelArray<T> createEmpty
265     (int size, Class<? super T> elementType,
266     ForkJoinPool executor) {
267     T[] array = (T[])Array.newInstance(elementType, size);
268     return new ParallelArray<T>(executor, array, 0);
269     }
270    
271     /**
272     * Summary statistics for a possibly bounded, filtered, and/or
273     * mapped ParallelArray.
274     */
275     public static interface SummaryStatistics<T> {
276 jsr166 1.4 /** Returns the number of elements */
277 dl 1.1 public int size();
278 jsr166 1.4 /** Returns the minimum element, or null if empty */
279 dl 1.1 public T min();
280 jsr166 1.4 /** Returns the maximum element, or null if empty */
281 dl 1.1 public T max();
282 jsr166 1.4 /** Returns the index of the minimum element, or -1 if empty */
283 dl 1.1 public int indexOfMin();
284 jsr166 1.4 /** Returns the index of the maximum element, or -1 if empty */
285 dl 1.1 public int indexOfMax();
286     }
287    
288     /**
289 jsr166 1.4 * Returns the executor used for computations.
290 dl 1.1 * @return the executor
291     */
292     public ForkJoinPool getExecutor() { return ex; }
293    
294     /**
295 jsr166 1.8 * Applies the given procedure to elements.
296 dl 1.1 * @param procedure the procedure
297     */
298     public void apply(Procedure<? super T> procedure) {
299     super.apply(procedure);
300     }
301    
302     /**
303 jsr166 1.8 * Returns reduction of elements.
304 dl 1.1 * @param reducer the reducer
305     * @param base the result for an empty array
306     * @return reduction
307     */
308     public T reduce(Reducer<T> reducer, T base) {
309     return super.reduce(reducer, base);
310     }
311    
312     /**
313 jsr166 1.8 * Returns a new ParallelArray holding all elements.
314 dl 1.1 * @return a new ParallelArray holding all elements
315     */
316     public ParallelArray<T> all() {
317     return super.all();
318     }
319    
320     /**
321     * Returns a new ParallelArray with the given element type holding
322 jsr166 1.8 * all elements.
323 dl 1.1 * @param elementType the type of the elements
324     * @return a new ParallelArray holding all elements
325     */
326     public ParallelArray<T> all(Class<? super T> elementType) {
327     return super.all(elementType);
328     }
329    
330     /**
331     * Replaces elements with the results of applying the given transform
332     * to their current values.
333     * @param op the op
334     * @return this (to simplify use in expressions)
335     */
336     public ParallelArray<T> replaceWithMapping
337     (Op<? super T, ? extends T> op) {
338     super.replaceWithMapping(op);
339     return this;
340     }
341    
342     /**
343     * Replaces elements with the results of applying the given
344     * mapping to their indices.
345     * @param op the op
346     * @return this (to simplify use in expressions)
347     */
348     public ParallelArray<T> replaceWithMappedIndex
349     (IntToObject<? extends T> op) {
350     super.replaceWithMappedIndex(op);
351     return this;
352     }
353    
354     /**
355     * Replaces elements with the results of applying the given
356 jsr166 1.8 * mapping to each index and current element value.
357 dl 1.1 * @param op the op
358     * @return this (to simplify use in expressions)
359     */
360     public ParallelArray<T> replaceWithMappedIndex
361     (IntAndObjectToObject<? super T, ? extends T> op) {
362     super.replaceWithMappedIndex(op);
363     return this;
364     }
365    
366     /**
367     * Replaces elements with the results of applying the given
368     * generator.
369     * @param generator the generator
370     * @return this (to simplify use in expressions)
371     */
372     public ParallelArray<T> replaceWithGeneratedValue
373     (Generator<? extends T> generator) {
374     super.replaceWithGeneratedValue(generator);
375     return this;
376     }
377    
378     /**
379     * Replaces elements with the given value.
380     * @param value the value
381     * @return this (to simplify use in expressions)
382     */
383     public ParallelArray<T> replaceWithValue(T value) {
384     super.replaceWithValue(value);
385     return this;
386     }
387    
388     /**
389     * Replaces elements with results of applying
390 jsr166 1.9 * {@code op(thisElement, otherElement)}.
391 dl 1.1 * @param other the other array
392     * @param combiner the combiner
393     * @return this (to simplify use in expressions)
394     */
395     public <V,W> ParallelArray<T> replaceWithMapping
396     (BinaryOp<? super T, ? super V, ? extends T> combiner,
397     ParallelArrayWithMapping<W,V> other) {
398     super.replaceWithMapping(combiner, other);
399     return this;
400     }
401    
402     /**
403     * Replaces elements with results of applying
404 jsr166 1.9 * {@code op(thisElement, otherElement)}.
405 dl 1.1 * @param other the other array
406     * @param combiner the combiner
407     * @return this (to simplify use in expressions)
408     */
409     public ParallelArray<T> replaceWithMapping
410     (BinaryOp<T,T,T> combiner, T[] other) {
411     super.replaceWithMapping(combiner, other);
412     return this;
413     }
414    
415     /**
416     * Returns the index of some element equal to given target,
417 jsr166 1.8 * or -1 if not present.
418 dl 1.1 * @param target the element to search for
419     * @return the index or -1 if not present
420     */
421     public int indexOf(T target) {
422     return super.indexOf(target);
423     }
424    
425     /**
426     * Assuming this array is sorted, returns the index of an element
427     * equal to given target, or -1 if not present. If the array
428     * is not sorted, the results are undefined.
429     * @param target the element to search for
430     * @return the index or -1 if not present
431     */
432     public int binarySearch(T target) {
433     return super.binarySearch(target);
434     }
435    
436     /**
437     * Assuming this array is sorted with respect to the given
438     * comparator, returns the index of an element equal to given
439     * target, or -1 if not present. If the array is not sorted, the
440     * results are undefined.
441     * @param target the element to search for
442     * @param comparator the comparator
443     * @return the index or -1 if not present
444     */
445     public int binarySearch(T target, Comparator<? super T> comparator) {
446     return super.binarySearch(target, comparator);
447     }
448    
449     /**
450     * Returns summary statistics, using the given comparator
451     * to locate minimum and maximum elements.
452     * @param comparator the comparator to use for
453     * locating minimum and maximum elements
454 jsr166 1.7 * @return the summary
455 dl 1.1 */
456     public ParallelArray.SummaryStatistics<T> summary
457     (Comparator<? super T> comparator) {
458     return super.summary(comparator);
459     }
460    
461     /**
462     * Returns summary statistics, assuming that all elements are
463 jsr166 1.7 * Comparables.
464     * @return the summary
465 dl 1.1 */
466     public ParallelArray.SummaryStatistics<T> summary() {
467     return super.summary();
468     }
469    
470     /**
471 jsr166 1.7 * Returns the minimum element, or null if empty.
472 dl 1.1 * @param comparator the comparator
473     * @return minimum element, or null if empty
474     */
475     public T min(Comparator<? super T> comparator) {
476     return super.min(comparator);
477     }
478    
479     /**
480     * Returns the minimum element, or null if empty,
481 jsr166 1.7 * assuming that all elements are Comparables.
482 dl 1.1 * @return minimum element, or null if empty
483 jsr166 1.7 * @throws ClassCastException if any element is not Comparable
484 dl 1.1 */
485     public T min() {
486     return super.min();
487     }
488    
489     /**
490 jsr166 1.7 * Returns the maximum element, or null if empty.
491 dl 1.1 * @param comparator the comparator
492     * @return maximum element, or null if empty
493     */
494     public T max(Comparator<? super T> comparator) {
495     return super.max(comparator);
496     }
497    
498     /**
499 jsr166 1.7 * Returns the maximum element, or null if empty,
500     * assuming that all elements are Comparables.
501 dl 1.1 * @return maximum element, or null if empty
502 jsr166 1.7 * @throws ClassCastException if any element is not Comparable
503 dl 1.1 */
504     public T max() {
505     return super.max();
506     }
507    
508     /**
509     * Replaces each element with the running cumulation of applying
510     * the given reducer. For example, if the contents are the numbers
511 jsr166 1.9 * {@code 1, 2, 3}, and the reducer operation adds numbers, then
512     * after invocation of this method, the contents would be {@code 1,
513 jsr166 1.12 * 3, 6} (that is, {@code 1, 1+2, 1+2+3}).
514 dl 1.1 * @param reducer the reducer
515     * @param base the result for an empty array
516     * @return this (to simplify use in expressions)
517     */
518     public ParallelArray<T> cumulate(Reducer<T> reducer, T base) {
519     super.cumulate(reducer, base);
520     return this;
521     }
522    
523     /**
524     * Replaces each element with the cumulation of applying the given
525     * reducer to all previous values, and returns the total
526 jsr166 1.9 * reduction. For example, if the contents are the numbers {@code 1,
527     * 2, 3}, and the reducer operation adds numbers, then after
528     * invocation of this method, the contents would be {@code 0, 1,
529     * 3} (that is, {@code 0, 0+1, 0+1+2}, and the return value
530 jsr166 1.16 * would be 6 (that is, {@code 1+2+3}).
531 dl 1.1 * @param reducer the reducer
532     * @param base the result for an empty array
533     * @return the total reduction
534     */
535     public T precumulate(Reducer<T> reducer, T base) {
536 jsr166 1.10 return super.precumulate(reducer, base);
537 dl 1.1 }
538    
539     /**
540     * Sorts the array. Unlike Arrays.sort, this sort does
541     * not guarantee that elements with equal keys maintain their
542     * relative position in the array.
543     * @param comparator the comparator to use
544     * @return this (to simplify use in expressions)
545     */
546     public ParallelArray<T> sort(Comparator<? super T> comparator) {
547     super.sort(comparator);
548     return this;
549     }
550    
551     /**
552     * Sorts the array, assuming all elements are Comparable. Unlike
553     * Arrays.sort, this sort does not guarantee that elements
554     * with equal keys maintain their relative position in the array.
555 jsr166 1.14 * @return this (to simplify use in expressions)
556 jsr166 1.7 * @throws ClassCastException if any element is not Comparable
557 dl 1.1 */
558     public ParallelArray<T> sort() {
559     super.sort();
560     return this;
561     }
562    
563     /**
564     * Returns a new ParallelArray containing only the non-null unique
565     * elements of this array (that is, without any duplicates), using
566 jsr166 1.9 * each element's {@code equals} method to test for duplication.
567 dl 1.1 * @return the new ParallelArray
568     */
569     public ParallelArray<T> allUniqueElements() {
570     return super.allUniqueElements();
571     }
572    
573     /**
574     * Returns a new ParallelArray containing only the non-null unique
575     * elements of this array (that is, without any duplicates), using
576     * reference identity to test for duplication.
577     * @return the new ParallelArray
578     */
579     public ParallelArray<T> allNonidenticalElements() {
580     return super.allNonidenticalElements();
581     }
582    
583     /**
584     * Removes from the array all elements for which the given
585     * selector holds.
586     * @param selector the selector
587     * @return this (to simplify use in expressions)
588     */
589     public ParallelArray<T> removeAll(Predicate<? super T> selector) {
590     OFPap<T> v = new OFPap<T>(ex, 0, fence, array, selector);
591     PAS.FJRemoveAllDriver f = new PAS.FJRemoveAllDriver(v, 0, fence);
592     ex.invoke(f);
593     removeSlotsAt(f.offset, fence);
594     return this;
595     }
596    
597     /**
598     * Returns true if all elements at the same relative positions
599     * of this and other array are equal.
600     * @param other the other array
601     * @return true if equal
602     */
603     public <U,V> boolean hasAllEqualElements
604     (ParallelArrayWithMapping<U,V> other) {
605     return super.hasAllEqualElements(other);
606     }
607    
608     /**
609     * Returns true if all elements at the same relative positions
610     * of this and other array are identical.
611     * @param other the other array
612     * @return true if equal
613     */
614     public <U,V> boolean hasAllIdenticalElements
615     (ParallelArrayWithMapping<U,V> other) {
616     return super.hasAllIdenticalElements(other);
617     }
618    
619     /**
620     * Removes consecutive elements that are equal (or null),
621     * shifting others leftward, and possibly decreasing size. This
622     * method may be used after sorting to ensure that this
623     * ParallelArray contains a set of unique elements.
624     * @return this (to simplify use in expressions)
625     */
626     public ParallelArray<T> removeConsecutiveDuplicates() {
627     // Sequential implementation for now
628     int k = 0;
629     int n = fence;
630     Object[] arr = this.array;
631     Object last = null;
632     for (int i = k; i < n; ++i) {
633     Object x = arr[i];
634     if (x != null && (last == null || !last.equals(x)))
635     arr[k++] = last = x;
636     }
637     removeSlotsAt(k, n);
638     return this;
639     }
640    
641     /**
642     * Removes null elements, shifting others leftward, and possibly
643     * decreasing size.
644     * @return this (to simplify use in expressions)
645     */
646     public ParallelArray<T> removeNulls() {
647     // Sequential implementation for now
648     int k = 0;
649     int n = fence;
650     Object[] arr = this.array;
651     for (int i = k; i < n; ++i) {
652     Object x = arr[i];
653     if (x != null)
654     arr[k++] = x;
655     }
656     removeSlotsAt(k, n);
657     return this;
658     }
659    
660     /**
661 jsr166 1.9 * Equivalent to {@code asList().addAll} but specialized for array
662 dl 1.1 * arguments and likely to be more efficient.
663     * @param other the elements to add
664     * @return this (to simplify use in expressions)
665     */
666 jsr166 1.3 public ParallelArray<T> addAll(T[] other) {
667 dl 1.1 int csize = other.length;
668     int end = fence;
669     insertSlotsAt(end, csize);
670     System.arraycopy(other, 0, array, end, csize);
671     return this;
672     }
673    
674     /**
675     * Appends all (possibly bounded, filtered, or mapped) elements of
676     * the given ParallelArray, resizing and/or reallocating this
677     * array if necessary.
678     * @param other the elements to add
679     * @return this (to simplify use in expressions)
680     */
681     public <V> ParallelArray<T> addAll
682     (ParallelArrayWithMapping<V,T> other) {
683     int end = fence;
684     if (other.hasFilter()) {
685     PAS.FJOAppendAllDriver r = new PAS.FJOAppendAllDriver
686     (other, end, array);
687     ex.invoke(r);
688     array = (T[])(r.results);
689     fence = end + r.resultSize;
690     }
691     else {
692     int csize = other.size();
693     insertSlotsAt(end, csize);
694     if (other.hasMap())
695     ex.invoke(new PAS.FJOMap(other, other.origin, other.fence,
696     null, array, end - other.origin));
697     else
698     System.arraycopy(other.array, 0, array, end, csize);
699     }
700     return this;
701     }
702    
703     /**
704     * Returns an operation prefix that causes a method to
705     * operate only on the elements of the array between
706     * firstIndex (inclusive) and upperBound (exclusive).
707     * @param firstIndex the lower bound (inclusive)
708     * @param upperBound the upper bound (exclusive)
709     * @return operation prefix
710     */
711     public ParallelArrayWithBounds<T> withBounds
712     (int firstIndex, int upperBound) {
713     return super.withBounds(firstIndex, upperBound);
714     }
715    
716     /**
717     * Returns an operation prefix that causes a method to operate
718     * only on the elements of the array for which the given selector
719 jsr166 1.7 * returns true.
720 dl 1.1 * @param selector the selector
721     * @return operation prefix
722     */
723     public ParallelArrayWithFilter<T> withFilter
724     (Predicate<? super T> selector) {
725     return super.withFilter(selector);
726     }
727    
728     /**
729     * Returns an operation prefix that causes a method to operate
730     * only on elements for which the given binary selector returns
731 jsr166 1.7 * true.
732 dl 1.1 * @param selector the selector
733     * @return operation prefix
734     */
735     public <V,W> ParallelArrayWithFilter<T> withFilter
736     (BinaryPredicate<? super T, ? super V> selector,
737     ParallelArrayWithMapping<W,V> other) {
738     return super.withFilter(selector, other);
739     }
740    
741     /**
742     * Returns an operation prefix that causes a method to operate
743     * only on elements for which the given indexed selector returns
744 jsr166 1.7 * true.
745 dl 1.1 * @param selector the selector
746     * @return operation prefix
747     */
748     public ParallelArrayWithFilter<T> withIndexedFilter
749     (IntAndObjectPredicate<? super T> selector) {
750     return super.withIndexedFilter(selector);
751     }
752    
753     /**
754     * Returns an operation prefix that causes a method to operate
755     * on mapped elements of the array using the given op.
756     * @param op the op
757     * @return operation prefix
758     */
759 jsr166 1.13 public <U> ParallelArrayWithMapping<T,U> withMapping
760 dl 1.1 (Op<? super T, ? extends U> op) {
761     return super.withMapping(op);
762     }
763    
764     /**
765     * Returns an operation prefix that causes a method to operate
766     * on mapped elements of the array using the given op.
767     * @param op the op
768     * @return operation prefix
769     */
770     public ParallelArrayWithDoubleMapping<T> withMapping
771     (ObjectToDouble<? super T> op) {
772     return super.withMapping(op);
773     }
774    
775     /**
776     * Returns an operation prefix that causes a method to operate
777     * on mapped elements of the array using the given op.
778     * @param op the op
779     * @return operation prefix
780     */
781     public ParallelArrayWithLongMapping<T> withMapping
782     (ObjectToLong<? super T> op) {
783     return super.withMapping(op);
784     }
785    
786     /**
787     * Returns an operation prefix that causes a method to operate
788     * on binary mappings of this array and the other array.
789     * @param combiner the combiner
790     * @param other the other array
791     * @return operation prefix
792     * @throws IllegalArgumentException if other array is a
793 jsr166 1.7 * filtered view (all filters must precede all mappings)
794 dl 1.1 */
795     public <U,V,W> ParallelArrayWithMapping<T,V> withMapping
796     (BinaryOp<? super T, ? super U, ? extends V> combiner,
797     ParallelArrayWithMapping<W,U> other) {
798     return super.withMapping(combiner, other);
799     }
800    
801     /**
802     * Returns an operation prefix that causes a method to operate
803     * on binary mappings of this array and the other array.
804     * @param combiner the combiner
805     * @param other the other array
806     * @return operation prefix
807     * @throws IllegalArgumentException if other array is a
808 jsr166 1.7 * filtered view (all filters must precede all mappings)
809 dl 1.1 */
810     public <V> ParallelArrayWithMapping<T,V> withMapping
811     (ObjectAndDoubleToObject<? super T, ? extends V> combiner,
812     ParallelDoubleArrayWithDoubleMapping other) {
813     return super.withMapping(combiner, other);
814     }
815    
816     /**
817     * Returns an operation prefix that causes a method to operate
818     * on binary mappings of this array and the other array.
819     * @param combiner the combiner
820     * @param other the other array
821     * @return operation prefix
822     * @throws IllegalArgumentException if other array is a
823 jsr166 1.7 * filtered view (all filters must precede all mappings)
824 dl 1.1 */
825     public <V> ParallelArrayWithMapping<T,V> withMapping
826     (ObjectAndLongToObject<? super T, ? extends V> combiner,
827     ParallelLongArrayWithLongMapping other) {
828     return super.withMapping(combiner, other);
829     }
830    
831     /**
832     * Returns an operation prefix that causes a method to operate
833     * on binary mappings of this array and the other array.
834     * @param combiner the combiner
835     * @param other the other array
836     * @return operation prefix
837     * @throws IllegalArgumentException if other array is a
838 jsr166 1.7 * filtered view (all filters must precede all mappings)
839 dl 1.1 */
840     public <U,W> ParallelArrayWithDoubleMapping<T> withMapping
841     (ObjectAndObjectToDouble<? super T, ? super U> combiner,
842     ParallelArrayWithMapping<W,U> other) {
843     return super.withMapping(combiner, other);
844     }
845    
846     /**
847     * Returns an operation prefix that causes a method to operate
848     * on binary mappings of this array and the other array.
849     * @param combiner the combiner
850     * @param other the other array
851     * @return operation prefix
852     * @throws IllegalArgumentException if other array is a
853 jsr166 1.7 * filtered view (all filters must precede all mappings)
854 dl 1.1 */
855     public ParallelArrayWithDoubleMapping<T> withMapping
856     (ObjectAndDoubleToDouble<? super T> combiner,
857     ParallelDoubleArrayWithDoubleMapping other) {
858     return super.withMapping(combiner, other);
859     }
860    
861     /**
862     * Returns an operation prefix that causes a method to operate
863     * on binary mappings of this array and the other array.
864     * @param combiner the combiner
865     * @param other the other array
866     * @return operation prefix
867     * @throws IllegalArgumentException if other array is a
868 jsr166 1.7 * filtered view (all filters must precede all mappings)
869 dl 1.1 */
870     public ParallelArrayWithDoubleMapping<T> withMapping
871     (ObjectAndLongToDouble<? super T> combiner,
872     ParallelLongArrayWithLongMapping other) {
873     return super.withMapping(combiner, other);
874     }
875    
876     /**
877     * Returns an operation prefix that causes a method to operate
878     * on binary mappings of this array and the other array.
879     * @param combiner the combiner
880     * @param other the other array
881     * @return operation prefix
882     * @throws IllegalArgumentException if other array is a
883 jsr166 1.7 * filtered view (all filters must precede all mappings)
884 dl 1.1 */
885     public <U,W> ParallelArrayWithLongMapping<T> withMapping
886     (ObjectAndObjectToLong<? super T, ? super U> combiner,
887     ParallelArrayWithMapping<W,U> other) {
888     return super.withMapping(combiner, other);
889     }
890    
891     /**
892     * Returns an operation prefix that causes a method to operate
893     * on binary mappings of this array and the other array.
894     * @param combiner the combiner
895     * @param other the other array
896     * @return operation prefix
897     * @throws IllegalArgumentException if other array is a
898 jsr166 1.7 * filtered view (all filters must precede all mappings)
899 dl 1.1 */
900     public ParallelArrayWithLongMapping<T> withMapping
901     (ObjectAndDoubleToLong<? super T> combiner,
902     ParallelDoubleArrayWithDoubleMapping other) {
903     return super.withMapping(combiner, other);
904     }
905    
906     /**
907     * Returns an operation prefix that causes a method to operate
908     * on binary mappings of this array and the other array.
909     * @param combiner the combiner
910     * @param other the other array
911     * @return operation prefix
912     * @throws IllegalArgumentException if other array is a
913 jsr166 1.7 * filtered view (all filters must precede all mappings)
914 dl 1.1 */
915     public ParallelArrayWithLongMapping<T> withMapping
916     (ObjectAndLongToLong<? super T> combiner,
917     ParallelLongArrayWithLongMapping other) {
918     return super.withMapping(combiner, other);
919     }
920    
921     /**
922     * Returns an operation prefix that causes a method to operate on
923     * mappings of this array using the given mapper that accepts as
924     * arguments an element's current index and value, and produces a
925     * new value. Index-based mappings allow parallel computation of
926     * many common array operations. For example, you could create
927     * function to average the values at the same index of multiple
928     * arrays and apply it using this method.
929     * @param mapper the mapper
930     * @return operation prefix
931     */
932     public <U> ParallelArrayWithMapping<T,U> withIndexedMapping
933     (IntAndObjectToObject<? super T, ? extends U> mapper) {
934     return super.withIndexedMapping(mapper);
935     }
936    
937     /**
938     * Returns an operation prefix that causes a method to operate on
939     * mappings of this array using the given mapper that accepts as
940     * arguments an element's current index and value, and produces a
941     * new value.
942     * @param mapper the mapper
943     * @return operation prefix
944     */
945     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
946     (IntAndObjectToDouble<? super T> mapper) {
947     return super.withIndexedMapping(mapper);
948     }
949    
950     /**
951     * Returns an operation prefix that causes a method to operate on
952     * mappings of this array using the given mapper that accepts as
953     * arguments an element's current index and value, and produces a
954     * new value.
955     * @param mapper the mapper
956     * @return operation prefix
957     */
958     public ParallelArrayWithLongMapping<T> withIndexedMapping
959     (IntAndObjectToLong<? super T> mapper) {
960     return super.withIndexedMapping(mapper);
961     }
962    
963     /**
964     * Returns an iterator stepping through each element of the array
965     * up to the current limit. This iterator does <em>not</em>
966     * support the remove operation. However, a full
967 jsr166 1.9 * {@code ListIterator} supporting add, remove, and set
968 dl 1.1 * operations is available via {@link #asList}.
969 jsr166 1.7 * @return an iterator stepping through each element
970 dl 1.1 */
971     public Iterator<T> iterator() {
972     return new ParallelArrayIterator<T>(array, fence);
973     }
974    
975     static final class ParallelArrayIterator<T> implements Iterator<T> {
976     int cursor;
977     final T[] arr;
978     final int hi;
979     ParallelArrayIterator(T[] a, int limit) { arr = a; hi = limit; }
980     public boolean hasNext() { return cursor < hi; }
981     public T next() {
982     if (cursor >= hi)
983     throw new NoSuchElementException();
984     return arr[cursor++];
985     }
986     public void remove() {
987     throw new UnsupportedOperationException();
988     }
989     }
990    
991     // List support
992    
993     /**
994     * Returns a view of this ParallelArray as a List. This List has
995     * the same structural and performance characteristics as {@link
996     * ArrayList}, and may be used to modify, replace or extend the
997     * bounds of the array underlying this ParallelArray. The methods
998     * supported by this list view are <em>not</em> in general
999     * implemented as parallel operations. This list is also not
1000     * itself thread-safe. In particular, performing list updates
1001     * while other parallel operations are in progress has undefined
1002     * (and surely undesired) effects.
1003     * @return a list view
1004     */
1005     public List<T> asList() {
1006     AsList lv = listView;
1007     if (lv == null)
1008     listView = lv = new AsList();
1009     return lv;
1010     }
1011    
1012     /**
1013     * Returns the effective size of the underlying array. The
1014     * effective size is the current limit, if used (see {@link
1015     * #setLimit}), or the length of the array otherwise.
1016     * @return the effective size of array
1017     */
1018     public int size() { return fence; }
1019    
1020     /**
1021 jsr166 1.7 * Returns the element of the array at the given index.
1022 dl 1.1 * @param i the index
1023     * @return the element of the array at the given index
1024     */
1025     public T get(int i) { return array[i]; }
1026    
1027     /**
1028 jsr166 1.7 * Sets the element of the array at the given index to the given value.
1029 dl 1.1 * @param i the index
1030     * @param x the value
1031     */
1032     public void set(int i, T x) { array[i] = x; }
1033    
1034     /**
1035 jsr166 1.7 * Returns the underlying array used for computations.
1036 dl 1.1 * @return the array
1037     */
1038     public T[] getArray() { return array; }
1039    
1040     /**
1041 jsr166 1.11 * Equivalent to {@code asList().toString()}.
1042 dl 1.1 * @return a string representation
1043     */
1044     public String toString() {
1045     return asList().toString();
1046     }
1047    
1048    
1049     /**
1050     * Ensures that the underlying array can be accessed up to the
1051     * given upper bound, reallocating and copying the underlying
1052     * array to expand if necessary. Or, if the given limit is less
1053     * than the length of the underlying array, causes computations to
1054     * ignore elements past the given limit.
1055     * @param newLimit the new upper bound
1056 jsr166 1.7 * @throws IllegalArgumentException if newLimit less than zero
1057 dl 1.1 */
1058     public final void setLimit(int newLimit) {
1059     if (newLimit < 0)
1060     throw new IllegalArgumentException();
1061     int cap = array.length;
1062     if (newLimit > cap)
1063     resizeArray(newLimit);
1064     fence = newLimit;
1065     }
1066    
1067     final void replaceElementsWith(T[] a) {
1068     System.arraycopy(a, 0, array, 0, a.length);
1069     fence = a.length;
1070     }
1071    
1072     final void resizeArray(int newCap) {
1073     int cap = array.length;
1074     if (newCap > cap) {
1075     Class elementType = array.getClass().getComponentType();
1076     T[] a =(T[])Array.newInstance(elementType, newCap);
1077     System.arraycopy(array, 0, a, 0, cap);
1078     array = a;
1079     }
1080     }
1081    
1082     final void insertElementAt(int index, T e) {
1083     int hi = fence++;
1084     if (hi >= array.length)
1085     resizeArray((hi * 3)/2 + 1);
1086     if (hi > index)
1087     System.arraycopy(array, index, array, index+1, hi - index);
1088     array[index] = e;
1089     }
1090    
1091     final void appendElement(T e) {
1092     int hi = fence++;
1093     if (hi >= array.length)
1094     resizeArray((hi * 3)/2 + 1);
1095     array[hi] = e;
1096     }
1097    
1098     /**
1099 jsr166 1.4 * Makes len slots available at index.
1100 dl 1.1 */
1101     final void insertSlotsAt(int index, int len) {
1102     if (len <= 0)
1103     return;
1104     int cap = array.length;
1105     int newSize = fence + len;
1106     if (cap < newSize) {
1107     cap = (cap * 3)/2 + 1;
1108     if (cap < newSize)
1109     cap = newSize;
1110     resizeArray(cap);
1111     }
1112     if (index < fence)
1113     System.arraycopy(array, index, array, index + len, fence - index);
1114     fence = newSize;
1115     }
1116    
1117     final void removeSlotAt(int index) {
1118     System.arraycopy(array, index + 1, array, index, fence - index - 1);
1119     array[--fence] = null;
1120     }
1121    
1122     final void removeSlotsAt(int fromIndex, int toIndex) {
1123     if (fromIndex < toIndex) {
1124     int size = fence;
1125     System.arraycopy(array, toIndex, array, fromIndex, size - toIndex);
1126     int newSize = size - (toIndex - fromIndex);
1127     fence = newSize;
1128     while (size > newSize)
1129     array[--size] = null;
1130     }
1131     }
1132    
1133     final int seqIndexOf(Object target) {
1134     T[] arr = array;
1135     int end = fence;
1136     if (target == null) {
1137     for (int i = 0; i < end; i++)
1138     if (arr[i] == null)
1139     return i;
1140     } else {
1141     for (int i = 0; i < end; i++)
1142     if (target.equals(arr[i]))
1143     return i;
1144     }
1145     return -1;
1146     }
1147    
1148     final int seqLastIndexOf(Object target) {
1149     T[] arr = array;
1150     int last = fence - 1;
1151     if (target == null) {
1152     for (int i = last; i >= 0; i--)
1153     if (arr[i] == null)
1154     return i;
1155     } else {
1156     for (int i = last; i >= 0; i--)
1157     if (target.equals(arr[i]))
1158     return i;
1159     }
1160     return -1;
1161     }
1162    
1163     final class ListIter implements ListIterator<T> {
1164     int cursor;
1165     int lastRet;
1166     T[] arr; // cache array and bound
1167     int hi;
1168     ListIter(int lo) {
1169     this.cursor = lo;
1170     this.lastRet = -1;
1171     this.arr = ParallelArray.this.array;
1172     this.hi = ParallelArray.this.fence;
1173     }
1174    
1175     public boolean hasNext() {
1176     return cursor < hi;
1177     }
1178    
1179     public T next() {
1180     int i = cursor;
1181     if (i < 0 || i >= hi)
1182     throw new NoSuchElementException();
1183     T next = arr[i];
1184     lastRet = i;
1185     cursor = i + 1;
1186     return next;
1187     }
1188    
1189     public void remove() {
1190     int k = lastRet;
1191     if (k < 0)
1192     throw new IllegalStateException();
1193     ParallelArray.this.removeSlotAt(k);
1194     hi = ParallelArray.this.fence;
1195     if (lastRet < cursor)
1196     cursor--;
1197     lastRet = -1;
1198     }
1199    
1200     public boolean hasPrevious() {
1201     return cursor > 0;
1202     }
1203    
1204     public T previous() {
1205     int i = cursor - 1;
1206     if (i < 0 || i >= hi)
1207     throw new NoSuchElementException();
1208     T previous = arr[i];
1209     lastRet = cursor = i;
1210     return previous;
1211     }
1212    
1213     public int nextIndex() {
1214     return cursor;
1215     }
1216    
1217     public int previousIndex() {
1218     return cursor - 1;
1219     }
1220    
1221     public void set(T e) {
1222     int i = lastRet;
1223     if (i < 0 || i >= hi)
1224     throw new NoSuchElementException();
1225     arr[i] = e;
1226     }
1227    
1228     public void add(T e) {
1229     int i = cursor;
1230     ParallelArray.this.insertElementAt(i, e);
1231     arr = ParallelArray.this.array;
1232     hi = ParallelArray.this.fence;
1233     lastRet = -1;
1234     cursor = i + 1;
1235     }
1236     }
1237    
1238     final class AsList extends AbstractList<T> implements RandomAccess {
1239     public T get(int i) {
1240     if (i >= fence)
1241     throw new IndexOutOfBoundsException();
1242     return array[i];
1243     }
1244    
1245     public T set(int i, T x) {
1246     if (i >= fence)
1247     throw new IndexOutOfBoundsException();
1248     T[] arr = array;
1249     T t = arr[i];
1250     arr[i] = x;
1251     return t;
1252     }
1253    
1254     public boolean isEmpty() {
1255     return fence == 0;
1256     }
1257    
1258     public int size() {
1259     return fence;
1260     }
1261    
1262     public Iterator<T> iterator() {
1263     return new ListIter(0);
1264     }
1265    
1266     public ListIterator<T> listIterator() {
1267     return new ListIter(0);
1268     }
1269    
1270     public ListIterator<T> listIterator(int index) {
1271     if (index < 0 || index > fence)
1272     throw new IndexOutOfBoundsException();
1273     return new ListIter(index);
1274     }
1275    
1276     public boolean add(T e) {
1277     appendElement(e);
1278     return true;
1279     }
1280    
1281     public void add(int index, T e) {
1282     if (index < 0 || index > fence)
1283     throw new IndexOutOfBoundsException();
1284     insertElementAt(index, e);
1285     }
1286    
1287     public boolean addAll(Collection<? extends T> c) {
1288     int csize = c.size();
1289     if (csize == 0)
1290     return false;
1291     int hi = fence;
1292     setLimit(hi + csize);
1293     T[] arr = array;
1294     for (T e : c)
1295     arr[hi++] = e;
1296     return true;
1297     }
1298    
1299     public boolean addAll(int index, Collection<? extends T> c) {
1300     if (index < 0 || index > fence)
1301     throw new IndexOutOfBoundsException();
1302     int csize = c.size();
1303     if (csize == 0)
1304     return false;
1305     insertSlotsAt(index, csize);
1306     T[] arr = array;
1307     for (T e : c)
1308     arr[index++] = e;
1309     return true;
1310     }
1311    
1312     public void clear() {
1313     T[] arr = array;
1314     for (int i = 0; i < fence; ++i)
1315     arr[i] = null;
1316     fence = 0;
1317     }
1318    
1319     public boolean remove(Object o) {
1320     int idx = seqIndexOf(o);
1321     if (idx < 0)
1322     return false;
1323     removeSlotAt(idx);
1324     return true;
1325     }
1326    
1327     public T remove(int index) {
1328     T oldValue = get(index);
1329     removeSlotAt(index);
1330     return oldValue;
1331     }
1332    
1333     public void removeRange(int fromIndex, int toIndex) {
1334     removeSlotsAt(fromIndex, toIndex);
1335     }
1336    
1337     public boolean contains(Object o) {
1338     return seqIndexOf(o) >= 0;
1339     }
1340    
1341     public int indexOf(Object o) {
1342     return seqIndexOf(o);
1343     }
1344    
1345     public int lastIndexOf(Object o) {
1346     return seqLastIndexOf(o);
1347     }
1348    
1349     public Object[] toArray() {
1350     int len = fence;
1351     Object[] a = new Object[len];
1352     System.arraycopy(array, 0, a, 0, len);
1353     return a;
1354     }
1355    
1356 jsr166 1.17 public <V> V[] toArray(V[] a) {
1357 dl 1.1 int len = fence;
1358     if (a.length < len) {
1359     Class elementType = a.getClass().getComponentType();
1360     a =(V[])Array.newInstance(elementType, len);
1361     }
1362     System.arraycopy(array, 0, a, 0, len);
1363     if (a.length > len)
1364     a[len] = null;
1365     return a;
1366     }
1367     }
1368    
1369     }