KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > log4j > helpers > BoundedFIFO


1 /*
2  * Copyright 1999-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 // Contributors: Mathias Bogaert
18
// joelr@viair.com
19

20 package org.apache.log4j.helpers;
21
22 import org.apache.log4j.spi.LoggingEvent;
23
24 /**
25    <code>BoundedFIFO</code> serves as the bounded first-in-first-out
26    buffer heavily used by the {@link org.apache.log4j.AsyncAppender}.
27    
28    @author Ceki G&uuml;lc&uuml;
29    @since version 0.9.1 */

30 public class BoundedFIFO {
31   
32   LoggingEvent[] buf;
33   int numElements = 0;
34   int first = 0;
35   int next = 0;
36   int maxSize;
37
38   /**
39      Instantiate a new BoundedFIFO with a maximum size passed as argument.
40    */

41   public
42   BoundedFIFO(int maxSize) {
43    if(maxSize < 1) {
44       throw new IllegalArgumentException JavaDoc("The maxSize argument ("+maxSize+
45                 ") is not a positive integer.");
46     }
47     this.maxSize = maxSize;
48     buf = new LoggingEvent[maxSize];
49   }
50   
51   /**
52      Get the first element in the buffer. Returns <code>null</code> if
53      there are no elements in the buffer. */

54   public
55   LoggingEvent get() {
56     if(numElements == 0)
57       return null;
58     
59     LoggingEvent r = buf[first];
60     buf[first] = null; // help garbage collection
61

62     if(++first == maxSize) {
63     first = 0;
64     }
65     numElements--;
66     return r;
67   }
68
69   /**
70      Place a {@link LoggingEvent} in the buffer. If the buffer is full
71      then the event is <b>silently dropped</b>. It is the caller's
72      responsability to make sure that the buffer has free space. */

73   public
74   void put(LoggingEvent o) {
75     if(numElements != maxSize) {
76       buf[next] = o;
77       if(++next == maxSize) {
78     next = 0;
79       }
80       numElements++;
81     }
82   }
83
84   /**
85      Get the maximum size of the buffer.
86    */

87   public
88   int getMaxSize() {
89     return maxSize;
90   }
91
92   /**
93      Return <code>true</code> if the buffer is full, that is, whether
94      the number of elements in the buffer equals the buffer size. */

95   public
96   boolean isFull() {
97     return numElements == maxSize;
98   }
99
100   /**
101      Get the number of elements in the buffer. This number is
102      guaranteed to be in the range 0 to <code>maxSize</code>
103      (inclusive).
104   */

105   public
106   int length() {
107     return numElements;
108   }
109
110
111   int min(int a, int b) {
112     return a < b ? a : b;
113   }
114
115
116   /**
117      Resize the buffer to a new size. If the new size is smaller than
118      the old size events might be lost.
119      
120      @since 1.1
121    */

122   synchronized
123   public
124   void resize(int newSize) {
125     if(newSize == maxSize)
126       return;
127
128
129    LoggingEvent[] tmp = new LoggingEvent[newSize];
130
131    // we should not copy beyond the buf array
132
int len1 = maxSize - first;
133
134    // we should not copy beyond the tmp array
135
len1 = min(len1, newSize);
136
137    // er.. how much do we actually need to copy?
138
// We should not copy more than the actual number of elements.
139
len1 = min(len1, numElements);
140
141    // Copy from buf starting a first, to tmp, starting at position 0, len1 elements.
142
System.arraycopy(buf, first, tmp, 0, len1);
143    
144    // Are there any uncopied elements and is there still space in the new array?
145
int len2 = 0;
146    if((len1 < numElements) && (len1 < newSize)) {
147      len2 = numElements - len1;
148      len2 = min(len2, newSize - len1);
149      System.arraycopy(buf, 0, tmp, len1, len2);
150    }
151    
152    this.buf = tmp;
153    this.maxSize = newSize;
154    this.first=0;
155    this.numElements = len1+len2;
156    this.next = this.numElements;
157    if(this.next == this.maxSize) // this should never happen, but again, it just might.
158
this.next = 0;
159   }
160
161   
162   /**
163      Returns <code>true</code> if there is just one element in the
164      buffer. In other words, if there were no elements before the last
165      {@link #put} operation completed. */

166   public
167   boolean wasEmpty() {
168     return numElements == 1;
169   }
170
171   /**
172       Returns <code>true</code> if the number of elements in the
173       buffer plus 1 equals the maximum buffer size, returns
174       <code>false</code> otherwise. */

175   public
176   boolean wasFull() {
177     return (numElements+1 == maxSize);
178   }
179
180 }
181
Popular Tags