Removed BCNN classes
This commit is contained in:
@@ -1,151 +0,0 @@
|
|||||||
package net.berack.upo.valpre.bcnn;
|
|
||||||
|
|
||||||
import net.berack.upo.valpre.bcnn.simutil.*;
|
|
||||||
import net.berack.upo.valpre.bcnn.simutil.Queue;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
class Sim {
|
|
||||||
|
|
||||||
// Class Sim variables
|
|
||||||
public static double Clock, MeanInterArrivalTime, MeanServiceTime, SIGMA, LastEventTime,
|
|
||||||
TotalBusy, MaxQueueLength, SumResponseTime;
|
|
||||||
public static long NumberOfCustomers, QueueLength, NumberInService,
|
|
||||||
TotalCustomers, NumberOfDepartures, LongService;
|
|
||||||
|
|
||||||
public final static int arrival = 1;
|
|
||||||
public final static int departure = 2;
|
|
||||||
|
|
||||||
public static EventList FutureEventList;
|
|
||||||
public static Queue Customers;
|
|
||||||
public static Random stream;
|
|
||||||
|
|
||||||
public static void main(String argv[]) {
|
|
||||||
|
|
||||||
MeanInterArrivalTime = 4.5; MeanServiceTime = 3.2;
|
|
||||||
SIGMA = 0.6; TotalCustomers = 1000;
|
|
||||||
long seed = Long.parseLong(argv[0]);
|
|
||||||
|
|
||||||
stream = new Random(seed); // initialize rng stream
|
|
||||||
FutureEventList = new EventList();
|
|
||||||
Customers = new Queue();
|
|
||||||
|
|
||||||
Initialization();
|
|
||||||
|
|
||||||
// Loop until first "TotalCustomers" have departed
|
|
||||||
while(NumberOfDepartures < TotalCustomers ) {
|
|
||||||
Event evt = (Event)FutureEventList.getMin(); // get imminent event
|
|
||||||
FutureEventList.dequeue(); // be rid of it
|
|
||||||
Clock = evt.get_time(); // advance simulation time
|
|
||||||
if( evt.get_type() == arrival ) ProcessArrival(evt);
|
|
||||||
else ProcessDeparture(evt);
|
|
||||||
}
|
|
||||||
ReportGeneration();
|
|
||||||
}
|
|
||||||
|
|
||||||
// seed the event list with TotalCustomers arrivals
|
|
||||||
public static void Initialization() {
|
|
||||||
Clock = 0.0;
|
|
||||||
QueueLength = 0;
|
|
||||||
NumberInService = 0;
|
|
||||||
LastEventTime = 0.0;
|
|
||||||
TotalBusy = 0 ;
|
|
||||||
MaxQueueLength = 0;
|
|
||||||
SumResponseTime = 0;
|
|
||||||
NumberOfDepartures = 0;
|
|
||||||
LongService = 0;
|
|
||||||
|
|
||||||
// create first arrival event
|
|
||||||
Event evt = new Event(arrival, exponential( stream, MeanInterArrivalTime));
|
|
||||||
FutureEventList.enqueue( evt );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ProcessArrival(Event evt) {
|
|
||||||
Customers.enqueue(evt);
|
|
||||||
QueueLength++;
|
|
||||||
// if the server is idle, fetch the event, do statistics
|
|
||||||
// and put into service
|
|
||||||
if( NumberInService == 0) ScheduleDeparture();
|
|
||||||
else TotalBusy += (Clock - LastEventTime); // server is busy
|
|
||||||
|
|
||||||
// adjust max queue length statistics
|
|
||||||
if (MaxQueueLength < QueueLength) MaxQueueLength = QueueLength;
|
|
||||||
|
|
||||||
// schedule the next arrival
|
|
||||||
Event next_arrival = new Event(arrival, Clock+exponential(stream, MeanInterArrivalTime));
|
|
||||||
FutureEventList.enqueue( next_arrival );
|
|
||||||
LastEventTime = Clock;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ScheduleDeparture() {
|
|
||||||
double ServiceTime;
|
|
||||||
// get the job at the head of the queue
|
|
||||||
while (( ServiceTime = normal(stream, MeanServiceTime, SIGMA)) < 0 );
|
|
||||||
Event depart = new Event(departure,Clock+ServiceTime);
|
|
||||||
FutureEventList.enqueue( depart );
|
|
||||||
NumberInService = 1;
|
|
||||||
QueueLength--;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ProcessDeparture(Event e) {
|
|
||||||
// get the customer description
|
|
||||||
Event finished = (Event) Customers.dequeue();
|
|
||||||
// if there are customers in the queue then schedule
|
|
||||||
// the departure of the next one
|
|
||||||
if( QueueLength > 0 ) ScheduleDeparture();
|
|
||||||
else NumberInService = 0;
|
|
||||||
// measure the response time and add to the sum
|
|
||||||
double response = (Clock - finished.get_time());
|
|
||||||
SumResponseTime += response;
|
|
||||||
if( response > 4.0 ) LongService++; // record long service
|
|
||||||
TotalBusy += (Clock - LastEventTime );
|
|
||||||
NumberOfDepartures++;
|
|
||||||
LastEventTime = Clock;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ReportGeneration() {
|
|
||||||
double RHO = TotalBusy/Clock;
|
|
||||||
double AVGR = SumResponseTime/TotalCustomers;
|
|
||||||
double PC4 = ((double)LongService)/TotalCustomers;
|
|
||||||
|
|
||||||
|
|
||||||
System.out.println( "SINGLE SERVER QUEUE SIMULATION - GROCERY STORE CHECKOUT COUNTER ");
|
|
||||||
System.out.println( "\tMEAN INTERARRIVAL TIME "
|
|
||||||
+ MeanInterArrivalTime );
|
|
||||||
System.out.println( "\tMEAN SERVICE TIME "
|
|
||||||
+ MeanServiceTime );
|
|
||||||
System.out.println( "\tSTANDARD DEVIATION OF SERVICE TIMES " + SIGMA );
|
|
||||||
System.out.println( "\tNUMBER OF CUSTOMERS SERVED " + TotalCustomers );
|
|
||||||
System.out.println();
|
|
||||||
System.out.println( "\tSERVER UTILIZATION " + RHO );
|
|
||||||
System.out.println( "\tMAXIMUM LINE LENGTH " + MaxQueueLength );
|
|
||||||
System.out.println( "\tAVERAGE RESPONSE TIME " + AVGR + " MINUTES" );
|
|
||||||
System.out.println( "\tPROPORTION WHO SPEND FOUR ");
|
|
||||||
System.out.println( "\t MINUTES OR MORE IN SYSTEM " + PC4 );
|
|
||||||
System.out.println( "\tSIMULATION RUNLENGTH " + Clock + " MINUTES" );
|
|
||||||
System.out.println( "\tNUMBER OF DEPARTURES " + TotalCustomers );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double exponential(Random rng, double mean) {
|
|
||||||
return -mean*Math.log( rng.nextDouble() );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double SaveNormal;
|
|
||||||
public static int NumNormals = 0;
|
|
||||||
public static final double PI = 3.1415927 ;
|
|
||||||
|
|
||||||
public static double normal(Random rng, double mean, double sigma) {
|
|
||||||
double ReturnNormal;
|
|
||||||
// should we generate two normals?
|
|
||||||
if(NumNormals == 0 ) {
|
|
||||||
double r1 = rng.nextDouble();
|
|
||||||
double r2 = rng.nextDouble();
|
|
||||||
ReturnNormal = Math.sqrt(-2*Math.log(r1))*Math.cos(2*PI*r2);
|
|
||||||
SaveNormal = Math.sqrt(-2*Math.log(r1))*Math.sin(2*PI*r2);
|
|
||||||
NumNormals = 1;
|
|
||||||
} else {
|
|
||||||
NumNormals = 0;
|
|
||||||
ReturnNormal = SaveNormal;
|
|
||||||
}
|
|
||||||
return ReturnNormal*sigma + mean ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package net.berack.upo.valpre.bcnn.simutil;
|
|
||||||
|
|
||||||
public class Event implements Comparable<Object> {
|
|
||||||
|
|
||||||
public Event(int a_type, double a_time) { _type = a_type; time = a_time; }
|
|
||||||
|
|
||||||
public double time;
|
|
||||||
private int _type;
|
|
||||||
|
|
||||||
public int get_type() { return _type; }
|
|
||||||
public double get_time() { return time; }
|
|
||||||
|
|
||||||
public Event leftlink, rightlink, uplink;
|
|
||||||
|
|
||||||
public int compareTo(Object _cmpEvent ) {
|
|
||||||
double _cmp_time = ((Event) _cmpEvent).get_time() ;
|
|
||||||
if( this.time < _cmp_time) return -1;
|
|
||||||
if( this.time == _cmp_time) return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,195 +0,0 @@
|
|||||||
package net.berack.upo.valpre.bcnn.simutil;
|
|
||||||
|
|
||||||
// EventList is implemented as a splay tree
|
|
||||||
// v1. class Event knows this and has fields
|
|
||||||
// leftlink, rightlink, uplink
|
|
||||||
public class EventList {
|
|
||||||
Event root;
|
|
||||||
Event update_p;
|
|
||||||
Event left,right,next,temp,farleft,farfarleft;
|
|
||||||
double ntime;
|
|
||||||
boolean update_code;
|
|
||||||
int size = 0;
|
|
||||||
Object owner;
|
|
||||||
|
|
||||||
public EventList(){ }
|
|
||||||
|
|
||||||
public String toString(){
|
|
||||||
return "EventList ";
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEmpty(){
|
|
||||||
return (this.root == null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enqueue(Event n){
|
|
||||||
size++;
|
|
||||||
n.uplink = null;
|
|
||||||
next = this.root;
|
|
||||||
this.root = n;
|
|
||||||
if (next == null){
|
|
||||||
n.leftlink = null;
|
|
||||||
n.rightlink = null;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
mainblock: {
|
|
||||||
ntime = n.time;
|
|
||||||
left = n;
|
|
||||||
right = n;
|
|
||||||
if (next.time > ntime){
|
|
||||||
//2222222222222222222222222
|
|
||||||
do{
|
|
||||||
temp = next.leftlink;
|
|
||||||
if (temp == null){
|
|
||||||
right.leftlink = next;
|
|
||||||
next.uplink = right;
|
|
||||||
left.rightlink = null;
|
|
||||||
break mainblock;
|
|
||||||
}
|
|
||||||
if (temp.time <= ntime){
|
|
||||||
right.leftlink = next;
|
|
||||||
next.uplink = right;
|
|
||||||
right = next;
|
|
||||||
next = temp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
next.leftlink = temp.rightlink;
|
|
||||||
if (temp.rightlink != null)
|
|
||||||
temp.rightlink.uplink = next;
|
|
||||||
right.leftlink = temp;
|
|
||||||
temp.uplink = right;
|
|
||||||
temp.rightlink = next;
|
|
||||||
next.uplink = temp;
|
|
||||||
right = temp;
|
|
||||||
next = temp.leftlink;
|
|
||||||
if (next == null){
|
|
||||||
left.rightlink = null;
|
|
||||||
break mainblock;
|
|
||||||
}
|
|
||||||
}while (next.time > ntime);
|
|
||||||
}
|
|
||||||
forblock:
|
|
||||||
for( ; ; ){
|
|
||||||
//111111111111111111111111111
|
|
||||||
do{
|
|
||||||
temp = next.rightlink;
|
|
||||||
if (temp == null){
|
|
||||||
left.rightlink = next;
|
|
||||||
next.uplink = left;
|
|
||||||
right.leftlink = null;
|
|
||||||
break forblock;
|
|
||||||
}
|
|
||||||
if (temp.time > ntime){
|
|
||||||
left.rightlink = next;
|
|
||||||
next.uplink = left;
|
|
||||||
left = next;
|
|
||||||
next = temp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
next.rightlink = temp.leftlink;
|
|
||||||
if (temp.leftlink!=null)
|
|
||||||
temp.leftlink.uplink = next;
|
|
||||||
left.rightlink = temp;
|
|
||||||
temp.uplink = left;
|
|
||||||
temp.leftlink = next;
|
|
||||||
next.uplink = temp;
|
|
||||||
left = temp;
|
|
||||||
next = temp.rightlink;
|
|
||||||
if (next == null){
|
|
||||||
right.leftlink = null;
|
|
||||||
break forblock;
|
|
||||||
}
|
|
||||||
}while (next.time <= ntime);
|
|
||||||
|
|
||||||
//2222222222222222222222222222
|
|
||||||
do{
|
|
||||||
temp = next.leftlink;
|
|
||||||
if (temp == null){
|
|
||||||
right.leftlink = next;
|
|
||||||
next.uplink = right;
|
|
||||||
left.rightlink = null;
|
|
||||||
break forblock;
|
|
||||||
}
|
|
||||||
if (temp.time <= ntime){
|
|
||||||
right.leftlink = next;
|
|
||||||
next.uplink = right;
|
|
||||||
right = next;
|
|
||||||
next = temp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
next.leftlink = temp.rightlink;
|
|
||||||
if (temp.rightlink != null)
|
|
||||||
temp.rightlink.uplink = next;
|
|
||||||
right.leftlink = temp;
|
|
||||||
temp.uplink = right;
|
|
||||||
temp.rightlink = next;
|
|
||||||
next.uplink = temp;
|
|
||||||
right = temp;
|
|
||||||
next = temp.leftlink;
|
|
||||||
if (next == null){
|
|
||||||
left.rightlink = null;
|
|
||||||
break forblock;
|
|
||||||
}
|
|
||||||
}while (next.time > ntime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//99999999999999999999999999999
|
|
||||||
temp = n.leftlink;
|
|
||||||
n.leftlink = n.rightlink;
|
|
||||||
n.rightlink = temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public Event getMin(){
|
|
||||||
|
|
||||||
//assumed that the tree is not empty
|
|
||||||
next = this.root;
|
|
||||||
left = next.leftlink;
|
|
||||||
if (left ==null){
|
|
||||||
update_code = true;
|
|
||||||
return next;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
for ( ; ; ){
|
|
||||||
farleft = left.leftlink;
|
|
||||||
if (farleft == null){
|
|
||||||
update_code = false;
|
|
||||||
update_p = next;
|
|
||||||
return left;
|
|
||||||
}
|
|
||||||
farfarleft = farleft.leftlink;
|
|
||||||
if (farfarleft==null){
|
|
||||||
update_code = false;
|
|
||||||
update_p = left;
|
|
||||||
return farleft;
|
|
||||||
}
|
|
||||||
next.leftlink = farleft;
|
|
||||||
farleft.uplink = next;
|
|
||||||
left.leftlink = farleft.rightlink;
|
|
||||||
if (farleft.rightlink!=null)
|
|
||||||
farleft.rightlink.uplink = left;
|
|
||||||
farleft.rightlink = left;
|
|
||||||
left.uplink = farleft;
|
|
||||||
next = farleft;
|
|
||||||
left = farfarleft;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dequeue(){
|
|
||||||
size--;
|
|
||||||
//assumed that getMin has been the last splay tree operation invoked. Removes that element.
|
|
||||||
if (update_code){
|
|
||||||
next = null; //remove pointer to the returned Event
|
|
||||||
root = root.rightlink;
|
|
||||||
if (root!=null)
|
|
||||||
root.uplink = null;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
left = farleft = null; //remove pointers to the returned event
|
|
||||||
if (update_p.leftlink.rightlink!=null)
|
|
||||||
update_p.leftlink.rightlink.uplink = update_p;
|
|
||||||
update_p.leftlink = update_p.leftlink.rightlink;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,253 +0,0 @@
|
|||||||
package net.berack.upo.valpre.bcnn.simutil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
|
|
||||||
This class provides a fairly efficient implementation of a FIFO
|
|
||||||
queue. We use an array to implement the queue which is
|
|
||||||
automatically increased in size when necessary. Note that the queue
|
|
||||||
is never shrunk in the current implementation.
|
|
||||||
|
|
||||||
@author Mark Astley
|
|
||||||
@version $Revision: 1.5 $ ($Date: 1998/09/07 23:00:37 $)
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
// public class Queue implements Cloneable, Serializable {
|
|
||||||
public class Queue {
|
|
||||||
/**
|
|
||||||
This constant sets the initial size of a queue when the default
|
|
||||||
constructor is invoked to create a queue. Users requiring a
|
|
||||||
different initial size may invoke the appropriate constructor
|
|
||||||
below.
|
|
||||||
*/
|
|
||||||
public static final int INITIAL_SIZE = 10;
|
|
||||||
|
|
||||||
/**
|
|
||||||
This array holds the queue. We use a dynamically growing circular
|
|
||||||
array to represent the queue. Queue size is doubled when
|
|
||||||
necessary which should make for a rather efficient implementation.
|
|
||||||
*/
|
|
||||||
Object[] theQ;
|
|
||||||
|
|
||||||
/**
|
|
||||||
These two fields hold indices to the first and last element of the
|
|
||||||
queue respectively. Technically, <em>back</em> points to the
|
|
||||||
first open spot in the queue rather than the last element.
|
|
||||||
*/
|
|
||||||
int front;
|
|
||||||
int back;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Default constructor for the <em>Queue</em> class.
|
|
||||||
*/
|
|
||||||
public Queue() {
|
|
||||||
theQ = new Object[INITIAL_SIZE];
|
|
||||||
front=back=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Alternative constructor for the <em>Queue</em> class which allows
|
|
||||||
the specification of the initial size of the queue.
|
|
||||||
|
|
||||||
@param <b>initialSize</b> The initial size of the new <em>Queue</em>.
|
|
||||||
*/
|
|
||||||
public Queue(int initialSize) {
|
|
||||||
theQ = new Object[initialSize];
|
|
||||||
front=back=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
This private method is used to double the size of the queue when
|
|
||||||
more space is required (as a result of calling enqueue). Note
|
|
||||||
that because the implementation is in terms of a circular array,
|
|
||||||
we have to be careful when copying elements from the old array to
|
|
||||||
the new array.
|
|
||||||
*/
|
|
||||||
synchronized private void grow() {
|
|
||||||
Object[] newQ = new Object[2 * theQ.length];
|
|
||||||
|
|
||||||
if (back >= front)
|
|
||||||
System.arraycopy(theQ, front, newQ, front, back - front + 1);
|
|
||||||
else {
|
|
||||||
System.arraycopy(theQ, front, newQ, front, theQ.length - front);
|
|
||||||
System.arraycopy(theQ, 0, newQ, theQ.length, back);
|
|
||||||
back = front + theQ.length - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
theQ = newQ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Determine if the queue is empty.
|
|
||||||
|
|
||||||
@return <b>true</b> if the queue contains no elements,
|
|
||||||
<b>false</b> otherwise.
|
|
||||||
*/
|
|
||||||
synchronized public boolean empty() {
|
|
||||||
return (front == back);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Add an object to the end of the queue.
|
|
||||||
|
|
||||||
@param <b>q</b> A reference to the object to add.
|
|
||||||
@return <b>void</b>
|
|
||||||
*/
|
|
||||||
synchronized public void enqueue(Object q) {
|
|
||||||
if (((back + 1) % theQ.length) == front)
|
|
||||||
grow();
|
|
||||||
|
|
||||||
theQ[back] = q;
|
|
||||||
back = (back + 1) % theQ.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Remove an object from the front of the queue. The returned object
|
|
||||||
is removed from the queue.
|
|
||||||
|
|
||||||
@return A reference to the <b>Object</b> at the front of the
|
|
||||||
queue. Returns <em>null</em> if the queue is empty.
|
|
||||||
*/
|
|
||||||
synchronized public Object dequeue() {
|
|
||||||
Object toReturn = null;
|
|
||||||
|
|
||||||
if (!empty()) {
|
|
||||||
toReturn = theQ[front];
|
|
||||||
front = (front + 1) % theQ.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
return toReturn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the object at the front of the queue without removing it.
|
|
||||||
|
|
||||||
@return A reference to the <b>Object</b> at the front of the
|
|
||||||
queue.
|
|
||||||
*/
|
|
||||||
synchronized public Object peekFront() {
|
|
||||||
if (!empty())
|
|
||||||
return theQ[front];
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Determine how many objects are currently stored in the queue.
|
|
||||||
|
|
||||||
@return An <b>int</b> indicating the number of objects in the
|
|
||||||
queue.
|
|
||||||
*/
|
|
||||||
synchronized public int numElements() {
|
|
||||||
if (front <= back)
|
|
||||||
return (back - front);
|
|
||||||
else
|
|
||||||
return (back + (theQ.length - front));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
This function allows arbitrary queue elements to be removed.
|
|
||||||
Elements which are equal (according to the <em>equal</em>
|
|
||||||
function) to the argument are removed from the queue. Note that
|
|
||||||
this version of the function only removes the FIRST element
|
|
||||||
found. Use the <em>removeAll</em> function to remove ALL elements
|
|
||||||
equal to the argument.
|
|
||||||
|
|
||||||
@param <b>rem</b> The object to be removed from the queue.
|
|
||||||
@return <b>true</b> if an element was removed, <b>false</b>
|
|
||||||
otherwise.
|
|
||||||
*/
|
|
||||||
synchronized public boolean remove(Object rem) {
|
|
||||||
int i, x, y;
|
|
||||||
|
|
||||||
// PRAGMA [debug,osl.util.Queue] Log.println("<Queue.remove> Searching for element: " + rem);
|
|
||||||
// First track down the element to remove (if there is one)
|
|
||||||
for(i=front; i != back; i = (i + 1) % theQ.length)
|
|
||||||
if (rem.equals(theQ[i]))
|
|
||||||
break;
|
|
||||||
|
|
||||||
// If nothing found then return false...
|
|
||||||
if (i == back)
|
|
||||||
// PRAGMA [debug,osl.util.Queue] {
|
|
||||||
// PRAGMA [debug,osl.util.Queue] Log.println("<Queue.remove> Element not found, returning");
|
|
||||||
return false;
|
|
||||||
// PRAGMA [debug,osl.util.Queue] } else {
|
|
||||||
// PRAGMA [debug,osl.util.Queue] Log.println("<Queue.remove> Element found at position: " + i);
|
|
||||||
// PRAGMA [debug,osl.util.Queue] }
|
|
||||||
|
|
||||||
// Otherwise remove the one element. This is a bit of a hack but
|
|
||||||
// should be fairly efficient.
|
|
||||||
Object[] newQ = new Object[theQ.length];
|
|
||||||
for(x=front, y=0; x != back; x = (x + 1) % theQ.length)
|
|
||||||
if (x != i) {
|
|
||||||
newQ[y] = theQ[x];
|
|
||||||
y++;
|
|
||||||
}
|
|
||||||
|
|
||||||
theQ = newQ;
|
|
||||||
front = 0;
|
|
||||||
back = y;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
This function has the same behavior as <em>remove</em> except that
|
|
||||||
ALL matching elements are removed from the queue.
|
|
||||||
|
|
||||||
@param <b>rem</b> The object to be removed from the queue.
|
|
||||||
@return The number of elements removed.
|
|
||||||
*/
|
|
||||||
synchronized public int removeAll(Object rem) {
|
|
||||||
int i, match, x, y, z;
|
|
||||||
|
|
||||||
// Track down all the elements to remove.
|
|
||||||
int[] toRemove = new int[numElements()];
|
|
||||||
for(i=front, match=0; i != back; i = (i + 1) % theQ.length)
|
|
||||||
if (rem.equals(theQ[i])) {
|
|
||||||
toRemove[match] = i;
|
|
||||||
match++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// See if anything matched, if not then just return
|
|
||||||
if (match == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Now make a new array with all the matching elements removed
|
|
||||||
Object[] newQ = new Object[theQ.length];
|
|
||||||
for(x=front, y=0, z=0; x != back; x = (x + 1) % theQ.length)
|
|
||||||
if (z < match)
|
|
||||||
if (x != toRemove[z]) {
|
|
||||||
newQ[y] = theQ[x];
|
|
||||||
y++;
|
|
||||||
} else
|
|
||||||
z++;
|
|
||||||
else {
|
|
||||||
newQ[y] = theQ[x];
|
|
||||||
y++;
|
|
||||||
}
|
|
||||||
|
|
||||||
theQ = newQ;
|
|
||||||
front = 0;
|
|
||||||
back = y;
|
|
||||||
|
|
||||||
// match holds the number of things we removed
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
The canonical toString method.
|
|
||||||
*/
|
|
||||||
synchronized public String toString() {
|
|
||||||
String returnVal = "Queue: ";
|
|
||||||
|
|
||||||
if (empty())
|
|
||||||
return returnVal + "no elements";
|
|
||||||
|
|
||||||
for(int i=front; i != back; i = (i + 1) % theQ.length)
|
|
||||||
returnVal = returnVal + theQ[i].toString() + " ";
|
|
||||||
|
|
||||||
return returnVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user