View Javadoc
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 }