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 }