1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.mortbay.util;
16
17 import java.util.AbstractList;
18 import java.util.Collection;
19 import java.util.Iterator;
20 import java.util.List;
21 import java.util.NoSuchElementException;
22 import java.util.Queue;
23
24
25
26
27
28
29
30
31
32
33
34 public class ArrayQueue<E> extends AbstractList<E> implements Queue<E>
35 {
36 public final int DEFAULT_CAPACITY=64;
37 public final int DEFAULT_GROWTH=32;
38 private Object _lock=this;
39 private Object[] _elements;
40 private int _nextE;
41 private int _nextSlot;
42 private int _size;
43 private int _growCapacity;
44
45
46 public ArrayQueue()
47 {
48 _elements=new Object[64];
49 _growCapacity=32;
50 }
51
52
53 public ArrayQueue(int capacity)
54 {
55 _elements=new Object[capacity];
56 _growCapacity=-1;
57 }
58
59
60 public ArrayQueue(int initCapacity,int growBy)
61 {
62 _elements=new Object[initCapacity];
63 _growCapacity=growBy;
64 }
65
66
67 public ArrayQueue(int initCapacity,int growBy,Object lock)
68 {
69 _elements=new Object[initCapacity];
70 _growCapacity=growBy;
71 _lock=lock;
72 }
73
74
75 public int getCapacity()
76 {
77 return _elements.length;
78 }
79
80
81 public boolean add(E e)
82 {
83 synchronized(_lock)
84 {
85 _size++;
86 _elements[_nextSlot++]=e;
87 if (_nextSlot==_elements.length)
88 _nextSlot=0;
89 if (_nextSlot==_nextE)
90 grow();
91 }
92 return true;
93 }
94
95
96
97
98
99
100 public void addUnsafe(E e)
101 {
102 _size++;
103 _elements[_nextSlot++]=e;
104 if (_nextSlot==_elements.length)
105 _nextSlot=0;
106 if (_nextSlot==_nextE)
107 grow();
108 }
109
110
111 public E element()
112 {
113 synchronized(_lock)
114 {
115 if (_nextSlot==_nextE)
116 throw new NoSuchElementException();
117 return (E)_elements[_nextE];
118 }
119 }
120
121
122 public boolean offer(E e)
123 {
124 synchronized(_lock)
125 {
126 _size++;
127 _elements[_nextSlot++]=e;
128 if (_nextSlot==_elements.length)
129 _nextSlot=0;
130 if (_nextSlot==_nextE)
131 {
132 if (_growCapacity<=0)
133 return false;
134
135 Object[] elements=new Object[_elements.length+_growCapacity];
136
137 int split=_elements.length-_nextE;
138 if (split>0)
139 System.arraycopy(_elements,_nextE,elements,0,split);
140 if (_nextE!=0)
141 System.arraycopy(_elements,0,elements,split,_nextSlot);
142
143 _elements=elements;
144 _nextE=0;
145 _nextSlot=_size;
146 }
147
148 return true;
149 }
150 }
151
152
153 public E peek()
154 {
155 synchronized(_lock)
156 {
157 if (_nextSlot==_nextE)
158 return null;
159 return (E)_elements[_nextE];
160 }
161 }
162
163
164 public E poll()
165 {
166 synchronized(_lock)
167 {
168 if (_size==0)
169 return null;
170 E e = (E)_elements[_nextE];
171 _elements[_nextE]=null;
172 _size--;
173 if (++_nextE==_elements.length)
174 _nextE=0;
175 return e;
176 }
177 }
178
179
180 public E remove()
181 {
182 synchronized(_lock)
183 {
184 if (_nextSlot==_nextE)
185 throw new NoSuchElementException();
186 E e = (E)_elements[_nextE++];
187 if (_nextE==_elements.length)
188 _nextE=0;
189 return e;
190 }
191 }
192
193
194 public void clear()
195 {
196 synchronized(_lock)
197 {
198 _size=0;
199 _nextE=0;
200 _nextSlot=0;
201 }
202 }
203
204
205 public boolean isEmpty()
206 {
207 synchronized(_lock)
208 {
209 return _size==0;
210 }
211 }
212
213
214 public int size()
215 {
216 return _size;
217 }
218
219
220 public E get(int index)
221 {
222 synchronized(_lock)
223 {
224 if (index<0 || index>=_size)
225 throw new IndexOutOfBoundsException("!("+0+"<"+index+"<="+_size+")");
226 int i = _nextE+index;
227 if (i>=_elements.length)
228 i-=_elements.length;
229 return (E)_elements[i];
230 }
231 }
232
233
234
235
236
237
238 public E getUnsafe(int index)
239 {
240 int i = _nextE+index;
241 if (i>=_elements.length)
242 i-=_elements.length;
243 return (E)_elements[i];
244 }
245
246
247 public E remove(int index)
248 {
249 synchronized(_lock)
250 {
251 if (index<0 || index>=_size)
252 throw new IndexOutOfBoundsException("!("+0+"<"+index+"<="+_size+")");
253
254 int i = _nextE+index;
255 if (i>=_elements.length)
256 i-=_elements.length;
257 E old=(E)_elements[i];
258
259 if (i<_nextSlot)
260 {
261
262
263 System.arraycopy(_elements,i+1,_elements,i,_nextSlot-i);
264 _nextSlot--;
265 _size--;
266 }
267 else
268 {
269
270
271 System.arraycopy(_elements,i+1,_elements,i,_elements.length-1);
272 if (_nextSlot>0)
273 {
274 _elements[_elements.length]=_elements[0];
275 System.arraycopy(_elements,1,_elements,0,_nextSlot-1);
276 _nextSlot--;
277 }
278 else
279 _nextSlot=_elements.length-1;
280
281 _size--;
282 }
283
284 return old;
285 }
286 }
287
288
289 public E set(int index, E element)
290 {
291 synchronized(_lock)
292 {
293 if (index<0 || index>=_size)
294 throw new IndexOutOfBoundsException("!("+0+"<"+index+"<="+_size+")");
295
296 int i = _nextE+index;
297 if (i>=_elements.length)
298 i-=_elements.length;
299 E old=(E)_elements[i];
300 _elements[i]=element;
301 return old;
302 }
303 }
304
305
306 public void add(int index, E element)
307 {
308 synchronized(_lock)
309 {
310 if (index<0 || index>_size)
311 throw new IndexOutOfBoundsException("!("+0+"<"+index+"<="+_size+")");
312
313 if (index==_size)
314 {
315 add(element);
316 }
317 else
318 {
319 int i = _nextE+index;
320 if (i>=_elements.length)
321 i-=_elements.length;
322
323 _size++;
324 _nextSlot++;
325 if (_nextSlot==_elements.length)
326 _nextSlot=0;
327
328 if (_nextSlot==_nextE)
329 grow();
330
331 if (i<_nextSlot)
332 {
333
334
335
336
337 System.arraycopy(_elements,i,_elements,i+1,_nextSlot-i);
338 _elements[i]=element;
339 }
340 else
341 {
342
343
344 if (_nextSlot>0)
345 {
346 System.arraycopy(_elements,0,_elements,1,_nextSlot);
347 _elements[0]=_elements[_elements.length-1];
348 }
349
350 System.arraycopy(_elements,i,_elements,i+1,_elements.length-i-1);
351 _elements[i]=element;
352 }
353 }
354 }
355 }
356
357 protected void grow()
358 {
359 if (_growCapacity<=0)
360 throw new IllegalStateException("Full");
361
362 Object[] elements=new Object[_elements.length+_growCapacity];
363
364 int split=_elements.length-_nextE;
365 if (split>0)
366 System.arraycopy(_elements,_nextE,elements,0,split);
367 if (_nextE!=0)
368 System.arraycopy(_elements,0,elements,split,_nextSlot);
369
370 _elements=elements;
371 _nextE=0;
372 _nextSlot=_size;
373 }
374 }