Package jmt.engine.NodeSections

Source Code of jmt.engine.NodeSections.Server

/**   
  * Copyright (C) 2009, Laboratorio di Valutazione delle Prestazioni - Politecnico di Milano

  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.

  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.

  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */

package jmt.engine.NodeSections;

import jmt.common.exception.NetException;
import jmt.engine.NetStrategies.ServiceStrategy;
import jmt.engine.QueueNet.Job;
import jmt.engine.QueueNet.JobClass;
import jmt.engine.QueueNet.NetEvent;
import jmt.engine.QueueNet.NetMessage;
import jmt.engine.QueueNet.NetNode;
import jmt.engine.QueueNet.NetSystem;
import jmt.engine.QueueNet.NodeSection;

/**
* This class implements a multi-class, single/multi server service.
* Every class has a specific distribution and a own set of statistical
* parameters.
* A server service remains busy while processing one or more jobs.
* @author  Francesco Radaelli, Stefano Omini, Bertoli Marco
*/
public class Server extends ServiceSection {

  public static final boolean DEBUG = false;

  /** Property Identifier:  Busy counter. */
  public static final int PROPERTY_ID_BUSY_COUNTER = 0x0101;
  /** Property Identifier:  Max jobs (number of servers). */
  public static final int PROPERTY_ID_MAX_JOBS = 0x0102;
  /** Property Identifier:  Visits per class. */
  public static final int PROPERTY_ID_VISITS_PER_CLASS = 0x0103;
  /** Property Identifier:  Service strategy. */
  public static final int PROPERTY_ID_SERVICE_STRATEGY = 0x0104;

  //TODO: use this to correct residence times (R=r*v) or remove them!!
  private int numberOfVisitsPerClass[];

  private int busyCounter, numberOfServers;

  private ServiceStrategy serviceStrategy[];

  /** Creates a new instance of Server.
   * @param numberOfVisitsPerClass Number of job visits per class: if null
   * the server will be single visit.
   * @param serverNumber Number of jobs which can be served simultaneously.
   * @param serviceStrategy Array of service strategies, one per class.
   * @throws jmt.common.exception.NetException
   */
  public Server(Integer serverNumber, Integer numberOfVisitsPerClass[], ServiceStrategy serviceStrategy[]) throws jmt.common.exception.NetException {
    //numberOfVisitsPerClass is null
    if (numberOfVisitsPerClass == null) {
      this.serviceStrategy = serviceStrategy;
      this.numberOfVisitsPerClass = null;
      busyCounter = 0;
      this.numberOfServers = serverNumber.intValue();
    } else {
      //else creates an array of int & then use the same cosntructor
      int[] nVisits = new int[numberOfVisitsPerClass.length];
      for (int i = 0; i < numberOfVisitsPerClass.length; i++) {
        nVisits[i] = numberOfVisitsPerClass[i].intValue();

      }
      this.serviceStrategy = serviceStrategy;
      this.numberOfVisitsPerClass = nVisits;
      busyCounter = 0;
      this.numberOfServers = serverNumber.intValue();
    }

  }

  /** Creates a new instance of Server.
   * @param serverNumber Number of jobs which can be served simultaneously.
   * @param numberOfVisitsPerClass Number of job visits per class: if null
   * the server will be single visit.
   * @param serviceStrategy Array of service strategies, one per class.
   * @throws jmt.common.exception.NetException
   */
  public Server(int serverNumber, int numberOfVisitsPerClass[], ServiceStrategy serviceStrategy[]) throws jmt.common.exception.NetException {
    this.serviceStrategy = serviceStrategy;
    this.numberOfVisitsPerClass = numberOfVisitsPerClass;
    busyCounter = 0;
    this.numberOfServers = serverNumber;

  }

  @Override
  public int getIntSectionProperty(int id) throws jmt.common.exception.NetException {
    switch (id) {
      case PROPERTY_ID_BUSY_COUNTER:
        return busyCounter;
      case PROPERTY_ID_MAX_JOBS:
        return numberOfServers;
      default:
        return super.getIntSectionProperty(id);
    }
  }

  @Override
  public int getIntSectionProperty(int id, JobClass jobClass) throws jmt.common.exception.NetException {
    switch (id) {
      case PROPERTY_ID_VISITS_PER_CLASS:
        return numberOfVisitsPerClass[jobClass.getId()];
      default:
        return super.getIntSectionProperty(id, jobClass);
    }
  }

