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