1 package org.mortbay.cometd.ext;
2
3 import org.mortbay.util.ArrayQueue;
4
5
6 public class ArrayIdQueue<E> extends ArrayQueue<E>
7 {
8 private int[] _ids;
9 private int _currentId;
10
11
12 public ArrayIdQueue()
13 {
14 super();
15 _ids=new int[DEFAULT_CAPACITY];
16 }
17
18
19 public ArrayIdQueue(int capacity)
20 {
21 super(capacity);
22 _ids=new int[capacity];
23 }
24
25
26 public ArrayIdQueue(int initCapacity, int growBy)
27 {
28 super(initCapacity,growBy);
29 _ids=new int[initCapacity];
30 }
31
32
33 public ArrayIdQueue(int initCapacity, int growBy, Object lock)
34 {
35 super(initCapacity,growBy,lock);
36 _ids=new int[initCapacity];
37 }
38
39
40
41
42
43 public int getCurrentId()
44 {
45 synchronized (_lock)
46 {
47 return _currentId;
48 }
49 }
50
51
52 public void setCurrentId(int currentId)
53 {
54 synchronized (_lock)
55 {
56 _currentId=currentId;
57 }
58 }
59
60
61 public void incrementCurrentId()
62 {
63 synchronized (_lock)
64 {
65 _currentId++;
66 }
67 }
68
69
70 public boolean add(E e)
71 {
72 synchronized (_lock)
73 {
74 final int nextSlot=_nextSlot;
75 super.add(e);
76 _ids[nextSlot]=_currentId;
77 }
78 return true;
79 }
80
81
82 public void addUnsafe(E e)
83 {
84 int nextSlot=_nextSlot;
85 super.addUnsafe(e);
86 _ids[nextSlot]=_currentId;
87
88 }
89
90
91 public boolean offer(E e)
92 {
93 synchronized (_lock)
94 {
95 final int nextSlot=_nextSlot;
96 super.offer(e);
97 _ids[nextSlot]=_currentId;
98 }
99 return true;
100
101 }
102
103
104 public int getAssociatedId(int index)
105 {
106 synchronized(_lock)
107 {
108 if (index<0 || index>=_size)
109 throw new IndexOutOfBoundsException("!("+0+"<"+index+"<="+_size+")");
110 int i = (_nextE+index)%_ids.length;
111 return _ids[i];
112 }
113 }
114
115
116 public long getAssociatedIdUnsafe(int index)
117 {
118 int i = (_nextE+index)%_ids.length;
119 return _ids[i];
120 }
121
122
123 public E remove(int index)
124 {
125 synchronized(_lock)
126 {
127 int nextSlot = _nextSlot;
128 E e = super.remove(index);
129
130 int i = _nextE+index;
131 if (i>=_ids.length)
132 i-=_ids.length;
133
134 if (i<nextSlot)
135 {
136 System.arraycopy(_ids,i+1,_ids,i,nextSlot-i);
137 nextSlot--;
138 }
139 else
140 {
141 System.arraycopy(_ids,i+1,_ids,i,_ids.length-i-1);
142 if (nextSlot>0)
143 {
144 _ids[_ids.length-1]=_ids[0];
145 System.arraycopy(_ids,1,_ids,0,nextSlot-1);
146 nextSlot--;
147 }
148 else
149 nextSlot=_ids.length-1;
150 }
151
152 return e;
153 }
154 }
155
156
157 public E set(int index, E element)
158 {
159 synchronized(_lock)
160 {
161 E old = super.set(index, element);
162
163 int i = _nextE+index;
164 if (i>=_ids.length)
165 i-=_ids.length;
166
167 _ids[i]=_currentId;
168 return old;
169 }
170 }
171
172
173 public void add(int index, E element)
174 {
175 synchronized(_lock)
176 {
177 int nextSlot = _nextSlot;
178 super.add(index, element);
179
180 if (index==_size)
181 {
182 _ids[index] = _currentId;
183 }
184 else
185 {
186 int i = _nextE+index;
187 if (i>=_ids.length)
188 i-=_ids.length;
189
190 if (i<nextSlot)
191 {
192 System.arraycopy(_ids,i,_ids,i+1,nextSlot-i);
193 _ids[i]=_currentId;
194 }
195 else
196 {
197 if (nextSlot>0)
198 {
199 System.arraycopy(_ids,0,_ids,1,nextSlot);
200 _ids[0]=_ids[_ids.length-1];
201 }
202
203 System.arraycopy(_ids,i,_ids,i+1,_ids.length-i-1);
204 _ids[i]=_currentId;
205 }
206 }
207 }
208 }
209
210 protected boolean grow()
211 {
212 int nextE=_nextE;
213 int nextSlot=_nextSlot;
214
215 if (!super.grow())
216 return false;
217
218 int[] Ids=new int[_elements.length];
219 int split=_ids.length - nextE;
220 if (split > 0)
221 System.arraycopy(_ids,nextE,Ids,0,split);
222 if (nextE != 0)
223 System.arraycopy(_ids,0,Ids,split,nextSlot);
224
225 _ids=Ids;
226 return true;
227 }
228
229
230
231 }