1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.log4j.chainsaw;
19
20 import java.util.AbstractList;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.List;
24
25
26 /***
27 *
28 * CyclicBuffer implementation that is Object generic, and implements the List interface.
29 *
30 * Original CyclicBuffer @author Ceki Gülcü
31 *
32 * This implementation (although there's very little change) @author Paul Smith <psmith@apache.org>
33 *
34 */
35 public class CyclicBufferList extends AbstractList implements List {
36 Object[] 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 CyclicBufferList(int maxSize) {
50 if (maxSize < 1) {
51 throw new IllegalArgumentException(
52 "The maxSize argument (" + maxSize + ") is not a positive integer.");
53 }
54 this.maxSize = maxSize;
55 clear();
56 }
57
58 public CyclicBufferList() {
59 this(5000);
60 }
61
62 /***
63 * Removes the element at the specified position in this list.
64 * Shifts any subsequent elements to the left (subtracts one from their
65 * indices).
66 *
67 * @param index the index of the element to removed.
68 * @return the element that was removed from the list.
69 * @throws IndexOutOfBoundsException if index out of range <tt>(index
70 * < 0 || index >= size())</tt>.
71 */
72 public Object remove(int index) {
73 Object oldValue = ea[index];
74
75 List list = new ArrayList(Arrays.asList(ea));
76 list.remove(index);
77 ea = list.toArray(ea);
78 numElems = ea.length;
79
80 numElems--;
81 if (--last <= 0) {
82 last = numElems;
83 }
84
85 if (first == maxSize) {
86 first = 0;
87 }
88 return oldValue;
89 }
90
91 public Object set(int index, Object element) {
92 Object previous = ea[index];
93 ea[index] = element;
94
95 return previous;
96 }
97
98 /***
99 Add an <code>event</code> as the last event in the buffer.
100
101 */
102 public boolean add(Object event) {
103 ea[last] = event;
104
105 if (++last == maxSize) {
106 last = 0;
107 }
108
109 if (numElems < maxSize) {
110 numElems++;
111 } else if (++first == maxSize) {
112 first = 0;
113 }
114
115 return true;
116 }
117
118 /***
119 Get the <i>i</i>th oldest event currently in the buffer. If
120 <em>i</em> is outside the range 0 to the number of elements
121 currently in the buffer, then <code>null</code> is returned.
122
123
124 */
125 public Object get(int i) {
126 if ((i < 0) || (i >= numElems)) {
127 return null;
128 }
129
130 return ea[(first + i) % maxSize];
131 }
132
133 public int getMaxSize() {
134 return maxSize;
135 }
136
137 public int getLast() {
138 return last;
139 }
140
141 /***
142 Get the oldest (first) element in the buffer. The oldest element
143 is removed from the buffer.
144 */
145 public Object get() {
146 Object r = null;
147
148 if (numElems > 0) {
149 numElems--;
150 r = ea[first];
151 ea[first] = null;
152
153 if (++first == maxSize) {
154 first = 0;
155 }
156 }
157
158 return r;
159 }
160
161 /***
162 Get the number of elements in the buffer. This number is
163 guaranteed to be in the range 0 to <code>maxSize</code>
164 (inclusive).
165 */
166 public int size() {
167 return numElems;
168 }
169
170 /***
171 Resize the cyclic buffer to <code>newSize</code>.
172
173 @throws IllegalArgumentException if <code>newSize</code> is negative.
174 */
175 public void resize(int newSize) {
176 if (newSize < 0) {
177 throw new IllegalArgumentException(
178 "Negative array size [" + newSize + "] not allowed.");
179 }
180
181 if (newSize == numElems) {
182 return;
183 }
184
185 Object[] temp = new Object[newSize];
186
187 int loopLen = (newSize < numElems) ? newSize : numElems;
188
189 for (int i = 0; i < loopLen; i++) {
190 temp[i] = ea[first];
191 ea[first] = null;
192
193 if (++first == numElems) {
194 first = 0;
195 }
196 }
197
198 ea = temp;
199 first = 0;
200 numElems = loopLen;
201 maxSize = newSize;
202
203 if (loopLen == newSize) {
204 last = 0;
205 } else {
206 last = loopLen;
207 }
208 }
209
210
211
212 public void clear() {
213 ea = new Object[maxSize];
214 first = 0;
215 last = 0;
216 numElems = 0;
217
218 }
219
220 }