1 16 package org.apache.commons.collections; 17 18 import java.util.AbstractCollection ; 19 import java.util.Iterator ; 20 import java.util.NoSuchElementException ; 21 22 53 public class UnboundedFifoBuffer extends AbstractCollection implements Buffer { 54 55 protected Object [] m_buffer; 56 protected int m_head; 57 protected int m_tail; 58 59 67 public UnboundedFifoBuffer() { 68 this(32); 69 } 70 71 78 public UnboundedFifoBuffer(int initialSize) { 79 if (initialSize <= 0) { 80 throw new IllegalArgumentException ("The size must be greater than 0"); 81 } 82 m_buffer = new Object [initialSize + 1]; 83 m_head = 0; 84 m_tail = 0; 85 } 86 87 92 public int size() { 93 int size = 0; 94 95 if (m_tail < m_head) { 96 size = m_buffer.length - m_head + m_tail; 97 } else { 98 size = m_tail - m_head; 99 } 100 101 return size; 102 } 103 104 109 public boolean isEmpty() { 110 return (size() == 0); 111 } 112 113 121 public boolean add(final Object obj) { 122 if (obj == null) { 123 throw new NullPointerException ("Attempted to add null object to buffer"); 124 } 125 126 if (size() + 1 >= m_buffer.length) { 127 Object [] tmp = new Object [((m_buffer.length - 1) * 2) + 1]; 128 129 int j = 0; 130 for (int i = m_head; i != m_tail;) { 131 tmp[j] = m_buffer[i]; 132 m_buffer[i] = null; 133 134 j++; 135 i++; 136 if (i == m_buffer.length) { 137 i = 0; 138 } 139 } 140 141 m_buffer = tmp; 142 m_head = 0; 143 m_tail = j; 144 } 145 146 m_buffer[m_tail] = obj; 147 m_tail++; 148 if (m_tail >= m_buffer.length) { 149 m_tail = 0; 150 } 151 return true; 152 } 153 154 160 public Object get() { 161 if (isEmpty()) { 162 throw new BufferUnderflowException("The buffer is already empty"); 163 } 164 165 return m_buffer[m_head]; 166 } 167 168 174 public Object remove() { 175 if (isEmpty()) { 176 throw new BufferUnderflowException("The buffer is already empty"); 177 } 178 179 Object element = m_buffer[m_head]; 180 181 if (null != element) { 182 m_buffer[m_head] = null; 183 184 m_head++; 185 if (m_head >= m_buffer.length) { 186 m_head = 0; 187 } 188 } 189 190 return element; 191 } 192 193 199 private int increment(int index) { 200 index++; 201 if (index >= m_buffer.length) { 202 index = 0; 203 } 204 return index; 205 } 206 207 213 private int decrement(int index) { 214 index--; 215 if (index < 0) { 216 index = m_buffer.length - 1; 217 } 218 return index; 219 } 220 221 226 public Iterator iterator() { 227 return new Iterator () { 228 229 private int index = m_head; 230 private int lastReturnedIndex = -1; 231 232 public boolean hasNext() { 233 return index != m_tail; 234 235 } 236 237 public Object next() { 238 if (!hasNext()) 239 throw new NoSuchElementException (); 240 lastReturnedIndex = index; 241 index = increment(index); 242 return m_buffer[lastReturnedIndex]; 243 } 244 245 public void remove() { 246 if (lastReturnedIndex == -1) 247 throw new IllegalStateException (); 248 249 if (lastReturnedIndex == m_head) { 251 UnboundedFifoBuffer.this.remove(); 252 lastReturnedIndex = -1; 253 return; 254 } 255 256 int i = lastReturnedIndex + 1; 258 while (i != m_tail) { 259 if (i >= m_buffer.length) { 260 m_buffer[i - 1] = m_buffer[0]; 261 i = 0; 262 } else { 263 m_buffer[i - 1] = m_buffer[i]; 264 i++; 265 } 266 } 267 268 lastReturnedIndex = -1; 269 m_tail = decrement(m_tail); 270 m_buffer[m_tail] = null; 271 index = decrement(index); 272 } 273 274 }; 275 } 276 277 } 278 | Popular Tags |