package jadex.rules.state.javaimpl; /** * Container for queue attribute values. */ class RingBufferQueue { //-------- constants -------- /** The default inital capacity of the agenda buffer. */ protected static final int DEFAULT_INITIAL_CAPACITY = 16; //-------- attributes -------- /** * The list of values. * For efficiency we use a custom non-blocking, non-synchronized queue. * The implementation is based on an array used as buffer, an integer for * the current size, and a cursor indicating the current start of the * queue. When the cursor moves beyond the end of the array it starts * again from the beginning. When the size gets larger than the buffer, * the array will be resized. Shrinking of the array has not been * implemented, and is probably not needed(?). */ protected Object[] values; /** The size of the queue. */ protected int size; /** The pointer to the currently first value. */ protected int current; //-------- constructors -------- /** * Create a new ring buffer queue. */ public RingBufferQueue() { this.values = new Object[DEFAULT_INITIAL_CAPACITY]; this.size = 0; this.current = 0; } //-------- methods -------- /** * Remove the first value from the queue, if any. * @return The first value from the queue, or null if the queue is empty. */ public Object removeFirstValue() { Object ret = null; // Check if there is a current value. if(size>0) { // Save the return value. ret = values[current]; // Move to next element in buffer. values[current] = null; // To allow garbage collection. current = (current+1)%values.length; size--; } return ret; } /** * Add a value to the queue. * @param value The value to add. */ public void addValue(Object value) { // Resize buffer, if necessary. if(size==values.length) { // Create new buffer with doubled size. Object[] newvalues = new Object[values.length*2]; // Copy into new buffer the elements from cursor to the end of the old buffer. System.arraycopy(values, current, newvalues, 0, values.length-current); // When there ere elements to the left of the cursor... if(current>0) { // Copy remaining elements to new buffer. System.arraycopy(values, 0, newvalues, values.length-current, current); } // Switch to new buffer, which starts at index 0. values = newvalues; current = 0; // System.out.println("New buffersize: "+values.length); } // Add entry to end of the buffer, and increment size. this.values[(current+(size++))%values.length] = value; } /** * Test if the queue is empty. * @return True, if the queue is empty. */ public boolean isEmpty() { return size==0; } }