1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.maven.plugin.surefire.booterclient;
20
21 import java.util.Queue;
22 import java.util.concurrent.ConcurrentLinkedQueue;
23 import java.util.concurrent.atomic.AtomicInteger;
24
25 /**
26 * A bucket from which fork numbers can be drawn. Any drawn number needs to be returned to the bucket, in order to keep
27 * the range of provided values delivered as small as possible.
28 *
29 * @author Andreas Gudian
30 */
31 public final class ForkNumberBucket {
32 private static final ForkNumberBucket INSTANCE = new ForkNumberBucket();
33
34 private final Queue<Integer> qFree = new ConcurrentLinkedQueue<>();
35
36 private final AtomicInteger highWaterMark = new AtomicInteger(1);
37
38 /**
39 * Non-public constructor
40 */
41 private ForkNumberBucket() {}
42
43 /**
44 * @return a fork number that is not currently in use. The value must be returned to the bucket using
45 * {@link #returnNumber(int)}.
46 */
47 public static int drawNumber() {
48 return getInstance().drawNumberInternal();
49 }
50
51 /**
52 * @param number the number to return to the bucket so that it can be reused.
53 */
54 public static void returnNumber(int number) {
55 getInstance().returnNumberInternal(number);
56 }
57
58 /**
59 * @return a singleton instance
60 */
61 private static ForkNumberBucket getInstance() {
62 return INSTANCE;
63 }
64
65 /**
66 * @return a fork number that is not currently in use. The value must be returned to the bucket using
67 * {@link #returnNumber(int)}.
68 */
69 private int drawNumberInternal() {
70 Integer nextFree = qFree.poll();
71 return nextFree == null ? highWaterMark.getAndIncrement() : nextFree;
72 }
73
74 /**
75 * @return the highest number that has been drawn
76 */
77 private int getHighestDrawnNumber() {
78 return highWaterMark.get() - 1;
79 }
80
81 /**
82 * @param number the number to return to the bucket so that it can be reused.
83 */
84 private void returnNumberInternal(int number) {
85 qFree.add(number);
86 }
87 }