  /* (non-Javadoc)
   * @see jmt.engine.QueueNet.NodeSection#getDoubleSectionProperty(int, jmt.engine.QueueNet.JobClass)
   */
  @Override
  public double getDoubleSectionProperty(int id, JobClass jobClass) throws NetException {
    if (id == PROPERTY_ID_UTILIZATION) {
      double divisor = numberOfServers;
      return jobsList.getBusyTimePerClass(jobClass) / NetSystem.getTime() / divisor;
    } else {
      return super.getDoubleSectionProperty(id, jobClass);
    }
  }

  /* (non-Javadoc)
   * @see jmt.engine.QueueNet.NodeSection#getDoubleSectionProperty(int)
   */
  @Override
  public double getDoubleSectionProperty(int id) throws NetException {
    if (id == PROPERTY_ID_UTILIZATION) {
      double divisor = numberOfServers;
      return jobsList.getBusyTime() / NetSystem.getTime() / divisor;
    } else {
      return super.getDoubleSectionProperty(id);
    }
  }

  @Override
  public Object getObject(int id, JobClass jobClass) throws jmt.common.exception.NetException {
    switch (id) {
      case PROPERTY_ID_SERVICE_STRATEGY:
        return serviceStrategy[jobClass.getId()];
      default:
        return super.getObject(id);
    }
  }

  @Override
  public Object getObject(int id) throws jmt.common.exception.NetException {
    switch (id) {
      case PROPERTY_ID_SERVICE_STRATEGY:
        return serviceStrategy;
      default:
        return super.getObject(id);
    }
  }

  @Override
  protected void nodeLinked(NetNode node) {
    //if (numberOfVisitsPerClass != null)
    //  tempJobsList = new JobInfoList(getJobClasses().size(), true);
    jobsList.setServerNumber(numberOfServers);
  }

  @Override
  protected int process(NetMessage message) throws jmt.common.exception.NetException {
    int c;
    Job job;
    double serviceTime;
    switch (message.getEvent()) {

      case NetEvent.EVENT_ACK:
        //EVENT_ACK
        //If there are no jobs in the service section, message is not processed.
        //Otherwise an ack is sent backward to the input section and
        //the counter of jobs in service is decreased.
        if (busyCounter == 0) {
          //it wasn't waiting for any job
          return NodeSection.MSG_NOT_PROCESSED;
        } else if (busyCounter == numberOfServers) {
          // Sends a request to the input section
          sendBackward(NetEvent.EVENT_ACK, message.getJob(), 0.0);
          busyCounter--;
        } else {
          // Avoid ACK as we already sent ack
          busyCounter--;
        }
        break;

      case NetEvent.EVENT_JOB:

        //EVENT_JOB
        //If the message has been sent by the server itself,
        // then the job is forwarded.
        //
        //If the message has been sent by another section, the server, if
        //is not completely busy, sends to itself a message containing the
        //job and with delay equal to the service time calculated using
        //the service strategy.
        //The counter of jobs in service is increased and, if further service
        //capacity is left, an ack is sent to the input section.

        // Gets the job from the message
        job = message.getJob();

        if (isMine(message)) {
          // this job has been just served (the message has been sent by the server itself)
          // forwards the job to the output section
          sendForward(job, 0.0);
        } else {
          //message received from another node section: if the server is not completely busy,
          //it sends itself a message with this job
          if (busyCounter < numberOfServers) {
            // Gets the class of the job
            c = job.getJobClass().getId();
            // Auto-sends the job with delay equal to "serviceTime"
            serviceTime = serviceStrategy[c].wait(this);
            // Calculates the service time of job
            sendMe(job, serviceTime);

            busyCounter++;
            if (busyCounter < numberOfServers) {
              // Sends an ACK to the input section (remember not to propagate
              // this ack again when computation is finished)
              sendBackward(NetEvent.EVENT_ACK, message.getJob(), 0.0);
            }
          } else {
            //server is busy
            return NodeSection.MSG_NOT_PROCESSED;
          }
        }
        break;

      default:
        return MSG_NOT_PROCESSED;
    }
    return MSG_PROCESSED;
  }

}
TOP

Related Classes of jmt.engine.NodeSections.Server

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.