Exemplo n.º 1
0
  /** Parse a DAX file with jdom */
  private void parseXmlFile(String path) {

    try {

      SAXBuilder builder = new SAXBuilder();
      // parse using builder to get DOM representation of the XML file
      Document dom = builder.build(new File(path));
      Element root = dom.getRootElement();
      List list = root.getChildren();
      for (Iterator it = list.iterator(); it.hasNext(); ) {
        Element node = (Element) it.next();
        if (node.getName().toLowerCase().equals("job")) {

          long length = 0;
          String nodeName = node.getAttributeValue("id");
          String nodeType = node.getAttributeValue("name");

          /**
           * capture runtime. If not exist, by default the runtime is 0.1. Otherwise CloudSim would
           * ignore this task. BUG/#11
           */
          double runtime = 0.1;
          if (node.getAttributeValue("runtime") != null) {
            String nodeTime = node.getAttributeValue("runtime");
            runtime = 1000 * Double.parseDouble(nodeTime);
            if (runtime < 100) {
              runtime = 100;
            }
            length = (long) runtime;
          } else {
            Log.printLine("Cannot find runtime for " + nodeName + ",set it to be 0");
          }
          // multiple the scale, by default it is 1.0
          length *= Parameters.getRuntimeScale();

          List fileList = node.getChildren();

          List mFileList = new ArrayList<org.cloudbus.cloudsim.File>();

          for (Iterator itf = fileList.iterator(); itf.hasNext(); ) {
            Element file = (Element) itf.next();
            if (file.getName().toLowerCase().equals("uses")) {
              String fileName = file.getAttributeValue("name"); // DAX version 3.3
              if (fileName == null) {
                fileName = file.getAttributeValue("file"); // DAX version 3.0
              }
              if (fileName == null) {
                Log.print("Error in parsing xml");
              }

              String inout = file.getAttributeValue("link");
              double size = 0.0;

              String fileSize = file.getAttributeValue("size");
              if (fileSize != null) {
                size = Double.parseDouble(fileSize) /*/ 1024*/;
              } else {
                Log.printLine("File Size not found for " + fileName);
              }

              /** a bug of cloudsim, size 0 causes a problem. 1 is ok. */
              if (size == 0) {
                size++;
              }
              /** Sets the file type 1 is input 2 is output */
              int type = 0;
              if (inout.equals("input")) {
                type = Parameters.FileType.INPUT.value;
              } else if (inout.equals("output")) {
                type = Parameters.FileType.OUTPUT.value;
              } else {
                Log.printLine("Parsing Error");
              }
              org.cloudbus.cloudsim.File tFile;
              /*
               * Already exists an input file (forget output file)
               */
              if (size < 0) {
                /*
                 * Assuming it is a parsing error
                 */
                size = 0 - size;
                Log.printLine("Size is negative, I assume it is a parser error");
              }
              if (type == Parameters.FileType.OUTPUT.value) {
                /** It is good that CloudSim does tell whether a size is zero */
                tFile = new org.cloudbus.cloudsim.File(fileName, (int) size);
              } else if (ReplicaCatalog.containsFile(fileName)) {
                tFile = ReplicaCatalog.getFile(fileName);
              } else {

                tFile = new org.cloudbus.cloudsim.File(fileName, (int) size);
                ReplicaCatalog.setFile(fileName, tFile);
              }

              tFile.setType(type);
              mFileList.add(tFile);
            }
          }
          Task task;
          // In case of multiple workflow submission. Make sure the jobIdStartsFrom is consistent.
          synchronized (this) {
            task = new Task(this.jobIdStartsFrom, length);
            this.jobIdStartsFrom++;
          }
          task.setType(nodeType);

          task.setUserId(userId);
          mName2Task.put(nodeName, task);

          for (Iterator itm = mFileList.iterator(); itm.hasNext(); ) {
            org.cloudbus.cloudsim.File file = (org.cloudbus.cloudsim.File) itm.next();
            task.addRequiredFile(file.getName());
          }

          task.setFileList(mFileList);
          this.getTaskList().add(task);

          /** Add dependencies info. */
        } else if (node.getName().toLowerCase().equals("child")) {
          List pList = node.getChildren();
          String childName = node.getAttributeValue("ref");
          if (mName2Task.containsKey(childName)) {

            Task childTask = (Task) mName2Task.get(childName);

            for (Iterator itc = pList.iterator(); itc.hasNext(); ) {
              Element parent = (Element) itc.next();
              String parentName = parent.getAttributeValue("ref");
              if (mName2Task.containsKey(parentName)) {
                Task parentTask = (Task) mName2Task.get(parentName);
                parentTask.addChild(childTask);
                childTask.addParent(parentTask);
              }
            }
          }
        }
      }
      /** If a task has no parent, then it is root task. */
      ArrayList roots = new ArrayList<Task>();
      for (Iterator it = mName2Task.values().iterator(); it.hasNext(); ) {
        Task task = (Task) it.next();
        task.setDepth(0);
        if (task.getParentList().isEmpty()) {
          roots.add(task);
        }
      }

      /** Add depth from top to bottom. */
      for (Iterator it = roots.iterator(); it.hasNext(); ) {
        Task task = (Task) it.next();
        setDepth(task, 1);
      }
      /** Clean them so as to save memory. Parsing workflow may take much memory */
      this.mName2Task.clear();

    } catch (JDOMException jde) {
      Log.printLine("JDOM Exception;Please make sure your dax file is valid");

    } catch (IOException ioe) {
      Log.printLine("IO Exception;Please make sure dax.path is correctly set in your config file");

    } catch (Exception e) {
      e.printStackTrace();
      Log.printLine("Parsing Exception");
    }
  }
  /** The main function */
  @Override
  public void run() {

    double[][] bandwidths = Parameters.getBandwidths();
    int vmNum = getVmList().size();
    int taskNum = getTaskList().size();
    double[] availableTime = new double[vmNum];
    // cloudlet id starts from 1
    double[][] earliestStartTime = new double[taskNum + 1][vmNum];
    double[][] earliestFinishTime = new double[taskNum + 1][vmNum];
    int[] allocation = new int[taskNum + 1];

    List<Task> taskList = new ArrayList<Task>(getTaskList());
    List<Task> readyList = new ArrayList<Task>();
    while (!taskList.isEmpty()) {
      readyList.clear();
      for (Task task : taskList) {
        boolean ready = true;
        for (Task parent : task.getParentList()) {
          if (taskList.contains(parent)) {
            ready = false;
            break;
          }
        }
        if (ready) {
          readyList.add(task);
        }
      }
      taskList.removeAll(readyList);
      // schedule readylist
      for (Task task : readyList) {
        long[] fileSizes = new long[task.getParentList().size()];
        int parentIndex = 0;
        for (Task parent : task.getParentList()) {
          long fileSize = 0;
          for (Iterator fileIter = task.getFileList().iterator(); fileIter.hasNext(); ) {
            File file = (File) fileIter.next();
            if (file.getType() == 1) {
              for (Iterator fileIter2 = parent.getFileList().iterator(); fileIter2.hasNext(); ) {
                File file2 = (File) fileIter2.next();
                if (file2.getType() == 2 && file2.getName().equals(file.getName())) {
                  fileSize += file.getSize();
                }
              }
            }
          }
          fileSizes[parentIndex] = fileSize;
          parentIndex++;
        }

        double minTime = Double.MAX_VALUE;
        int minTimeIndex = 0;

        for (int vmIndex = 0; vmIndex < getVmList().size(); vmIndex++) {
          Vm vm = (Vm) getVmList().get(vmIndex);
          double startTime = availableTime[vm.getId()];
          parentIndex = 0;
          for (Task parent : task.getParentList()) {
            int allocatedVmId = allocation[parent.getCloudletId()];
            double actualFinishTime = earliestFinishTime[parent.getCloudletId()][allocatedVmId];
            double communicationTime =
                fileSizes[parentIndex] / bandwidths[allocatedVmId][vm.getId()];

            if (actualFinishTime + communicationTime > startTime) {
              startTime = actualFinishTime + communicationTime;
            }
            parentIndex++;
          }
          earliestStartTime[task.getCloudletId()][vm.getId()] = startTime;
          double runtime = task.getCloudletLength() / vm.getMips();
          earliestFinishTime[task.getCloudletId()][vm.getId()] = runtime + startTime;

          if (runtime + startTime < minTime) {
            minTime = runtime + startTime;
            minTimeIndex = vmIndex;
          }
        }

        allocation[task.getCloudletId()] =
            minTimeIndex; // we do not really need it use task.getVmId
        task.setVmId(minTimeIndex);
        availableTime[minTimeIndex] = minTime;
      }
    }
  }