ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/extra166y/ParallelLongArray.java
Revision: 1.17
Committed: Thu Feb 26 06:53:34 2015 UTC (9 years, 1 month ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.16: +0 -1 lines
Log Message:
delete unused imports

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