Files
Brainstorm/Common/src/com/common/util/CircularQueue.java
2014-05-30 10:31:51 -07:00

152 lines
4.3 KiB
Java

/*
* Copyright (c) 2002,2009 Declarative Engineering LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Declarative Engineering LLC
* verson 1 which accompanies this distribution, and is available at
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
*/
package com.common.util;
import com.common.debug.Debug;
import com.common.debug.QueuedLog;
/**
* Implements a circular queue - FIFO (first in first out) collection where the size is fixed and new entries will overwrite the oldest entries and entries cannot be removed.
* <p><b>WARNING: This class is not thread safe.</b>
*/
public class CircularQueue implements ICircularQueue {
private Object[] data = null;
private boolean hasLooped = false;
private int nextIndex = 0;
/**
* An iterator over the circular queue.
* <p><b>WARNING: This class is not thread safe. The iterator is designed to only be used either as a forward or reverse iterator, but not necessarily both at the same time.</b>
*/
private class Iterator implements IReversableIterator {
private int startIndex = -1;
private int index = -1;
private Iterator() {
}//Iterator()//
public boolean remove() {
//Values cannot be removed from a circular queue.//
throw new com.common.exception.MethodNotSupportedException();
}//remove()//
public boolean hasNext() {
return getSize() > 0 && (index == -1 || index != startIndex);
}//hasNext()//
public boolean hasPrevious() {
return getSize() > 0 && (index == -1 || index != startIndex);
}//hasPrevious()//
public Object next() {
Object result;
if(!hasNext()) {
throw new IndexOutOfBoundsException("Call iterator.hasNext() before calling iterator.next()");
}//if//
if(index == -1) {
if(CircularQueue.this.hasLooped) {
startIndex = index = CircularQueue.this.nextIndex == 0 ? CircularQueue.this.data.length - 1 : CircularQueue.this.nextIndex - 1;
}//if//
else {
index = 0;
startIndex = CircularQueue.this.nextIndex;
}//else//
}//if//
//Increment & wrap the index.//
if(++index == CircularQueue.this.data.length && CircularQueue.this.hasLooped) {
index = 0;
}//if//
result = data[index];
return result;
}//next()//
public Object previous() {
Object result;
if(!hasPrevious()) {
throw new IndexOutOfBoundsException("Call iterator.hasPrevious() before calling iterator.previous()");
}//if//
if(index == -1) {
if(CircularQueue.this.hasLooped) {
startIndex = index = CircularQueue.this.nextIndex == 0 ? CircularQueue.this.data.length : CircularQueue.this.nextIndex;
}//if//
else {
index = CircularQueue.this.nextIndex;
startIndex = 0;
}//else//
}//if//
if(--index == -1 && CircularQueue.this.hasLooped) {
index = CircularQueue.this.data.length - 1;
}//if//
result = data[index];
return result;
}//previous()//
public void resetToFront() {
startIndex = index = -1;
}//resetToFront()//
public void resetToBack() {
startIndex = index = -1;
}//resetToBack()//
}//Iterator//
/**
* CircularQueue constructor.
*/
public CircularQueue(int size) {
super();
data = new Object[size];
}//CircularQueue()//
/**
* ICircularQueue#enqueue(Object)
*/
public boolean enqueue(Object value) {
data[nextIndex++] = value;
if(nextIndex == data.length) {
nextIndex = 0;
hasLooped = true;
}//if//
return true;
}//enqueue()//
/**
* ICircularQueue#getSize()
*/
public int getSize() {
return hasLooped ? data.length : nextIndex;
}//getSize()//
/**
* ICircularQueue#iterator()
*/
public IReversableIterator iterator() {
return new Iterator();
}//iterator()//
/**
* Reads the collection from the stream.
* @param in java.io.ObjectInput The stream that the object data can be read from.
*/
public void readExternal(java.io.ObjectInput in) throws java.io.IOException, ClassNotFoundException {
data = (Object[]) in.readObject();
hasLooped = in.readBoolean();
nextIndex = in.readInt();
}//readExternal()//
/**
* Writes the collection to the stream.
* @param out java.io.ObjectOutput The stream that the object data can be written to.
*/
public void writeExternal(java.io.ObjectOutput out) throws java.io.IOException {
out.writeObject(data);
out.writeBoolean(hasLooped);
out.writeInt(nextIndex);
}//writeExternal()//
}//CircularQueue//