2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 // Contributors: Mathias Bogaert
21 package org.apache.log4j.helpers;
23 import org.apache.log4j.spi.LoggingEvent;
26 <code>BoundedFIFO</code> serves as the bounded first-in-first-out
27 buffer heavily used by the {@link org.apache.log4j.AsyncAppender}.
29 @author Ceki Gülcü
30 @since version 0.9.1 */
31 public class BoundedFIFO {
40 Instantiate a new BoundedFIFO with a maximum size passed as argument.
43 BoundedFIFO(int maxSize) {
45 throw new IllegalArgumentException("The maxSize argument ("+maxSize+
46 ") is not a positive integer.");
48 this.maxSize = maxSize;
49 buf = new LoggingEvent[maxSize];
53 Get the first element in the buffer. Returns <code>null</code> if
54 there are no elements in the buffer. */
57 if(numElements == 0) {
61 LoggingEvent r = buf[first];
62 buf[first] = null; // help garbage collection
64 if(++first == maxSize) {
72 Place a {@link LoggingEvent} in the buffer. If the buffer is full
73 then the event is <b>silently dropped</b>. It is the caller's
74 responsability to make sure that the buffer has free space. */
76 void put(LoggingEvent o) {
77 if(numElements != maxSize) {
79 if(++next == maxSize) {
87 Get the maximum size of the buffer.
95 Return <code>true</code> if the buffer is full, that is, whether
96 the number of elements in the buffer equals the buffer size. */
99 return numElements == maxSize;
103 Get the number of elements in the buffer. This number is
104 guaranteed to be in the range 0 to <code>maxSize</code>
113 int min(int a, int b) {
114 return a < b ? a : b;
119 Resize the buffer to a new size. If the new size is smaller than
120 the old size events might be lost.
126 void resize(int newSize) {
127 if(newSize == maxSize) {
132 LoggingEvent[] tmp = new LoggingEvent[newSize];
134 // we should not copy beyond the buf array
135 int len1 = maxSize - first;
137 // we should not copy beyond the tmp array
138 len1 = min(len1, newSize);
140 // er.. how much do we actually need to copy?
141 // We should not copy more than the actual number of elements.
142 len1 = min(len1, numElements);
144 // Copy from buf starting a first, to tmp, starting at position 0, len1 elements.
145 System.arraycopy(buf, first, tmp, 0, len1);
147 // Are there any uncopied elements and is there still space in the new array?
149 if((len1 < numElements) && (len1 < newSize)) {
150 len2 = numElements - len1;
151 len2 = min(len2, newSize - len1);
152 System.arraycopy(buf, 0, tmp, len1, len2);
156 this.maxSize = newSize;
158 this.numElements = len1+len2;
159 this.next = this.numElements;
160 if(this.next == this.maxSize) {
167 Returns <code>true</code> if there is just one element in the
168 buffer. In other words, if there were no elements before the last
169 {@link #put} operation completed. */
172 return numElements == 1;
176 Returns <code>true</code> if the number of elements in the
177 buffer plus 1 equals the maximum buffer size, returns
178 <code>false</code> otherwise. */
181 return (numElements+1 == maxSize);