5c830131065ccef272ac202d51de155264adf7d0
[jalview.git] / srcjar2 / org / apache / log4j / helpers / CyclicBuffer.java
1 /*
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
8  * 
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  * 
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.
16  */
17      
18 package org.apache.log4j.helpers;
19
20 import org.apache.log4j.spi.LoggingEvent;
21
22 /**
23
24    CyclicBuffer is used by other appenders to hold {@link LoggingEvent
25    LoggingEvents} for immediate or differed display.
26    
27    <p>This buffer gives read access to any element in the buffer not
28    just the first or last element.
29
30    @author Ceki G&uuml;lc&uuml;
31    @since 0.9.0
32
33  */
34 public class CyclicBuffer {
35   
36   LoggingEvent[] ea;
37   int first; 
38   int last; 
39   int numElems;
40   int maxSize;
41
42   /**
43      Instantiate a new CyclicBuffer of at most <code>maxSize</code> events.
44
45      The <code>maxSize</code> argument must a positive integer.
46
47      @param maxSize The maximum number of elements in the buffer.
48   */
49   public CyclicBuffer(int maxSize) throws IllegalArgumentException {
50     if(maxSize < 1) {
51       throw new IllegalArgumentException("The maxSize argument ("+maxSize+
52                             ") is not a positive integer.");
53     }
54     this.maxSize = maxSize;
55     ea = new LoggingEvent[maxSize];
56     first = 0;
57     last = 0;
58     numElems = 0;
59   }
60     
61   /**
62      Add an <code>event</code> as the last event in the buffer.
63
64    */
65   public
66   void add(LoggingEvent event) {    
67     ea[last] = event;    
68     if(++last == maxSize) {
69         last = 0;
70     }
71
72     if(numElems < maxSize) {
73         numElems++;
74     } else if(++first == maxSize) {
75         first = 0;
76     }
77   }
78
79
80   /**
81      Get the <i>i</i>th oldest event currently in the buffer. If
82      <em>i</em> is outside the range 0 to the number of elements
83      currently in the buffer, then <code>null</code> is returned.
84
85
86   */
87   public
88   LoggingEvent get(int i) {
89     if(i < 0 || i >= numElems) {
90         return null;
91     }
92
93     return ea[(first + i) % maxSize];
94   }
95
96   public 
97   int getMaxSize() {
98     return maxSize;
99   }
100
101   /**
102      Get the oldest (first) element in the buffer. The oldest element
103      is removed from the buffer.
104   */
105   public
106   LoggingEvent get() {
107     LoggingEvent r = null;
108     if(numElems > 0) {
109       numElems--;
110       r = ea[first];
111       ea[first] = null;
112       if(++first == maxSize) {
113         first = 0;
114     }
115     } 
116     return r;
117   }
118   
119   /**
120      Get the number of elements in the buffer. This number is
121      guaranteed to be in the range 0 to <code>maxSize</code>
122      (inclusive).
123   */
124   public
125   int length() {
126     return numElems;
127   } 
128
129   /**
130      Resize the cyclic buffer to <code>newSize</code>.
131
132      @throws IllegalArgumentException if <code>newSize</code> is negative.
133    */
134   public 
135   void resize(int newSize) {
136     if(newSize < 0) {
137       throw new IllegalArgumentException("Negative array size ["+newSize+
138                                          "] not allowed.");
139     }
140     if(newSize == numElems)
141      {
142         return; // nothing to do
143     }
144     
145     LoggingEvent[] temp = new  LoggingEvent[newSize];
146
147     int loopLen = newSize < numElems ? newSize : numElems;
148     
149     for(int i = 0; i < loopLen; i++) {
150       temp[i] = ea[first];
151       ea[first] = null;
152       if(++first == numElems) {
153         first = 0;
154     }
155     }
156     ea = temp;
157     first = 0;
158     numElems = loopLen;
159     maxSize = newSize;
160     if (loopLen == newSize) {
161       last = 0;
162     } else {
163       last = loopLen;
164     }
165   }
166 }