View Javadoc

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