View Javadoc
1   /*
2    * Copyright 2024 Hochschule Luzern Informatik.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
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   * Codebeispiel zu CountedCompleter für die Suche eines Elementes in einem
23   * int-Array.
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       * Erzeugt einen Array-Such Task.
36       *
37       * @param key   zu findendes Element.
38       * @param array Interger-Array.
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  }