1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package ch.hslu.exercises.sw11.ex1.n41.array.search;
17
18 import java.util.concurrent.CountedCompleter;
19 import java.util.concurrent.atomic.AtomicInteger;
20
21
22
23
24
25 @SuppressWarnings("serial")
26 public final class SearchTask extends CountedCompleter<Integer> {
27
28 private static final int SEGMENTS = 4;
29 private final int key;
30 private final int[] array;
31 private final int segmentNo;
32 private final AtomicInteger result;
33
34
35
36
37
38
39
40 public SearchTask(final int key, final int[] array) {
41 this(null, key, array, -1, new AtomicInteger(-1));
42 }
43
44 private SearchTask(final CountedCompleter<?> parent, final int key,
45 final int[] array, final int segmentNo,
46 final AtomicInteger result) {
47 super(parent);
48 this.key = key;
49 this.array = array;
50 this.segmentNo = segmentNo;
51 this.result = result;
52 }
53
54 @Override
55 public Integer getRawResult() {
56 return result.get();
57 }
58
59 @Override
60 public void compute() {
61 if (segmentNo >= 0) {
62 int segment = this.array.length / SearchTask.SEGMENTS;
63 int min = segmentNo * segment;
64 int max = min + segment;
65 for (int i = min; i < max; i++) {
66 if (i < this.array.length && array[i] == key && result.compareAndSet(-1, i)) {
67 this.quietlyCompleteRoot();
68 break;
69 }
70 }
71 } else {
72 this.addToPendingCount(SearchTask.SEGMENTS);
73 for (int i = 0; i < SearchTask.SEGMENTS + 1; i++) {
74 new SearchTask(this, key, array, i, result).fork();
75 }
76 }
77 this.tryComplete();
78 }
79 }