ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166y/forkjoin/ParallelLongArray.java
Revision: 1.14
Committed: Tue Jan 6 14:34:59 2009 UTC (15 years, 5 months ago) by dl
Branch: MAIN
CVS Tags: HEAD
Changes since 1.13: +0 -0 lines
State: FILE REMOVED
Log Message:
Repackaging

File Contents

# Content
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 * http://creativecommons.org/licenses/publicdomain
5 */
6
7 package jsr166y.forkjoin;
8 import static jsr166y.forkjoin.Ops.*;
9 import java.util.*;
10 import java.util.concurrent.atomic.*;
11 import java.lang.reflect.Array;
12
13 /**
14 * An array of longs supporting parallel operations. This class
15 * provides methods supporting the same operations as {@link
16 * ParallelArray}, but specialized for scalar longs. It additionally
17 * provides a few methods specific to numerical values.
18 *
19 * <p><b>Sample usages</b>.
20 * Here is a complete (although naive) prime filter program:
21 * <pre>
22 * import java.math.BigInteger;
23 * import jsr166y.forkjoin.*;
24 * import static jsr166y.forkjoin.Ops.*;
25 * import static jsr166y.forkjoin.ParallelLongArray.*;
26 *
27 * public class Sieve {
28 * public static void main(String[] args) {
29 * int n = Integer.parseInt(args[0]);
30 * // create array of divisors
31 * ParallelLongArray a = create(n-1, defaultExecutor());
32 * a.replaceWithMappedIndex(add2);
33 * int i = 0;
34 * long p = 2;
35 * while (p * p &lt; n) { // repeatedly filter
36 * a = a.withFilter(notDivisibleBy(p)).all();
37 * p = a.get(++i);
38 * }
39 * System.out.printf("sieve(%d) = %s%n", n, a);
40 * // check result
41 * if (!a.withFilter(notProbablePrime).isEmpty())
42 * throw new Error();
43 * }
44 * static IntToLong add2 = new IntToLong() {
45 * public long op(int i) { return i + 2; } };
46 * static LongPredicate notDivisibleBy(final long p) {
47 * return new LongPredicate() {
48 * public boolean op(long n) { return n &lt;= p || (n % p) != 0; }
49 * } }
50 * static LongPredicate notProbablePrime = new LongPredicate() {
51 * private static final int CERTAINTY = 8;
52 * public boolean op(long n) {
53 * return !BigInteger.valueOf(n).isProbablePrime(CERTAINTY);
54 * }
55 * }
56 * }
57 * </pre>
58 */
59 public class ParallelLongArray extends AbstractParallelAnyArray.LUPap {
60 // Same internals as ParallelArray, but specialized for longs
61 AsList listView;
62
63 /**
64 * Returns a common default executor for use in ParallelArrays.
65 * This executor arranges enough parallelism to use most, but not
66 * necessarily all, of the available processors on this system.
67 * @return the executor
68 */
69 public static ForkJoinExecutor defaultExecutor() {
70 return PAS.defaultExecutor();
71 }
72
73 /**
74 * Constructor for use by subclasses to create a new ParallelLongArray
75 * using the given executor, and initially using the supplied
76 * array, with effective size bound by the given limit. This
77 * constructor is designed to enable extensions via
78 * subclassing. To create a ParallelLongArray, use {@link #create},
79 * {@link #createEmpty}, {@link #createUsingHandoff} or {@link
80 * #createFromCopy}.
81 * @param executor the executor
82 * @param array the array
83 * @param limit the upper bound limit
84 */
85 protected ParallelLongArray(ForkJoinExecutor executor, long[] array,
86 int limit) {
87 super(executor, 0, limit, array);
88 if (executor == null || array == null)
89 throw new NullPointerException();
90 if (limit < 0 || limit > array.length)
91 throw new IllegalArgumentException();
92 }
93
94 /**
95 * Trusted internal version of protected constructor.
96 */
97 ParallelLongArray(ForkJoinExecutor executor, long[] array) {
98 super(executor, 0, array.length, array);
99 }
100
101 /**
102 * Creates a new ParallelLongArray using the given executor and
103 * an array of the given size
104 * @param size the array size
105 * @param executor the executor
106 */
107 public static ParallelLongArray create
108 (int size, ForkJoinExecutor executor) {
109 long[] array = new long[size];
110 return new ParallelLongArray(executor, array, size);
111 }
112
113 /**
114 * Creates a new ParallelLongArray initially using the given array and
115 * executor. In general, the handed off array should not be used
116 * for other purposes once constructing this ParallelLongArray. The
117 * given array may be internally replaced by another array in the
118 * course of methods that add or remove elements.
119 * @param handoff the array
120 * @param executor the executor
121 */
122 public static ParallelLongArray createUsingHandoff
123 (long[] handoff, ForkJoinExecutor executor) {
124 return new ParallelLongArray(executor, handoff, handoff.length);
125 }
126
127 /**
128 * Creates a new ParallelLongArray using the given executor and
129 * initially holding copies of the given
130 * source elements.
131 * @param source the source of initial elements
132 * @param executor the executor
133 */
134 public static ParallelLongArray createFromCopy
135 (long[] source, ForkJoinExecutor executor) {
136 // For now, avoid copyOf so people can compile with Java5
137 int size = source.length;
138 long[] array = new long[size];
139 System.arraycopy(source, 0, array, 0, size);
140 return new ParallelLongArray(executor, array, size);
141 }
142
143 /**
144 * Creates a new ParallelLongArray using an array of the given size,
145 * initially holding copies of the given source truncated or
146 * padded with zeros to obtain the specified length.
147 * @param source the source of initial elements
148 * @param size the array size
149 * @param executor the executor
150 */
151 public static ParallelLongArray createFromCopy
152 (int size, long[] source, ForkJoinExecutor executor) {
153 // For now, avoid copyOf so people can compile with Java5
154 long[] array = new long[size];
155 System.arraycopy(source, 0, array, 0,
156 Math.min(source.length, size));
157 return new ParallelLongArray(executor, array, size);
158 }
159
160 /**
161 * Creates a new ParallelLongArray using the given executor and
162 * an array of the given size, but with an initial effective size
163 * of zero, enabling incremental insertion via {@link
164 * ParallelLongArray#asList} operations.
165 * @param size the array size
166 * @param executor the executor
167 */
168 public static ParallelLongArray createEmpty
169 (int size, ForkJoinExecutor executor) {
170 long[] array = new long[size];
171 return new ParallelLongArray(executor, array, 0);
172 }
173
174 /**
175 * Summary statistics for a possibly bounded, filtered, and/or
176 * mapped ParallelLongArray.
177 */
178 public static interface SummaryStatistics {
179 /** Return the number of elements */
180 public int size();
181 /** Return the minimum element, or Long.MAX_VALUE if empty */
182 public long min();
183 /** Return the maximum element, or Long.MIN_VALUE if empty */
184 public long max();
185 /** Return the index of the minimum element, or -1 if empty */
186 public int indexOfMin();
187 /** Return the index of the maximum element, or -1 if empty */
188 public int indexOfMax();
189 /** Return the sum of all elements */
190 public long sum();
191 /** Return the arithmetic average of all elements */
192 public double average();
193 }
194
195 /**
196 * Returns the executor used for computations
197 * @return the executor
198 */
199 public ForkJoinExecutor getExecutor() { return ex; }
200
201 /**
202 * Applies the given procedure to elements
203 * @param procedure the procedure
204 */
205 public void apply(LongProcedure procedure) {
206 super.apply(procedure);
207 }
208
209 /**
210 * Returns reduction of elements
211 * @param reducer the reducer
212 * @param base the result for an empty array
213 * @return reduction
214 */
215 public long reduce(LongReducer reducer, long base) {
216 return super.reduce(reducer, base);
217 }
218
219 /**
220 * Returns a new ParallelLongArray holding all elements
221 * @return a new ParallelLongArray holding all elements
222 */
223 public ParallelLongArray all() {
224 return super.all();
225 }
226
227 /**
228 * Replaces elements with the results of applying the given op
229 * to their current values.
230 * @param op the op
231 * @return this (to simplify use in expressions)
232 */
233 public ParallelLongArray replaceWithMapping(LongOp op) {
234 super.replaceWithMapping(op);
235 return this;
236 }
237
238 /**
239 * Replaces elements with the results of applying the given
240 * op to their indices.
241 * @param op the op
242 * @return this (to simplify use in expressions)
243 */
244 public ParallelLongArray replaceWithMappedIndex(IntToLong op) {
245 super.replaceWithMappedIndex(op);
246 return this;
247 }
248
249 /**
250 * Replaces elements with the results of applying the given
251 * mapping to each index and current element value
252 * @param op the op
253 * @return this (to simplify use in expressions)
254 */
255 public ParallelLongArray replaceWithMappedIndex(IntAndLongToLong op) {
256 super.replaceWithMappedIndex(op);
257 return this;
258 }
259
260 /**
261 * Replaces elements with the results of applying the given
262 * generator. For example, to fill the array with uniform random
263 * values, use
264 * <tt>replaceWithGeneratedValue(Ops.longRandom())</tt>
265 * @param generator the generator
266 * @return this (to simplify use in expressions)
267 */
268 public ParallelLongArray replaceWithGeneratedValue(LongGenerator generator){
269 super.replaceWithGeneratedValue(generator);
270 return this;
271 }
272
273 /**
274 * Replaces elements with the given value.
275 * @param value the value
276 * @return this (to simplify use in expressions)
277 */
278 public ParallelLongArray replaceWithValue(long value) {
279 super.replaceWithValue(value);
280 return this;
281 }
282
283 /**
284 * Replaces elements with results of applying
285 * <tt>op(thisElement, otherElement)</tt>
286 * @param other the other array
287 * @param combiner the combiner
288 * @return this (to simplify use in expressions)
289 */
290 public ParallelLongArray replaceWithMapping
291 (BinaryLongOp combiner,
292 ParallelLongArrayWithLongMapping other) {
293 super.replaceWithMapping(combiner, other);
294 return this;
295 }
296
297 /**
298 * Replaces elements with results of applying
299 * <tt>op(thisElement, otherElement)</tt>
300 * @param other the other array
301 * @param combiner the combiner
302 * @return this (to simplify use in expressions)
303 * @throws ArrayIndexOutOfBoundsException if other array has
304 * fewer elements than this array.
305 */
306 public ParallelLongArray replaceWithMapping(BinaryLongOp combiner,
307 long[] other) {
308 super.replaceWithMapping(combiner, other);
309 return this;
310 }
311
312 /**
313 * Returns the index of some element equal to given target, or -1
314 * if not present
315 * @param target the element to search for
316 * @return the index or -1 if not present
317 */
318 public int indexOf(long target) {
319 return super.indexOf(target);
320 }
321
322 /**
323 * Assuming this array is sorted, returns the index of an element
324 * equal to given target, or -1 if not present. If the array
325 * is not sorted, the results are undefined.
326 * @param target the element to search for
327 * @return the index or -1 if not present
328 */
329 public int binarySearch(long target) {
330 return super.binarySearch(target);
331 }
332
333 /**
334 * Assuming this array is sorted with respect to the given
335 * comparator, returns the index of an element equal to given
336 * target, or -1 if not present. If the array is not sorted, the
337 * results are undefined.
338 * @param target the element to search for
339 * @param comparator the comparator
340 * @return the index or -1 if not present
341 */
342 public int binarySearch(long target, LongComparator comparator) {
343 return super.binarySearch(target, comparator);
344 }
345
346 /**
347 * Returns summary statistics, using the given comparator
348 * to locate minimum and maximum elements.
349 * @param comparator the comparator to use for
350 * locating minimum and maximum elements
351 * @return the summary.
352 */
353 public ParallelLongArray.SummaryStatistics summary
354 (LongComparator comparator) {
355 return super.summary(comparator);
356 }
357
358 /**
359 * Returns summary statistics, using natural comparator
360 * @return the summary.
361 */
362 public ParallelLongArray.SummaryStatistics summary() {
363 return super.summary();
364 }
365
366 /**
367 * Returns the minimum element, or Long.MAX_VALUE if empty
368 * @param comparator the comparator
369 * @return minimum element, or Long.MAX_VALUE if empty
370 */
371 public long min(LongComparator comparator) {
372 return super.min(comparator);
373 }
374
375 /**
376 * Returns the minimum element, or Long.MAX_VALUE if empty,
377 * @return minimum element, or Long.MAX_VALUE if empty
378 */
379 public long min() {
380 return super.min();
381 }
382
383 /**
384 * Returns the maximum element, or Long.MIN_VALUE if empty
385 * @param comparator the comparator
386 * @return maximum element, or Long.MIN_VALUE if empty
387 */
388 public long max(LongComparator comparator) {
389 return super.max(comparator);
390 }
391
392 /**
393 * Returns the maximum element, or Long.MIN_VALUE if empty
394 * @return maximum element, or Long.MIN_VALUE if empty
395 */
396 public long max() {
397 return super.max();
398 }
399
400 /**
401 * Replaces each element with the running cumulation of applying
402 * the given reducer. For example, if the contents are the numbers
403 * <tt>1, 2, 3</tt>, and the reducer operation adds numbers, then
404 * after invocation of this method, the contents would be <tt>1,
405 * 3, 6</tt> (that is, <tt>1, 1+2, 1+2+3</tt>);
406 * @param reducer the reducer
407 * @param base the result for an empty array
408 * @return this (to simplify use in expressions)
409 */
410 public ParallelLongArray cumulate(LongReducer reducer, long base) {
411 super.cumulate(reducer, base);
412 return this;
413 }
414
415 /**
416 * Replaces each element with the cumulation of applying the given
417 * reducer to all previous values, and returns the total
418 * reduction. For example, if the contents are the numbers <tt>1,
419 * 2, 3</tt>, and the reducer operation adds numbers, then after
420 * invocation of this method, the contents would be <tt>0, 1,
421 * 3</tt> (that is, <tt>0, 0+1, 0+1+2</tt>, and the return value
422 * would be 6 (that is, <tt> 1+2+3</tt>);
423 * @param reducer the reducer
424 * @param base the result for an empty array
425 * @return the total reduction
426 */
427 public long precumulate(LongReducer reducer, long base) {
428 return super.precumulate(reducer, base);
429 }
430
431 /**
432 * Sorts the array. Unlike Arrays.sort, this sort does
433 * not guarantee that elements with equal keys maintain their
434 * relative position in the array.
435 * @param comparator the comparator to use
436 * @return this (to simplify use in expressions)
437 */
438 public ParallelLongArray sort(LongComparator comparator) {
439 super.sort(comparator);
440 return this;
441 }
442
443 /**
444 * Sorts the array, assuming all elements are Comparable. Unlike
445 * Arrays.sort, this sort does not guarantee that elements
446 * with equal keys maintain their relative position in the array.
447 * @throws ClassCastException if any element is not Comparable.
448 * @return this (to simplify use in expressions)
449 */
450 public ParallelLongArray sort() {
451 super.sort();
452 return this;
453 }
454
455 /**
456 * Removes consecutive elements that are equal,
457 * shifting others leftward, and possibly decreasing size. This
458 * method may be used after sorting to ensure that this
459 * ParallelLongArray contains a set of unique elements.
460 * @return this (to simplify use in expressions)
461 */
462 public ParallelLongArray removeConsecutiveDuplicates() {
463 // Sequential implementation for now
464 int k = 0;
465 int n = fence;
466 if (k < n) {
467 long[] arr = this.array;
468 long last = arr[k++];
469 for (int i = k; i < n; ++i) {
470 long x = arr[i];
471 if (last != x)
472 arr[k++] = last = x;
473 }
474 removeSlotsAt(k, n);
475 }
476 return this;
477 }
478
479 /**
480 * Equivalent to <tt>asList().addAll</tt> but specialized for array
481 * arguments and likely to be more efficient.
482 * @param other the elements to add
483 * @return this (to simplify use in expressions)
484 */
485 public ParallelLongArray addAll(long[] other) {
486 int csize = other.length;
487 int end = fence;
488 insertSlotsAt(end, csize);
489 System.arraycopy(other, 0, array, end, csize);
490 return this;
491 }
492
493 /**
494 * Appends all (possibly bounded, filtered, or mapped) elements of
495 * the given ParallelDoubleArray, resizing and/or reallocating this
496 * array if necessary.
497 * @param other the elements to add
498 * @return this (to simplify use in expressions)
499 */
500 public ParallelLongArray addAll(ParallelLongArrayWithLongMapping other) {
501 int end = fence;
502 if (other.hasFilter()) {
503 PAS.FJLAppendAllDriver r = new PAS.FJLAppendAllDriver
504 (other, end, array);
505 ex.invoke(r);
506 array = r.results;
507 fence = end + r.resultSize;
508 }
509 else {
510 int csize = other.size();
511 insertSlotsAt(end, csize);
512 if (other.hasMap())
513 ex.invoke(new PAS.FJLMap(other, other.origin, other.fence,
514 null, array, end - other.origin));
515 else
516 System.arraycopy(other.array, 0, array, end, csize);
517 }
518 return this;
519 }
520
521 /**
522 * Returns a new ParallelLongArray containing only the unique
523 * elements of this array (that is, without any duplicates).
524 * @return the new ParallelLongArray
525 */
526 public ParallelLongArray allUniqueElements() {
527 return super.allUniqueElements();
528 }
529
530 /**
531 * Removes from the array all elements for which the given
532 * selector holds.
533 * @param selector the selector
534 * @return this (to simplify use in expressions)
535 */
536 public ParallelLongArray removeAll(LongPredicate selector) {
537 LFPap v = new LFPap(ex, 0, fence, array, selector);
538 PAS.FJRemoveAllDriver f = new PAS.FJRemoveAllDriver(v, 0, fence);
539 ex.invoke(f);
540 removeSlotsAt(f.offset, fence);
541 return this;
542 }
543
544 /**
545 * Returns true if all elements at the same relative positions
546 * of this and other array are equal.
547 * @param other the other array
548 */
549 public boolean hasAllEqualElements(ParallelLongArrayWithLongMapping other) {
550 return super.hasAllEqualElements(other);
551 }
552
553 /**
554 * Returns the sum of elements
555 * @return the sum of elements
556 */
557 public long sum() {
558 return super.sum();
559 }
560
561 /**
562 * Replaces each element with the running sum
563 * @return this (to simplify use in expressions)
564 */
565 public ParallelLongArray cumulateSum() {
566 super.cumulateSum();
567 return this;
568 }
569
570 /**
571 * Replaces each element with its prefix sum
572 * @return the total sum
573 */
574 public long precumulateSum() {
575 return super.precumulateSum();
576 }
577
578 /**
579 * Returns an operation prefix that causes a method to
580 * operate only on the elements of the array between
581 * firstIndex (inclusive) and upperBound (exclusive).
582 * @param firstIndex the lower bound (inclusive)
583 * @param upperBound the upper bound (exclusive)
584 * @return operation prefix
585 */
586 public ParallelLongArrayWithBounds withBounds(int firstIndex,
587 int upperBound) {
588 return super.withBounds(firstIndex, upperBound);
589 }
590
591 /**
592 * Returns an operation prefix that causes a method to operate
593 * only on the elements of the array for which the given selector
594 * returns true
595 * @param selector the selector
596 * @return operation prefix
597 */
598 public ParallelLongArrayWithFilter withFilter(LongPredicate selector) {
599 return super.withFilter(selector);
600 }
601
602 /**
603 * Returns an operation prefix that causes a method to operate
604 * only on elements for which the given binary selector returns
605 * true
606 * @param selector the selector
607 * @return operation prefix
608 */
609 public ParallelLongArrayWithFilter withFilter
610 (BinaryLongPredicate selector,
611 ParallelLongArrayWithLongMapping other) {
612 return super.withFilter(selector, other);
613 }
614
615 /**
616 * Returns an operation prefix that causes a method to operate
617 * only on elements for which the given indexed selector returns
618 * true
619 * @param selector the selector
620 * @return operation prefix
621 */
622 public ParallelLongArrayWithFilter withIndexedFilter
623 (IntAndLongPredicate selector) {
624 return super.withIndexedFilter(selector);
625 }
626
627
628 /**
629 * Returns an operation prefix that causes a method to operate
630 * on mapped elements of the array using the given op.
631 * @param op the op
632 * @return operation prefix
633 */
634 public <U> ParallelLongArrayWithMapping<U> withMapping
635 (LongToObject<? extends U> op) {
636 return super.withMapping(op);
637 }
638
639 /**
640 * Returns an operation prefix that causes a method to operate
641 * on mapped elements of the array using the given op.
642 * @param op the op
643 * @return operation prefix
644 */
645 public ParallelLongArrayWithLongMapping withMapping(LongOp op) {
646 return super.withMapping(op);
647 }
648
649 /**
650 * Returns an operation prefix that causes a method to operate
651 * on mapped elements of the array using the given op.
652 * @param op the op
653 * @return operation prefix
654 */
655 public ParallelLongArrayWithDoubleMapping withMapping(LongToDouble op) {
656 return super.withMapping(op);
657 }
658
659 /**
660 * Returns an operation prefix that causes a method to operate
661 * on binary mappings of this array and the other array.
662 * @param combiner the combiner
663 * @param other the other array
664 * @return operation prefix
665 * @throws IllegalArgumentException if other array is a
666 * filtered view (all filters must precede all mappings).
667 */
668 public <V,W,X> ParallelLongArrayWithMapping<W> withMapping
669 (LongAndObjectToObject<? super V, ? extends W> combiner,
670 ParallelArrayWithMapping<X,V> other) {
671 return super.withMapping(combiner, other);
672 }
673
674 /**
675 * Returns an operation prefix that causes a method to operate
676 * on binary mappings of this array and the other array.
677 * @param combiner the combiner
678 * @param other the other array
679 * @return operation prefix
680 * @throws IllegalArgumentException if other array is a
681 * filtered view (all filters must precede all mappings).
682 */
683 public <V> ParallelLongArrayWithMapping<V> withMapping
684 (LongAndDoubleToObject<? extends V> combiner,
685 ParallelDoubleArrayWithDoubleMapping other) {
686 return super.withMapping(combiner, other);
687 }
688
689 /**
690 * Returns an operation prefix that causes a method to operate
691 * on binary mappings of this array and the other array.
692 * @param combiner the combiner
693 * @param other the other array
694 * @return operation prefix
695 * @throws IllegalArgumentException if other array is a
696 * filtered view (all filters must precede all mappings).
697 */
698 public <V> ParallelLongArrayWithMapping<V> withMapping
699 (LongAndLongToObject<? extends V> combiner,
700 ParallelLongArrayWithLongMapping other) {
701 return super.withMapping(combiner, other);
702 }
703
704 /**
705 * Returns an operation prefix that causes a method to operate
706 * on binary mappings of this array and the other array.
707 * @param combiner the combiner
708 * @param other the other array
709 * @return operation prefix
710 * @throws IllegalArgumentException if other array is a
711 * filtered view (all filters must precede all mappings).
712 */
713 public <V,W> ParallelLongArrayWithDoubleMapping withMapping
714 (LongAndObjectToDouble<? super V> combiner,
715 ParallelArrayWithMapping<W,V> other) {
716 return super.withMapping(combiner, other);
717 }
718
719 /**
720 * Returns an operation prefix that causes a method to operate
721 * on binary mappings of this array and the other array.
722 * @param combiner the combiner
723 * @param other the other array
724 * @return operation prefix
725 * @throws IllegalArgumentException if other array is a
726 * filtered view (all filters must precede all mappings).
727 */
728 public ParallelLongArrayWithDoubleMapping withMapping
729 (LongAndDoubleToDouble combiner,
730 ParallelDoubleArrayWithDoubleMapping other) {
731 return super.withMapping(combiner, other);
732 }
733
734 /**
735 * Returns an operation prefix that causes a method to operate
736 * on binary mappings of this array and the other array.
737 * @param combiner the combiner
738 * @param other the other array
739 * @return operation prefix
740 * @throws IllegalArgumentException if other array is a
741 * filtered view (all filters must precede all mappings).
742 */
743 public ParallelLongArrayWithDoubleMapping withMapping
744 (LongAndLongToDouble combiner,
745 ParallelLongArrayWithLongMapping other) {
746 return super.withMapping(combiner, other);
747 }
748
749 /**
750 * Returns an operation prefix that causes a method to operate
751 * on binary mappings of this array and the other array.
752 * @param combiner the combiner
753 * @param other the other array
754 * @return operation prefix
755 * @throws IllegalArgumentException if other array is a
756 * filtered view (all filters must precede all mappings).
757 */
758 public <V,W> ParallelLongArrayWithLongMapping withMapping
759 (LongAndObjectToLong<? super V> combiner,
760 ParallelArrayWithMapping<W,V> other) {
761 return super.withMapping(combiner, other);
762 }
763
764 /**
765 * Returns an operation prefix that causes a method to operate
766 * on binary mappings of this array and the other array.
767 * @param combiner the combiner
768 * @param other the other array
769 * @return operation prefix
770 * @throws IllegalArgumentException if other array is a
771 * filtered view (all filters must precede all mappings).
772 */
773 public ParallelLongArrayWithLongMapping withMapping
774 (LongAndDoubleToLong combiner,
775 ParallelDoubleArrayWithDoubleMapping other) {
776 return super.withMapping(combiner, other);
777 }
778
779 /**
780 * Returns an operation prefix that causes a method to operate
781 * on binary mappings of this array and the other array.
782 * @param combiner the combiner
783 * @param other the other array
784 * @return operation prefix
785 * @throws IllegalArgumentException if other array is a
786 * filtered view (all filters must precede all mappings).
787 */
788 public ParallelLongArrayWithLongMapping withMapping
789 (BinaryLongOp combiner,
790 ParallelLongArrayWithLongMapping other) {
791 return super.withMapping(combiner, other);
792 }
793
794 /**
795 * Returns an operation prefix that causes a method to operate on
796 * mappings of this array using the given mapper that accepts as
797 * arguments an element's current index and value, and produces a
798 * new value.
799 * @param mapper the mapper
800 * @return operation prefix
801 */
802 public <U> ParallelLongArrayWithMapping<U> withIndexedMapping
803 (IntAndLongToObject<? extends U> mapper) {
804 return super.withIndexedMapping(mapper);
805 }
806
807 /**
808 * Returns an operation prefix that causes a method to operate on
809 * mappings of this array using the given mapper that accepts as
810 * arguments an element's current index and value, and produces a
811 * new value.
812 * @param mapper the mapper
813 * @return operation prefix
814 */
815 public ParallelLongArrayWithDoubleMapping withIndexedMapping
816 (IntAndLongToDouble mapper) {
817 return super.withIndexedMapping(mapper);
818 }
819
820 /**
821 * Returns an operation prefix that causes a method to operate on
822 * mappings of this array using the given mapper that accepts as
823 * arguments an element's current index and value, and produces a
824 * new value.
825 * @param mapper the mapper
826 * @return operation prefix
827 */
828 public ParallelLongArrayWithLongMapping withIndexedMapping
829 (IntAndLongToLong mapper) {
830 return super.withIndexedMapping(mapper);
831 }
832
833 /**
834 * Returns an iterator stepping through each element of the array
835 * up to the current limit. This iterator does <em>not</em>
836 * support the remove operation. However, a full
837 * <tt>ListIterator</tt> supporting add, remove, and set
838 * operations is available via {@link #asList}.
839 * @return an iterator stepping through each element.
840 */
841 public Iterator<Long> iterator() {
842 return new ParallelLongArrayIterator(array, fence);
843 }
844
845 static final class ParallelLongArrayIterator implements Iterator<Long> {
846 int cursor;
847 final long[] arr;
848 final int hi;
849 ParallelLongArrayIterator(long[] a, int limit) { arr = a; hi = limit; }
850 public boolean hasNext() { return cursor < hi; }
851 public Long next() {
852 if (cursor >= hi)
853 throw new NoSuchElementException();
854 return Long.valueOf(arr[cursor++]);
855 }
856 public void remove() {
857 throw new UnsupportedOperationException();
858 }
859 }
860
861 // List support
862
863 /**
864 * Returns a view of this ParallelLongArray as a List. This List has
865 * the same structural and performance characteristics as {@link
866 * ArrayList}, and may be used to modify, replace or extend the
867 * bounds of the array underlying this ParallelLongArray. The methods
868 * supported by this list view are <em>not</em> in general
869 * implemented as parallel operations. This list is also not
870 * itself thread-safe. In particular, performing list updates
871 * while other parallel operations are in progress has undefined
872 * (and surely undesired) effects.
873 * @return a list view
874 */
875 public List<Long> asList() {
876 AsList lv = listView;
877 if (lv == null)
878 listView = lv = new AsList();
879 return lv;
880 }
881
882 /**
883 * Returns the effective size of the underlying array. The
884 * effective size is the current limit, if used (see {@link
885 * #setLimit}), or the length of the array otherwise.
886 * @return the effective size of array
887 */
888 public int size() { return fence; }
889
890 /**
891 * Returns the underlying array used for computations
892 * @return the array
893 */
894 public long[] getArray() { return array; }
895
896 /**
897 * Returns the element of the array at the given index
898 * @param i the index
899 * @return the element of the array at the given index
900 */
901 public long get(int i) { return array[i]; }
902
903 /**
904 * Sets the element of the array at the given index to the given value
905 * @param i the index
906 * @param x the value
907 */
908 public void set(int i, long x) { array[i] = x; }
909
910 /**
911 * Equivalent to <tt>asList().toString()</tt>
912 * @return a string representation
913 */
914 public String toString() {
915 return asList().toString();
916 }
917
918 /**
919 * Ensures that the underlying array can be accessed up to the
920 * given upper bound, reallocating and copying the underlying
921 * array to expand if necessary. Or, if the given limit is less
922 * than the length of the underlying array, causes computations to
923 * ignore elements past the given limit.
924 * @param newLimit the new upper bound
925 * @throws IllegalArgumentException if newLimit less than zero.
926 */
927 public final void setLimit(int newLimit) {
928 if (newLimit < 0)
929 throw new IllegalArgumentException();
930 int cap = array.length;
931 if (newLimit > cap)
932 resizeArray(newLimit);
933 fence = newLimit;
934 }
935
936 final void replaceElementsParallelLongArrayWith(long[] a) {
937 System.arraycopy(a, 0, array, 0, a.length);
938 fence = a.length;
939 }
940
941 final void resizeArray(int newCap) {
942 int cap = array.length;
943 if (newCap > cap) {
944 long[] a = new long[newCap];
945 System.arraycopy(array, 0, a, 0, cap);
946 array = a;
947 }
948 }
949
950 final void insertElementAt(int index, long e) {
951 int hi = fence++;
952 if (hi >= array.length)
953 resizeArray((hi * 3)/2 + 1);
954 if (hi > index)
955 System.arraycopy(array, index, array, index+1, hi - index);
956 array[index] = e;
957 }
958
959 final void appendElement(long e) {
960 int hi = fence++;
961 if (hi >= array.length)
962 resizeArray((hi * 3)/2 + 1);
963 array[hi] = e;
964 }
965
966 /**
967 * Make len slots available at index
968 */
969 final void insertSlotsAt(int index, int len) {
970 if (len <= 0)
971 return;
972 int cap = array.length;
973 int newSize = fence + len;
974 if (cap < newSize) {
975 cap = (cap * 3)/2 + 1;
976 if (cap < newSize)
977 cap = newSize;
978 resizeArray(cap);
979 }
980 if (index < fence)
981 System.arraycopy(array, index, array, index + len, fence - index);
982 fence = newSize;
983 }
984
985 final void removeSlotAt(int index) {
986 System.arraycopy(array, index + 1, array, index, fence - index - 1);
987 --fence;
988 }
989
990 final void removeSlotsAt(int fromIndex, int toIndex) {
991 if (fromIndex < toIndex) {
992 int size = fence;
993 System.arraycopy(array, toIndex, array, fromIndex, size - toIndex);
994 int newSize = size - (toIndex - fromIndex);
995 fence = newSize;
996 }
997 }
998
999 final int seqIndexOf(long target) {
1000 long[] arr = array;
1001 int end = fence;
1002 for (int i = 0; i < end; i++)
1003 if (target == arr[i])
1004 return i;
1005 return -1;
1006 }
1007
1008 final int seqLastIndexOf(long target) {
1009 long[] arr = array;
1010 for (int i = fence - 1; i >= 0; i--)
1011 if (target == arr[i])
1012 return i;
1013 return -1;
1014 }
1015
1016 final class ListIter implements ListIterator<Long> {
1017 int cursor;
1018 int lastRet;
1019 long[] arr; // cache array and bound
1020 int hi;
1021 ListIter(int lo) {
1022 this.cursor = lo;
1023 this.lastRet = -1;
1024 this.arr = ParallelLongArray.this.array;
1025 this.hi = ParallelLongArray.this.fence;
1026 }
1027
1028 public boolean hasNext() {
1029 return cursor < hi;
1030 }
1031
1032 public Long next() {
1033 int i = cursor;
1034 if (i < 0 || i >= hi)
1035 throw new NoSuchElementException();
1036 long next = arr[i];
1037 lastRet = i;
1038 cursor = i + 1;
1039 return Long.valueOf(next);
1040 }
1041
1042 public void remove() {
1043 int k = lastRet;
1044 if (k < 0)
1045 throw new IllegalStateException();
1046 ParallelLongArray.this.removeSlotAt(k);
1047 hi = ParallelLongArray.this.fence;
1048 if (lastRet < cursor)
1049 cursor--;
1050 lastRet = -1;
1051 }
1052
1053 public boolean hasPrevious() {
1054 return cursor > 0;
1055 }
1056
1057 public Long previous() {
1058 int i = cursor - 1;
1059 if (i < 0 || i >= hi)
1060 throw new NoSuchElementException();
1061 long previous = arr[i];
1062 lastRet = cursor = i;
1063 return Long.valueOf(previous);
1064 }
1065
1066 public int nextIndex() {
1067 return cursor;
1068 }
1069
1070 public int previousIndex() {
1071 return cursor - 1;
1072 }
1073
1074 public void set(Long e) {
1075 int i = lastRet;
1076 if (i < 0 || i >= hi)
1077 throw new NoSuchElementException();
1078 arr[i] = e.longValue();
1079 }
1080
1081 public void add(Long e) {
1082 int i = cursor;
1083 ParallelLongArray.this.insertElementAt(i, e.longValue());
1084 arr = ParallelLongArray.this.array;
1085 hi = ParallelLongArray.this.fence;
1086 lastRet = -1;
1087 cursor = i + 1;
1088 }
1089 }
1090
1091 final class AsList extends AbstractList<Long> implements RandomAccess {
1092 public Long get(int i) {
1093 if (i >= fence)
1094 throw new IndexOutOfBoundsException();
1095 return Long.valueOf(array[i]);
1096 }
1097
1098 public Long set(int i, Long x) {
1099 if (i >= fence)
1100 throw new IndexOutOfBoundsException();
1101 long[] arr = array;
1102 Long t = Long.valueOf(arr[i]);
1103 arr[i] = x.longValue();
1104 return t;
1105 }
1106
1107 public boolean isEmpty() {
1108 return fence == 0;
1109 }
1110
1111 public int size() {
1112 return fence;
1113 }
1114
1115 public Iterator<Long> iterator() {
1116 return new ListIter(0);
1117 }
1118
1119 public ListIterator<Long> listIterator() {
1120 return new ListIter(0);
1121 }
1122
1123 public ListIterator<Long> listIterator(int index) {
1124 if (index < 0 || index > fence)
1125 throw new IndexOutOfBoundsException();
1126 return new ListIter(index);
1127 }
1128
1129 public boolean add(Long e) {
1130 appendElement(e.longValue());
1131 return true;
1132 }
1133
1134 public void add(int index, Long e) {
1135 if (index < 0 || index > fence)
1136 throw new IndexOutOfBoundsException();
1137 insertElementAt(index, e.longValue());
1138 }
1139
1140 public boolean addAll(Collection<? extends Long> c) {
1141 int csize = c.size();
1142 if (csize == 0)
1143 return false;
1144 int hi = fence;
1145 setLimit(hi + csize);
1146 long[] arr = array;
1147 for (Long e : c)
1148 arr[hi++] = e.longValue();
1149 return true;
1150 }
1151
1152 public boolean addAll(int index, Collection<? extends Long> c) {
1153 if (index < 0 || index > fence)
1154 throw new IndexOutOfBoundsException();
1155 int csize = c.size();
1156 if (csize == 0)
1157 return false;
1158 insertSlotsAt(index, csize);
1159 long[] arr = array;
1160 for (Long e : c)
1161 arr[index++] = e.longValue();
1162 return true;
1163 }
1164
1165 public void clear() {
1166 fence = 0;
1167 }
1168
1169 public boolean remove(Object o) {
1170 if (!(o instanceof Long))
1171 return false;
1172 int idx = seqIndexOf(((Long)o).longValue());
1173 if (idx < 0)
1174 return false;
1175 removeSlotAt(idx);
1176 return true;
1177 }
1178
1179 public Long remove(int index) {
1180 Long oldValue = get(index);
1181 removeSlotAt(index);
1182 return oldValue;
1183 }
1184
1185 public void removeRange(int fromIndex, int toIndex) {
1186 removeSlotsAt(fromIndex, toIndex);
1187 }
1188
1189 public boolean contains(Object o) {
1190 if (!(o instanceof Long))
1191 return false;
1192 return seqIndexOf(((Long)o).longValue()) >= 0;
1193 }
1194
1195 public int indexOf(Object o) {
1196 if (!(o instanceof Long))
1197 return -1;
1198 return seqIndexOf(((Long)o).longValue());
1199 }
1200
1201 public int lastIndexOf(Object o) {
1202 if (!(o instanceof Long))
1203 return -1;
1204 return seqLastIndexOf(((Long)o).longValue());
1205 }
1206 }
1207
1208 }
1209