1 package org.apache.fulcrum.pool;
2
3
4 /*
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file
9 * to you under the Apache License, Version 2.0 (the
10 * "License"); you may not use this file except in compliance
11 * with the License. You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing,
16 * software distributed under the License is distributed on an
17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 * KIND, either express or implied. See the License for the
19 * specific language governing permissions and limitations
20 * under the License.
21 */
22
23
24 /**
25 * Efficient array-based bounded buffer class.
26 * Adapted from CPJ, chapter 8, which describes design.
27 * Originally written by Doug Lea and released into the public domain.
28 * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>] <p>
29 *
30 * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a>
31 * @version $Id$
32 */
33 public class BoundedBuffer
34 {
35 /**
36 * The default capacity.
37 */
38 public static final int DEFAULT_CAPACITY = 1024;
39
40 protected final Object[] array_; // the elements
41
42 protected int takePtr_ = 0; // circular indices
43 protected int putPtr_ = 0;
44
45 protected int usedSlots_ = 0; // length
46 protected int emptySlots_; // capacity - length
47
48 /**
49 * Creates a buffer with the given capacity.
50 *
51 * @param capacity the capacity.
52 * @throws IllegalArgumentException if capacity less or equal to zero.
53 */
54 public BoundedBuffer(int capacity)
55 throws IllegalArgumentException
56 {
57 if (capacity <= 0)
58 throw new IllegalArgumentException();
59
60 array_ = new Object[capacity];
61 emptySlots_ = capacity;
62 }
63
64 /**
65 * Creates a buffer with the default capacity
66 */
67 public BoundedBuffer()
68 {
69 this(DEFAULT_CAPACITY);
70 }
71
72 /**
73 * Returns the number of elements in the buffer.
74 * This is only a snapshot value, that may change
75 * immediately after returning.
76 *
77 * @return the size.
78 */
79 public synchronized int size()
80 {
81 return usedSlots_;
82 }
83
84 /**
85 * Returns the capacity of the buffer.
86 *
87 * @return the capacity.
88 */
89 public int capacity()
90 {
91 return array_.length;
92 }
93
94 /**
95 * Peeks, but does not remove the top item from the buffer.
96 *
97 * @return the object or null.
98 */
99 public synchronized Object peek()
100 {
101 if (usedSlots_ > 0)
102 return array_[takePtr_];
103 else
104 return null;
105 }
106
107 /**
108 * Puts an item in the buffer only if there is capacity available.
109 *
110 * @param x the item to be inserted.
111 * @return true if accepted, else false.
112 */
113 public synchronized boolean offer(Object x)
114 {
115 if (x == null)
116 throw new IllegalArgumentException();
117
118 if (emptySlots_ > 0)
119 {
120 --emptySlots_;
121 array_[putPtr_] = x;
122 if (++putPtr_ >= array_.length)
123 putPtr_ = 0;
124 usedSlots_++;
125 return true;
126 }
127 else
128 return false;
129 }
130
131 /**
132 * Polls and removes the top item from the buffer if one is available.
133 *
134 * @return the oldest item from the buffer, or null if the buffer is empty.
135 */
136 public synchronized <T> T poll()
137 {
138 if (usedSlots_ > 0)
139 {
140 --usedSlots_;
141 @SuppressWarnings("unchecked")
142 T old = (T) array_[takePtr_];
143 array_[takePtr_] = null;
144 if (++takePtr_ >= array_.length)
145 takePtr_ = 0;
146 emptySlots_++;
147 return old;
148 }
149 else
150 return null;
151 }
152 }