📄 queue.java
字号:
}
}
}
//----END REDIRECTION BEHAVIOUR-------//
//----ZERO SERVICE TIME BEHAVIOUR-----//
//at the first execution checks which classes have service time always equal to zero
if (hasZeroServiceTime == null) {
detectZeroServiceTimeStrategy();
}
//at this point we know which classes have service time always equal to zero
if (hasZeroServiceTime[job.getJobClass().getId()]) {
//this job class has service time equal to zero
//job must be first added, then immediately removed from the queue and forwarded,
//without waiting in queue
//adds the job
jobsList.add(new JobInfo(job));
//marks this job, so that the server can forward it, even if it's already busy
job.setTunnelThisJob(true);
//forwards the job
forward(job);
//sends an ack backward
send(NetEvent.EVENT_ACK, job, 0.0, message.getSourceSection(),
message.getSource());
return MSG_PROCESSED;
//WARNING: the "TunnelThisJob" property of the job will be resetted to false
//by the service section of this station
//(otherwise the following stations would continue tunnelling it)
}
//else the job must be managed in the usual way
//WARNING: note that the zero service time behaviour is managed before checking
//if the queue has a finite size. The assumption is that these jobs don't
//consume system resources.
//----end ZERO SERVICE TIME BEHAVIOUR-----//
//
//two possible cases:
//1 - the queue is a generic queue (redirectionOn == false)
//2 - the queue is a redirecting queue, but the message has arrived
//from the inside of the region or from the inputStation:
//in this case the redirecting queue acts as a normal queue
//
//therefore in both cases the behaviour is the same
//
// If coolStart is true, this is the first job received or the
// queue was empty: this job is sent immediately to the next
// section and coolStart set to false.
if (coolStart) {
// No jobs in queue: Refresh jobsList and sends job
// (don't use put strategy, because queue is empty)
jobsList.add(new JobInfo(job));
//forward without any delay
forward(jobsList.removeFirst().getJob());
//sends an ack backward
send(NetEvent.EVENT_ACK, job, 0.0,
message.getSourceSection(),
message.getSource());
coolStart = false;
} else {
if (!infinite) {
// ... if the queue is finite checks the size
// If the queue is not full adds the job and send ack
// <= size because the arrived job hasn't been inserted in Queue
// job list but has been inserted in NetNode job list !!
if (nodeJobsList.size() <= size) {
putStrategy[job.getJobClass().getId()]
.put(job, jobsList,
message.getSourceSection(),
message.getSource(),
this);
send(NetEvent.EVENT_ACK, job, 0.0,
message.getSourceSection(),
message.getSource());
}
// queue is full
else {
// if the job has been sent by the owner node of this queue section
if (isMyOwnerNode(message.getSource())) {
send(NetEvent.EVENT_ACK, job, 0.0,
message.getSourceSection(),
message.getSource());
waitingRequests.add(new WaitingRequest(
message.getSource(),
message.getSourceSection(),
job));
}
// otherwise if job has been sent by another node
else
// if drop is true reject the job, else add
// the job to waitingRequests
if (!drop[job.getJobClass().getId()]) {
waitingRequests.add(new WaitingRequest(message.getSource(),
message.getSourceSection(), job));
//if blocking is disabled, sends ack otherwise router of the previous node remains busy
if (!block[job.getJobClass().getId()]) {
send(NetEvent.EVENT_ACK, job, 0.0, message.getSourceSection(),
message.getSource());
}
} else {
// if drop, send ack event to source
droppedJobs++;
droppedJobsPerClass[job.getJobClass().getId()]++;
// Removes job from global jobInfoList - Bertoli Marco
getOwnerNode().getQueueNet().getJobInfoList().dropJob(job);
//after arriving to this section, the job has been inserted in the job
//lists of both node section and node.
//If drop = true, the job must be removed if the queue is full.
//Using the "general" send method, however, the dropped job wasn't removed
//from the job info list of node section and of node, then it was
//sent later, after receiving one or more ack.
//send(NetEvent.EVENT_ACK, job, 0.0, message.getSourceSection(),
// message.getSource());
sendAckAfterDrop(job, 0.0, message.getSourceSection(),
message.getSource());
//if the queue is inside a blocking region, the jobs
//counter must be decreased
if (isRedirectionON()) {
//decrease the number of jobs
myRegion.decreaseOccupation(job.getJobClass());
//sends an event to the input station (which may be blocked)
send(NetEvent.EVENT_JOB_OUT_OF_REGION, null, 0.0, NodeSection.INPUT, regionInputStation);
}
}
}
} else {
// else if the queue is infinite adds the job and sends ack
putStrategy[job.getJobClass().getId()]
.put(job, jobsList, message.getSourceSection(),
message.getSource(), this);
send(NetEvent.EVENT_ACK, job, 0.0,
message.getSourceSection(),
message.getSource());
}
}
break;
default:
return MSG_NOT_PROCESSED;
}
return MSG_PROCESSED;
}
private void forward(Job job) throws jmt.common.exception.NetException {
sendForward(job, 0.0);
}
/**
* Gets the total number of dropped jobs
* @return the total number of dropped jobs, -1 otherwise
*/
public int getDroppedJobs() {
if (!infinite) {
return droppedJobs;
} else {
return -1;
}
}
/**
* Gets the numbers of dropped jobs for each class
* @return the numbers of dropped jobs for each class, null otherwise
*/
public int[] getDroppedJobsPerClass() {
if (!infinite) {
return droppedJobsPerClass;
} else {
return null;
}
}
/**
* Gets the number of dropped jobs for the specified class
* @return the number of dropped jobs for the specified class, -1 otherwise
*/
public int getDroppedJobPerClass(int jobClass) {
if (!infinite) {
return droppedJobsPerClass[jobClass];
} else {
return -1;
}
}
/**
* This method detects, for each class, if the corresponding service strategy is
* a ZeroServiceTimeStrategy. If it's so, the job of this class will be tunnelled.
*/
private void detectZeroServiceTimeStrategy() {
int numberOfClasses = this.getJobClasses().size();
hasZeroServiceTime = new boolean[numberOfClasses];
try {
NodeSection serviceSect = this.getOwnerNode().getSection(NodeSection.SERVICE);
if (serviceSect instanceof ServiceTunnel) {
//case #1: service tunnel
//nothing to control, every job has already service time zero
//it's useless to force the tunnel behaviour
for (int c = 0; c < numberOfClasses; c++) {
hasZeroServiceTime[c] = false;
}
} else {
//case #2: server
//check if there are classes with zero service time distribution
if (serviceSect instanceof Server) {
for (int c = 0; c < this.getJobClasses().size(); c++) {
ServiceStrategy[] servStrat = (ServiceStrategy[]) ((Server) serviceSect).getObject(Server.PROPERTY_ID_SERVICE_STRATEGY);
hasZeroServiceTime[c] = servStrat[c] instanceof ZeroServiceTimeStrategy;
}
} else {
//case #3: serviceSect is nor a service tunnel neither a server
//use default behaviour
for (int c = 0; c < this.getJobClasses().size(); c++) {
hasZeroServiceTime[c] = false;
}
}
}
} catch(NetException ne) {
System.out.println("Error in detecting ZeroServiceTimeStrategy...");
}
}
/**
* Adds the specified numbers of jobs for each class
* @param preload_jobPerClass the numbers of jobs for each class
*/
public void preloadJobs(int[] preload_jobPerClass) {
//total jobs
int totJobs = 0;
//number of classes
int classNumber = preload_jobPerClass.length;
//jobs that haven't been inserted yet
int[] residualClassJobs = new int[classNumber];
//first of all computes the total number of jobs to be added
for (int c = 0; c < classNumber; c++) {
totJobs += preload_jobPerClass[c];
residualClassJobs[c] = preload_jobPerClass[c];
}
RandomEngine randomEng = RandomEngine.makeDefault();
int randomClassIndex;
JobClassList jobClasses = getJobClasses();
while (totJobs > 0) {
//jobs of different classes must be mixed.. use random numbers
randomClassIndex = (int) Math.floor((randomEng.raw())*classNumber);
if (residualClassJobs[randomClassIndex] > 0) {
//other jobs to be added
Job newJob = new Job(jobClasses.get(randomClassIndex));
jobsList.add(new JobInfo(newJob));
//job has been added: decrease class e total counters
residualClassJobs[randomClassIndex]--;
totJobs--;
// Signals to global jobInfoList new added job - Bertoli Marco
this.getOwnerNode().getQueueNet().getJobInfoList().addJob(newJob);
}
//else no other jobs of this class must be added
//continue
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -