public abstract class AbstractNonPreemptiveWorkConservingSimQueue<J extends SimJob,Q extends AbstractNonPreemptiveWorkConservingSimQueue> extends AbstractClassicSimQueue<J,Q> implements SimQueue<J,Q>
The work model for this class is that of a waiting area of possibly limited size and a service area that consists of a fixed (but possibly infinite) number of servers of equal capacity and "inter-changeable" to visiting jobs (i.e., jobs do not care by which server they are served). Arriving jobs that need to wait but find the waiting area full are dropped by default; however, sub-classes may override this and select another job from the waiting area to be dropped. Each server can only serve at most one job at a time. Once taken into service on one of the servers, jobs are served by that server until completion (unless they are revoked from service), after which they depart from the system.
In addition, implementations of this class are always work-conserving, which in this context is interpreted as follows:
Note that the potential lack of server-access credits inhibits any implementation of SimQueue to
be truly work-conserving.
The requirement of work-conservation should therefore be annotated with "given sufficient server-access credits".
Implementations allow (through inheritance) the job requested service time to be (positive) infinite. Jobs with that feature will never depart (through internal scheduling), even if time itself is positive or negative infinity. If time is infinite, jobs with finite service time requirement will always start and depart immediately upon arrival.
Despite the constraints and conditions outlined above, many classical non-preemptive queueing systems
like FCFS, FCFS_B_c, SJF and IS are in fact work-conserving.
Implementations only need worry about:
resetEntitySubClass().
insertJobInQueueUponArrival(J, double).
selectJobToDropAtFullQueue(J, double) in order to impose a non-default drop policy.
selectJobToStart()
(the moments to start jobs are entirely managed by this class).
AbstractSimQueue.getServiceTimeForJob(J).
removeJobFromQueueUponExit(J, double).
SimQoS.getQoS() and SimQoS.getQoSClass()
and advertising the appropriate SimQueueQoS generic-type structure.
Copyright (C) 2005-2017 Jan de Jongh, TNO
This file is covered by the LICENSE file in the root of this project.
AbstractSimEntity.Notifier, AbstractSimEntity.PreNotificationHookSimQueue.AutoRevocationPolicySimEntity.Action, SimEntity.UnknownNotificationTypePolicy, SimEntity.UnknownOperationPolicyeventsScheduled, SANITYUSE_ARRAY_OPTIMIZATION| Modifier | Constructor and Description |
|---|---|
protected |
AbstractNonPreemptiveWorkConservingSimQueue(org.javades.jsimulation.r5.SimEventList eventList,
int bufferSize,
int numberOfServers)
Creates a non-preemptive work-conserving queue given an event list, buffer size and number of servers.
|
| Modifier and Type | Method and Description |
|---|---|
boolean |
hasServerAvailable()
Returns true if there are strictly fewer jobs in the service area than servers present in the system,
or if the number of servers is infinite.
|
protected void |
insertJobInQueueUponArrival(J job,
double time)
The default implementation does nothing.
|
protected void |
insertJobInQueueUponStart(J job,
double time)
Does nothing.
|
boolean |
isStartArmed()
Returns whether a server is available.
|
protected void |
queueAccessVacationDropSubClass(double time,
J job)
Calls super method (in order to make implementation final).
|
protected void |
removeJobFromQueueUponDeparture(J departingJob,
double time)
Removes the job from the system and cancels its departure event (if present).
|
protected void |
removeJobFromQueueUponDrop(J job,
double time)
|
protected void |
removeJobFromQueueUponExit(J exitingJob,
double time)
Removes a job that ends its visit (in whatever way) from the internal administration.
|
protected void |
removeJobFromQueueUponRevokation(J job,
double time,
boolean auto)
|
protected void |
reschedule(double time)
Central rescheduling method.
|
protected void |
rescheduleAfterArrival(J job,
double time)
Drops a job from the waiting area if it has overflown; otherwise reschedules.
|
protected void |
rescheduleAfterDeparture(J departedJob,
double time)
Invokes
reschedule(double) passing the time argument. |
protected void |
rescheduleAfterDrop(J job,
double time)
Invokes
reschedule(double) passing the time argument. |
protected void |
rescheduleAfterRevokation(J job,
double time,
boolean auto)
Invokes
reschedule(double) passing the time argument. |
protected void |
rescheduleAfterStart(J job,
double time)
Depending on the job's requested service time, makes it depart immediately, schedules a suitable departure event,
or does nothing if the job requires infinite service time.
|
protected void |
rescheduleForNewServerAccessCredits(double time)
Invokes
reschedule(double) passing the time argument. |
protected void |
resetEntitySubClass()
Invokes super-method and revokes a pending job drop.
|
protected J |
selectJobToDropAtFullQueue(J arrivingJob,
double time)
Selects the job to drop from the waiting area that in case it "overflows".
|
protected abstract J |
selectJobToStart()
Selects which job in the waiting area to start next.
|
protected void |
setServerAccessCreditsSubClass()
Calls super method (in order to make implementation final).
|
getBufferSize, getNumberOfServersarrive, autoRevoke, cancelDepartureEvent, cancelDepartureEvent, depart, departureFromEventList, drop, getAutoRevocationPolicy, getDepartureEvents, getDepartureEvents, getFirstJob, getFirstJobInServiceArea, getFirstJobInWaitingArea, getJobs, getJobsInServiceArea, getJobsInWaitingArea, getNumberOfJobs, getNumberOfJobsInServiceArea, getNumberOfJobsInWaitingArea, getServerAccessCredits, getServiceTimeForJob, hasJobs, hasJobsInServiceArea, hasJobsInWaitingArea, hasServerAcccessCredits, isJob, isJobInServiceArea, isJobInWaitingArea, isQueueAccessVacation, registerStdOutSimQueueListener, revoke, revoke, scheduleDepartureEvent, scheduleJobArrival, setAutoRevocationPolicy, setQueueAccessVacation, setServerAccessCredits, start, takeServerAccessCredit, toStringDefault, triggerPotentialNewStartArmed, unregisterStdOutSimQueueListeneraddPendingNotification, addPendingNotification, clearAndUnlockPendingNotificationsIfLocked, delegateOperation, doAfterNotifications, doOperation, fireAndLockPendingNotifications, getEventList, getLastUpdateTime, getRegisteredDelegatedOperations, getRegisteredNotificationTypes, getRegisteredOperations, getSimEntityListeners, getUnknownNotificationTypePolicy, getUnknownOperationPolicy, isIgnoreEventListReset, notifyEventListReset, registerDelegatedOperation, registerNotificationType, registerOperation, registerPreEventHook, registerPreNotificationHook, registerPreUpdateHook, registerSimEntityListener, registerStdOutSimEntityListener, removeDelegationForOperation, resetEntity, setIgnoreEventListReset, setName, setUnknownNotificationTypePolicy, setUnknownOperationPolicy, toString, unregisterSimEntityListener, unregisterStdOutSimEntityListener, updateclone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitarrive, getAutoRevocationPolicy, getCopySimQueue, getJobs, getJobsInServiceArea, getJobsInWaitingArea, getNumberOfJobs, getNumberOfJobsInServiceArea, getNumberOfJobsInWaitingArea, getServerAccessCredits, isJob, isJobInServiceArea, isJobInWaitingArea, isQueueAccessVacation, revoke, revoke, setAutoRevocationPolicy, setQueueAccessVacation, setServerAccessCreditsdoAfterNotifications, doOperation, getEventList, getLastUpdateTime, getRegisteredNotificationTypes, getRegisteredOperations, getSimEntityListeners, getUnknownNotificationTypePolicy, getUnknownOperationPolicy, isIgnoreEventListReset, registerSimEntityListener, resetEntity, setIgnoreEventListReset, setName, setUnknownNotificationTypePolicy, setUnknownOperationPolicy, toStringDefault, unregisterSimEntityListener, updatenotifyEventListResetgetQoS, getQoSClassprotected AbstractNonPreemptiveWorkConservingSimQueue(org.javades.jsimulation.r5.SimEventList eventList,
int bufferSize,
int numberOfServers)
eventList - The event list to use.bufferSize - The buffer size (non-negative), Integer.MAX_VALUE is interpreted as infinity.numberOfServers - The number of servers (non-negative), Integer.MAX_VALUE is interpreted as infinity.protected void resetEntitySubClass()
resetEntitySubClass in class AbstractSimQueue<J extends SimJob,Q extends AbstractNonPreemptiveWorkConservingSimQueue>insertJobInQueueUponArrival(J, double)public final boolean hasServerAvailable()
AbstractClassicSimQueue.getNumberOfServers(),
AbstractSimQueue.getNumberOfJobsInServiceArea()protected void insertJobInQueueUponArrival(J job, double time)
insertJobInQueueUponArrival in class AbstractSimQueue<J extends SimJob,Q extends AbstractNonPreemptiveWorkConservingSimQueue>job - The job that arrived.time - The current time (i.e., arrival time of the job).AbstractSimQueue.arrive(double, J),
AbstractSimQueue.rescheduleAfterArrival(J, double)protected J selectJobToDropAtFullQueue(J arrivingJob, double time)
Implementations only have to select either the arriving job,
or a job from the waiting area to be dropped,
i.e., they should not alter the internal administration
and they should not reschedule.
Note that the arriving job is actually present in the waiting area,
see AbstractSimQueue.arrive(double, J).
The default implementation returns the arrivingJob argument;
which causes the arriving job to be dropped.
arrivingJob - The job that arrives, non-null.time - The job's arrival time.insertJobInQueueUponArrival(J, double)protected final void rescheduleAfterArrival(J job, double time)
The waiting area is "overflown" if it holds more (i.c., one) jobs than the buffer size
and a job cannot be taken into service immediately
in view of AbstractSimQueue.hasServerAcccessCredits() and isStartArmed().
If a job is to be dropped from the waiting area,
it is selected through selectJobToDropAtFullQueue(J, double).
rescheduleAfterArrival in class AbstractSimQueue<J extends SimJob,Q extends AbstractNonPreemptiveWorkConservingSimQueue>job - The job that arrived (and is already present in AbstractSimQueue.getJobs()).time - The current time (i.e., the arrival time of the job).insertJobInQueueUponArrival(J, double),
selectJobToDropAtFullQueue(J, double),
AbstractSimQueue.drop(J, double),
reschedule(double)protected final void queueAccessVacationDropSubClass(double time,
J job)
queueAccessVacationDropSubClass in class AbstractSimQueue<J extends SimJob,Q extends AbstractNonPreemptiveWorkConservingSimQueue>time - The time the job was dropped, i.e., the current time.job - The dropped job.AbstractSimQueue.arrive(double, J),
AbstractSimQueue.setQueueAccessVacation(double, boolean)protected final void removeJobFromQueueUponDrop(J job, double time)
removeJobFromQueueUponDrop in class AbstractSimQueue<J extends SimJob,Q extends AbstractNonPreemptiveWorkConservingSimQueue>job - The job that is to be dropped.time - The current time (i.e., drop time of the job).AbstractSimQueue.drop(J, double),
AbstractSimQueue.rescheduleAfterDrop(J, double)protected final void rescheduleAfterDrop(J job, double time)
reschedule(double) passing the time argument.rescheduleAfterDrop in class AbstractSimQueue<J extends SimJob,Q extends AbstractNonPreemptiveWorkConservingSimQueue>job - The jobs that was dropped.time - The current time (i.e., drop time of the job).AbstractSimQueue.drop(J, double),
AbstractSimQueue.removeJobFromQueueUponDrop(J, double)protected final void removeJobFromQueueUponRevokation(J job, double time, boolean auto)
removeJobFromQueueUponRevokation in class AbstractSimQueue<J extends SimJob,Q extends AbstractNonPreemptiveWorkConservingSimQueue>job - The job that is to be revoked.time - The current time (i.e., revocation time of the job).auto - Whether or not this applies to an auto-revocation.AbstractSimQueue.revoke(double, J, boolean),
AbstractSimQueue.autoRevoke(double, J),
AbstractSimQueue.rescheduleAfterRevokation(J, double, boolean),
SimQueue.AutoRevocationPolicyprotected final void rescheduleAfterRevokation(J job, double time, boolean auto)
reschedule(double) passing the time argument.rescheduleAfterRevokation in class AbstractSimQueue<J extends SimJob,Q extends AbstractNonPreemptiveWorkConservingSimQueue>job - The jobs that was successfully revoked.time - The current time (i.e., revocation time of the job).auto - Whether or not this applies to an auto-revocation.AbstractSimQueue.revoke(double, J, boolean),
AbstractSimQueue.autoRevoke(double, J),
AbstractSimQueue.removeJobFromQueueUponRevokation(J, double, boolean),
SimQueue.AutoRevocationPolicyprotected final void setServerAccessCreditsSubClass()
setServerAccessCreditsSubClass in class AbstractSimQueue<J extends SimJob,Q extends AbstractNonPreemptiveWorkConservingSimQueue>AbstractSimQueue.getServerAccessCredits(),
AbstractSimQueue.setServerAccessCredits(double, int),
AbstractSimQueue.rescheduleForNewServerAccessCredits(double)protected final void rescheduleForNewServerAccessCredits(double time)
reschedule(double) passing the time argument.rescheduleForNewServerAccessCredits in class AbstractSimQueue<J extends SimJob,Q extends AbstractNonPreemptiveWorkConservingSimQueue>time - The current time (i.e., the time at which new server-access credits became available).AbstractSimQueue.setServerAccessCredits(double, int),
AbstractSimQueue.hasServerAcccessCredits()public final boolean isStartArmed()
isStartArmed in interface SimQueue<J extends SimJob,Q extends AbstractNonPreemptiveWorkConservingSimQueue>hasServerAvailable().hasServerAvailable()protected abstract J selectJobToStart()
Implementations can assume that the waiting area is non-empty.
Moreover, they are free to chose whichever job from the waiting area to start,
irrespective of the structure implied by insertJobInQueueUponArrival(J, double).
null and must be present in the waiting area.insertJobInQueueUponArrival(J, double),
reschedule(double)protected final void insertJobInQueueUponStart(J job, double time)
insertJobInQueueUponStart in class AbstractSimQueue<J extends SimJob,Q extends AbstractNonPreemptiveWorkConservingSimQueue>job - The job that starts.time - The current time (i.e., start time of the job).AbstractSimQueue.start(double, J),
AbstractSimQueue.rescheduleAfterStart(J, double)protected final void rescheduleAfterStart(J job, double time)
Performs sanity checks on the fly (job present; job not yet started; requested service time zero or positive).
The time argument must match the result from AbstractSimEntity.getLastUpdateTime() (and is thus only present for sanity checking).
If a job has infinite requested service time, it will start but never depart, even if the start is scheduled at positive or negative infinity.
With zero requested service time, a job departs immediately. This is also the case if the start is at positive or negative infinity AND the job has finite requested service time.
In all other cases, a suitable departure event is scheduled through AbstractSimQueue.scheduleDepartureEvent(double, J).
Caveat: the specification above implies that NOT all jobs in the service area will have a departure event scheduled for them!
rescheduleAfterStart in class AbstractSimQueue<J extends SimJob,Q extends AbstractNonPreemptiveWorkConservingSimQueue>job - The job that started (and is already present in AbstractSimQueue.getJobsInServiceArea().time - The current time (i.e., the start time of the job).AbstractSimQueue.getServiceTimeForJob(J),
AbstractSimQueue.scheduleDepartureEvent(double, J),
AbstractSimQueue.depart(double, J)protected final void removeJobFromQueueUponDeparture(J departingJob, double time)
Checks the presence of the departing job through AbstractSimQueue.isJob(org.javades.jqueues.r5.entity.jq.job.SimJob) (jobs must be present),
cancels pending departure events for the job (if present),
and invokes removeJobFromQueueUponExit(J, double).
This method also serves as entry point for
removeJobFromQueueUponDrop(J, double) and
removeJobFromQueueUponRevokation(J, double, boolean).
removeJobFromQueueUponDeparture in class AbstractSimQueue<J extends SimJob,Q extends AbstractNonPreemptiveWorkConservingSimQueue>departingJob - The job that departs.time - The departure (current) time.IllegalStateException - If sanity checks fail.removeJobFromQueueUponExit(J, double)protected final void rescheduleAfterDeparture(J departedJob, double time)
reschedule(double) passing the time argument.rescheduleAfterDeparture in class AbstractSimQueue<J extends SimJob,Q extends AbstractNonPreemptiveWorkConservingSimQueue>departedJob - The departed job.time - The departure (current) time.AbstractSimQueue.depart(double, J),
AbstractSimQueue.removeJobFromQueueUponDeparture(J, double)protected void removeJobFromQueueUponExit(J exitingJob, double time)
The default implementation does nothing.
Implementations do not have to cancel (registered) departure events; this has been done by caller already.
exitingJob - The jobs that ends its visit, non-null.time - The current time, i.e., the time the job ends its visit.removeJobFromQueueUponDrop(J, double),
removeJobFromQueueUponRevokation(J, double, boolean),
removeJobFromQueueUponDeparture(J, double)protected final void reschedule(double time)
As long as there are service-access credits (AbstractSimQueue.hasServerAcccessCredits()),
start-able jobs (all waiting jobs)
and at least one server (hasServerAvailable()) available,
a single job is selected through (the sub-class specific) selectJobToStart()
and started through AbstractSimQueue.start(double, J).
time - The time of rescheduling.AbstractSimQueue.hasServerAcccessCredits(),
AbstractSimQueue.hasJobsInWaitingArea(),
hasServerAvailable(),
AbstractSimQueue.start(double, J),
selectJobToStart()Copyright © 2018. All rights reserved.