1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 package smtphandler;
44
45 import java.util.logging.LogRecord;
46
47 /**
48 *
49 * CyclicBuffer is used by other handlers to hold {@link LogRecord} objects for
50 * immediate or differed display.
51 *
52 * <p>
53 * This buffer gives read access to any element in the buffer not just the
54 * first or last element.
55 *
56 * @author Ceki Gülcü
57 * @author Sean C. Sullivan
58 *
59 */
60 public class CyclicBuffer
61 {
62 private LogRecord[] records;
63 private int first;
64 private int last;
65 private int numElems;
66 private int maxSize;
67
68 /**
69 * Instantiate a new CyclicBuffer of at most <code>maxSize</code>
70 * records.
71 *
72 * The <code>maxSize</code> argument must a positive integer.
73 *
74 * @param maxSize
75 * The maximum number of elements in the buffer.
76 */
77 public CyclicBuffer(int maxSize) throws IllegalArgumentException
78 {
79 if (maxSize < 1)
80 {
81 throw new IllegalArgumentException(
82 "The maxSize argument ("
83 + maxSize
84 + ") is not a positive integer.");
85 }
86 this.maxSize = maxSize;
87 records = new LogRecord[maxSize];
88 first = 0;
89 last = 0;
90 numElems = 0;
91 }
92
93 /**
94 * Add a <code>record</code> as the last record in the buffer.
95 *
96 * @param record must be non-null
97 *
98 */
99 public void add(LogRecord record)
100 {
101 records[last] = record;
102 if (++last == maxSize)
103 last = 0;
104
105 if (numElems < maxSize)
106 numElems++;
107 else if (++first == maxSize)
108 first = 0;
109 }
110
111 /**
112 * Get the <i>i</i> th oldest record currently in the buffer. If <em>i</em>
113 * is outside the range 0 to the number of elements currently in the
114 * buffer, then <code>null</code> is returned.
115 *
116 * @return may return null
117 *
118 */
119 public LogRecord get(int i)
120 {
121 if (i < 0 || i >= numElems)
122 return null;
123
124 return records[(first + i) % maxSize];
125 }
126
127 public int getMaxSize()
128 {
129 return maxSize;
130 }
131
132 /**
133 * Get the oldest (first) element in the buffer. The oldest element is
134 * removed from the buffer.
135 *
136 * @return may return null
137 *
138 */
139 public LogRecord get()
140 {
141 LogRecord r = null;
142 if (numElems > 0)
143 {
144 numElems--;
145 r = records[first];
146 records[first] = null;
147 if (++first == maxSize)
148 first = 0;
149 }
150 return r;
151 }
152
153 /**
154 * Get the number of elements in the buffer. This number is guaranteed to
155 * be in the range 0 to <code>maxSize</code> (inclusive).
156 */
157 public int length()
158 {
159 return numElems;
160 }
161
162 /**
163 * Resize the cyclic buffer to <code>newSize</code>.
164 *
165 * @throws IllegalArgumentException
166 * if <code>newSize</code> is negative.
167 */
168 public void resize(int newSize)
169 {
170 if (newSize < 0)
171 {
172 throw new IllegalArgumentException(
173 "Negative array size [" + newSize + "] not allowed.");
174 }
175 if (newSize == numElems)
176 {
177 return;
178 }
179
180 LogRecord[] temp = new LogRecord[newSize];
181
182 int loopLen = newSize < numElems ? newSize : numElems;
183
184 for (int i = 0; i < loopLen; i++)
185 {
186 temp[i] = records[first];
187 records[first] = null;
188 if (++first == numElems)
189 first = 0;
190 }
191 records = temp;
192 first = 0;
193 numElems = loopLen;
194 maxSize = newSize;
195 if (loopLen == newSize)
196 {
197 last = 0;
198 }
199 else
200 {
201 last = loopLen;
202 }
203 }
204
205 public String toString()
206 {
207 StringBuffer sb = new StringBuffer();
208 sb.append("length=" + length());
209 return sb.toString();
210 }
211 }