Home | History | Annotate | Download | only in util
      1 package com.jme3.util;
      2 
      3 import java.util.Iterator;
      4 import java.util.NoSuchElementException;
      5 
      6 /**
      7  * Ring buffer (fixed size queue) implementation using a circular array (array
      8  * with wrap-around).
      9  */
     10 // suppress unchecked warnings in Java 1.5.0_6 and later
     11 @SuppressWarnings("unchecked")
     12 public class RingBuffer<T> implements Iterable<T> {
     13 
     14     private T[] buffer;          // queue elements
     15     private int count = 0;          // number of elements on queue
     16     private int indexOut = 0;       // index of first element of queue
     17     private int indexIn = 0;       // index of next available slot
     18 
     19     // cast needed since no generic array creation in Java
     20     public RingBuffer(int capacity) {
     21         buffer = (T[]) new Object[capacity];
     22     }
     23 
     24     public boolean isEmpty() {
     25         return count == 0;
     26     }
     27 
     28     public int size() {
     29         return count;
     30     }
     31 
     32     public void push(T item) {
     33         if (count == buffer.length) {
     34             throw new RuntimeException("Ring buffer overflow");
     35         }
     36         buffer[indexIn] = item;
     37         indexIn = (indexIn + 1) % buffer.length;     // wrap-around
     38         count++;
     39     }
     40 
     41     public T pop() {
     42         if (isEmpty()) {
     43             throw new RuntimeException("Ring buffer underflow");
     44         }
     45         T item = buffer[indexOut];
     46         buffer[indexOut] = null;                  // to help with garbage collection
     47         count--;
     48         indexOut = (indexOut + 1) % buffer.length; // wrap-around
     49         return item;
     50     }
     51 
     52     public Iterator<T> iterator() {
     53         return new RingBufferIterator();
     54     }
     55 
     56     // an iterator, doesn't implement remove() since it's optional
     57     private class RingBufferIterator implements Iterator<T> {
     58 
     59         private int i = 0;
     60 
     61         public boolean hasNext() {
     62             return i < count;
     63         }
     64 
     65         public void remove() {
     66             throw new UnsupportedOperationException();
     67         }
     68 
     69         public T next() {
     70             if (!hasNext()) {
     71                 throw new NoSuchElementException();
     72             }
     73             return buffer[i++];
     74         }
     75     }
     76 }
     77