1 package org.apache.maven.plugin.surefire.booterclient;
2
3 import java.util.Queue;
4 import java.util.concurrent.ConcurrentLinkedQueue;
5 import java.util.concurrent.atomic.AtomicInteger;
6
7 /**
8 * A bucket from which fork numbers can be drawn. Any drawn number needs to be returned to the bucket, in order to keep
9 * the range of provided values delivered as small as possible.
10 *
11 * @author Andreas Gudian
12 */
13 public class ForkNumberBucket
14 {
15
16 private static final ForkNumberBucket INSTANCE = new ForkNumberBucket();
17
18 private Queue<Integer> qFree = new ConcurrentLinkedQueue<Integer>();
19
20 private AtomicInteger highWaterMark = new AtomicInteger( 1 );
21
22 /**
23 * Non-public constructor
24 */
25 protected ForkNumberBucket()
26 {
27 }
28
29 /**
30 * @return a fork number that is not currently in use. The value must be returned to the bucket using
31 * {@link #returnNumber(int)}.
32 */
33 public static int drawNumber()
34 {
35 return getInstance()._drawNumber();
36 }
37
38 /**
39 * @param number the number to return to the bucket so that it can be reused.
40 */
41 public static void returnNumber( int number )
42 {
43 getInstance()._returnNumber( number );
44 }
45
46 /**
47 * @return a singleton instance
48 */
49 private static ForkNumberBucket getInstance()
50 {
51 return INSTANCE;
52 }
53
54 /**
55 * @return a fork number that is not currently in use. The value must be returned to the bucket using
56 * {@link #returnNumber(int)}.
57 */
58 protected int _drawNumber()
59 {
60 Integer nextFree = qFree.poll();
61
62 if ( null == nextFree )
63 {
64 return highWaterMark.getAndIncrement();
65 }
66 else
67 {
68 return nextFree.intValue();
69 }
70 }
71
72 /**
73 * @return the highest number that has been drawn
74 */
75 protected int getHighestDrawnNumber()
76 {
77 return highWaterMark.get() - 1;
78 }
79
80 /**
81 * @param number the number to return to the bucket so that it can be reused.
82 */
83 protected void _returnNumber( int number )
84 {
85 qFree.add( Integer.valueOf( number ) );
86 }
87 }