View Javadoc

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       * @return currentId the latest batch that has been sent to the client
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             // TODO: what if the id is not meant to be the latest?
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 }