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