Initial commit from SVN.
This commit is contained in:
151
Common/src/com/common/util/CircularQueue.java
Normal file
151
Common/src/com/common/util/CircularQueue.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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//
|
||||
Reference in New Issue
Block a user