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

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