Design Introduction

The program we are asking you to write is almost identical to that 
which is described in the handout.  However, we are asking that an 
object-oriented version be written in C++ using a stack (LIFO) instead 
of a queue (FIFO) to hold jobs.

The attached Object Specification documents take precedence over the 
information provided in the copied textbook pages.  If there is any 
question about the design of the program, please ask for clarification.  
There is no penalty for asking, there is for an incorrect design.

All the objects can be written using static arrays.  This is not a 
requirement, but simply an indication that it can be done.  Please 
indicate the limits of your designs when delivering.  It may be a good 
idea to base your array sizes on the simulation program constants.


ServerList Object Specification

Structure:
The ServerList will contain an array-based list of servers, each of 
which has a timer associated with it.  The array index can serve as 
the server ID where needed.

Operations:

InitServers( NumServers )
Function:
Initializes ServerList object to contain NumServers elements, each with 
a "free" status (i.e. each timer = 0).

Input:
NumServers (int)

Preconditions:
1 <= NumServers <= maximum number of servers allowed

Output:
(none)

Postconditions:
The ServerList object is initialized with NumServers servers, all free to 
engage.


anyFree()
Function:
Returns one if there are any servers free, otherwise zero.

Input:
(none)

Preconditions:
(none)

Output:
return value (int)

Postconditions:
This is an accessor function, the object is not changed


EngageServer( TransactTime )
Function:
Engages a free server for time TransactTime

Input:
TransactTime (int)

Preconditions:
TransactTime > 0, a server is free

Output:
(none)

Postconditions:
A server is engaged


UpdateServers()
Function:
Decrements the timer of each engaged server.

Input:
(none)

Preconditions:
(none)

Output:
(none)

Postconditions:
The timer of each engaged server is decremented


Starting Jobs

The StartJob function in the original design obtains a ServerID from 
the ServerList.  The object-oriented design presented here does not 
require this intermediate step.  The psuedocode for the object version 
is as follows:

If Servers.anyFree() and not Stack.isEmpty() then
	Increment NumJobs
	TotalWait := TotalWait + Stack.Pop()
	Servers.EngageServer( TransactTime )


Stack (LIFO) Object Specification

Structure:
The Stack object is a generic stack designed to hold integers.  A static i
nt array can be used along with a top-of-stack (TOS) index value.

Operations:
Push( Data )
Function:
Pushes the Data value onto the stack.

Input:
Data (int)

Preconditions:
There is space available in the stack array

Output:
(none)

Postconditions:
TOS index is changed, the data value is on the top of the stack


Pop()
Function:
Returns and removes the value on the top of the stack.

Input:
(none)

Preconditions:
The stack is not empty

Output:
return value (int)

Postconditions:
TOS index is changed


isEmpty()
Function:
Returns one if the the stack is empty

Input:
(none)

Preconditions:
(none)

Output:
return value (int)

Postconditions:
This is an accessor function, the Stack object is not changed


Updating the Stack

The UpdateQueue function in the original design document dequeued, 
incremented, and requireed each job.  This operation is not possible 
using the LIFO Stack.  For the stack, the psuedocode for the equivalent 
operation is:

Instantiate an additional stack, STACK2
While not STACK1.isEmpty() do
	STACK2.Push( STACK1.Pop() )
While not STACK2.isEmpty() do
	STACK1.Push( STACK2.Pop() + 1 )


This algorithm should be a separate function that accepts the simulation 
stack (STACK1 in the psuedocode) as a parameter and creates STACK2 as a 
local variable.  As you can see, this algorithm unloads one stack into 
the other and then reloads the original stack with the same values, each 
incremented by one.