1 16 package org.apache.commons.collections.buffer; 17 18 import java.io.IOException ; 19 import java.io.ObjectInputStream ; 20 import java.io.ObjectOutputStream ; 21 import java.io.Serializable ; 22 import java.util.AbstractCollection ; 23 import java.util.Arrays ; 24 import java.util.Collection ; 25 import java.util.Iterator ; 26 import java.util.NoSuchElementException ; 27 28 import org.apache.commons.collections.BoundedCollection; 29 import org.apache.commons.collections.Buffer; 30 import org.apache.commons.collections.BufferOverflowException; 31 import org.apache.commons.collections.BufferUnderflowException; 32 33 64 public class BoundedFifoBuffer extends AbstractCollection 65 implements Buffer, BoundedCollection, Serializable { 66 67 68 private static final long serialVersionUID = 5603722811189451017L; 69 70 private transient Object [] elements; 71 private transient int start = 0; 72 private transient int end = 0; 73 private transient boolean full = false; 74 private final int maxElements; 75 76 80 public BoundedFifoBuffer() { 81 this(32); 82 } 83 84 91 public BoundedFifoBuffer(int size) { 92 if (size <= 0) { 93 throw new IllegalArgumentException ("The size must be greater than 0"); 94 } 95 elements = new Object [size]; 96 maxElements = elements.length; 97 } 98 99 107 public BoundedFifoBuffer(Collection coll) { 108 this(coll.size()); 109 addAll(coll); 110 } 111 112 119 private void writeObject(ObjectOutputStream out) throws IOException { 120 out.defaultWriteObject(); 121 out.writeInt(size()); 122 for (Iterator it = iterator(); it.hasNext();) { 123 out.writeObject(it.next()); 124 } 125 } 126 127 134 private void readObject(ObjectInputStream in) throws IOException , ClassNotFoundException { 135 in.defaultReadObject(); 136 elements = new Object [maxElements]; 137 int size = in.readInt(); 138 for (int i = 0; i < size; i++) { 139 elements[i] = in.readObject(); 140 } 141 start = 0; 142 end = size; 143 full = (size == maxElements); 144 } 145 146 152 public int size() { 153 int size = 0; 154 155 if (end < start) { 156 size = maxElements - start + end; 157 } else if (end == start) { 158 size = (full ? maxElements : 0); 159 } else { 160 size = end - start; 161 } 162 163 return size; 164 } 165 166 171 public boolean isEmpty() { 172 return size() == 0; 173 } 174 175 180 public boolean isFull() { 181 return size() == maxElements; 182 } 183 184 189 public int maxSize() { 190 return maxElements; 191 } 192 193 196 public void clear() { 197 full = false; 198 start = 0; 199 end = 0; 200 Arrays.fill(elements, null); 201 } 202 203 211 public boolean add(Object element) { 212 if (null == element) { 213 throw new NullPointerException ("Attempted to add null object to buffer"); 214 } 215 216 if (full) { 217 throw new BufferOverflowException("The buffer cannot hold more than " + maxElements + " objects."); 218 } 219 220 elements[end++] = element; 221 222 if (end >= maxElements) { 223 end = 0; 224 } 225 226 if (end == start) { 227 full = true; 228 } 229 230 return true; 231 } 232 233 239 public Object get() { 240 if (isEmpty()) { 241 throw new BufferUnderflowException("The buffer is already empty"); 242 } 243 244 return elements[start]; 245 } 246 247 253 public Object remove() { 254 if (isEmpty()) { 255 throw new BufferUnderflowException("The buffer is already empty"); 256 } 257 258 Object element = elements[start]; 259 260 if (null != element) { 261 elements[start++] = null; 262 263 if (start >= maxElements) { 264 start = 0; 265 } 266 267 full = false; 268 } 269 270 return element; 271 } 272 273 279 private int increment(int index) { 280 index++; 281 if (index >= maxElements) { 282 index = 0; 283 } 284 return index; 285 } 286 287 293 private int decrement(int index) { 294 index--; 295 if (index < 0) { 296 index = maxElements - 1; 297 } 298 return index; 299 } 300 301 306 public Iterator iterator() { 307 return new Iterator () { 308 309 private int index = start; 310 private int lastReturnedIndex = -1; 311 private boolean isFirst = full; 312 313 public boolean hasNext() { 314 return isFirst || (index != end); 315 316 } 317 318 public Object next() { 319 if (!hasNext()) { 320 throw new NoSuchElementException (); 321 } 322 isFirst = false; 323 lastReturnedIndex = index; 324 index = increment(index); 325 return elements[lastReturnedIndex]; 326 } 327 328 public void remove() { 329 if (lastReturnedIndex == -1) { 330 throw new IllegalStateException (); 331 } 332 333 if (lastReturnedIndex == start) { 335 BoundedFifoBuffer.this.remove(); 336 lastReturnedIndex = -1; 337 return; 338 } 339 340 int i = lastReturnedIndex + 1; 342 while (i != end) { 343 if (i >= maxElements) { 344 elements[i - 1] = elements[0]; 345 i = 0; 346 } else { 347 elements[i - 1] = elements[i]; 348 i++; 349 } 350 } 351 352 lastReturnedIndex = -1; 353 end = decrement(end); 354 elements[end] = null; 355 full = false; 356 index = decrement(index); 357 } 358 359 }; 360 } 361 362 } 363 | Popular Tags |