CloudSim源代码学习——任务单元(Cloudlet)

   1 /*
   2  * Title:        CloudSim Toolkit
   3  * Description:  CloudSim (Cloud Simulation) Toolkit for Modeling and Simulation of Clouds
   4  * Licence:      GPL - http://www.gnu.org/copyleft/gpl.html
   5  *
   6  * Copyright (c) 2009-2010, The University of Melbourne, Australia
   7  */
   8 
   9 package org.cloudbus.cloudsim;
  10 
  11 import java.text.DecimalFormat;//小数的  十进制的
  12 import java.util.ArrayList;//数组
  13 import java.util.LinkedList;//链接表
  14 import java.util.List;//java.util集合框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类
  15 
  16 import org.cloudbus.cloudsim.core.CloudSim;
  17 
  18 /**
  19  * Cloudlet is an extension to the cloudlet. It stores, despite all the information
  20  * encapsulated in the Cloudlet, the ID of the VM running it.
  21  *
  22  * @author        Rodrigo N. Calheiros
  23  * @author        Anton Beloglazov
  24  * @since        CloudSim Toolkit 1.0
  25  */
  26 public class Cloudlet {
  27 
  28     // the User or Broker ID. It is advisable that broker set this ID
  29     // with its own ID, so that CloudResource returns to it after the execution
  30     /** The user id. */ //用户ID
  31     private int userId;
  32 
  33     // the size of this Cloudlet to be executed in a CloudResource (unit: in MI)
  34     /** The cloudlet length. */ //云任务长度   单位:MI
  35     private long cloudletLength;
  36 
  37     // the input file size of this Cloudlet before execution (unit: in byte)
  38     /** The cloudlet file size. */ //云任务文件大小  单位:字节
  39     private final long cloudletFileSize;   // in byte = program + input data size //字节=程序+输入数据大小
  40 
  41     // the output file size of this Cloudlet after execution (unit: in byte)
  42     /** The cloudlet output size. */ //云任务输出文件大小
  43     private final long cloudletOutputSize;
  44 
  45     /** The pes number. *///执行任务请求的PE数
  46     private int pesNumber;              // num of Pe required to execute this job
  47 
  48     /** The cloudlet id. */ //云任务ID
  49     private final int cloudletId;          // this Cloudlet ID
  50 
  51     /** The status. */ //云任务状态
  52     private int status;             // status of this Cloudlet
  53 
  54     /** The num. */ //十进制格式
  55     private DecimalFormat num;      // to format the decimal number
  56 
  57     /** The finish time. */ //云任务完成时间
  58     private double finishTime;      // the time where this Cloudlet completes
  59 
  60     // start time of executing this Cloudlet.
  61     // With new functionalities, such as CANCEL, PAUSED and RESUMED, this
  62     // attribute only stores the latest execution time. Previous execution time
  63     // are ignored.
  64     /** The exec start time. */ //执行仿真开始时间
  65     private double execStartTime;   // in simulation time
  66 
  67     /** The reservation id. */  //云任务预约ID  资源的ID?(预约资源)
  68     private int reservationId = -1; // the ID of a reservation made for this cloudlet
  69 
  70     // records the transaction history for this Cloudlet //记录云任务的交易历史
  71     /** The record. */ //是否记录?
  72     private final boolean record;         // record a history or not
  73 
  74     /** The newline. */ //换行?
  75     private String newline;
  76 
  77     /** The history. */ //交易历史   String类是字符串常量,是不可更改的常量。而StringBuffer是字符串变量,它的对象是可以扩充和修改的
  78     private StringBuffer history;
  79 
  80     /** The res list. */ //资源列表?
  81     private final List<Resource> resList;
  82 
  83     /** The index. */ //索引
  84     private int index;
  85 
  86     // differentiated service 不同的服务
  87     /** The class type. */ //云任务类别 
  88     private int classType;    // class type of Cloudlet for resource scheduling
  89 
  90     /** The net to s. */ //TOS(terms of service)服务条款 ?
  91     private int netToS;       // ToS for sending Cloudlet over the network
  92 
  93 
  94 //私有访问控制符private 只能被该类自身所访问和修改,而且不能被任何其他类(包括该类的子类)来获取和引用。private修饰符用来声明那些类的私有成员,它提供了最高的保护级别
  95     ////////////////////////////////////////////
  96     // Below are CONSTANTS attributes 以下是常量属性 
  97     /** The Cloudlet has been created and added to the CloudletList object. */
  98     public static final int CREATED = 0;//云任务创建并加入云任务列表对象
  99 
 100     /** The Cloudlet has been assigned to a CloudResource object as planned. */
 101     public static final int READY = 1; //云任务按照计划分配给资源
 102 
 103     /** The Cloudlet has moved to a Cloud node. */
 104     public static final int QUEUED = 2; //云任务提交给一个【云节点】 虚拟机吗??
 105 
 106     /** The Cloudlet is in execution in a Cloud node. */
 107     public static final int INEXEC = 3; //云任务执行
 108 
 109     /** The Cloudlet has been executed successfully. */
 110     public static final int SUCCESS = 4; //云任务成功执行
 111 
 112     /** The Cloudlet is failed. */
 113     public static final int FAILED = 5; //执行失败
 114 
 115     /** The Cloudlet has been canceled. */
 116     public static final int CANCELED = 6; //云任务被取消
 117 
 118     /** The Cloudlet has been paused. It can be resumed by changing the status into <tt>RESUMED</tt>. */
 119     public static final int PAUSED = 7; //云任务执行暂停
 120 
 121     /** The Cloudlet has been resumed from <tt>PAUSED</tt> state. */
 122     public static final int RESUMED = 8; //重启执行云任务
 123 
 124     /** The cloudlet has failed due to a resource failure. */
 125     public static final int FAILED_RESOURCE_UNAVAILABLE = 9;//由于资源失败 云任务失败
 126 
 127     //公有访问控制符public  Java的类是通过包的概念来组织的,包是类的一个松散的集合。具有了被其他包中的类访问的可能性,只要这些其他包中的类在程序中使用import语句引入public类,就可以访问和引用这个类
 128     /** The vm id. */ //虚拟机编号
 129     protected int vmId;
 130 
 131     /** The cost per bw. */ //带宽费用
 132     protected double costPerBw;
 133 
 134     /** The accumulated bw cost. */ //累计的带宽费用
 135     protected double accumulatedBwCost;
 136 
 137     //protected 被三种类所引用:该类自身、与它在同一个包中的其它类、在其他包中的该类的子类。使用protected修饰符的主要作用是允许其他包中该类的子类来访问父类的特定属性。
 138 
 139 
 140     // Utilization 【利用率】
 141 
 142     /** The utilization of cpu model. */ //CPU利用模型
 143     private UtilizationModel utilizationModelCpu;
 144 
 145     /** The utilization of memory model. */ //memory利用模型
 146     private UtilizationModel utilizationModelRam;
 147 
 148     /** The utilization of bw model. */ //BW利用模型
 149     private UtilizationModel utilizationModelBw;
 150 
 151 
 152     // Data cloudlet 数据 云任务 ???
 153     /** The required files. */ //请求的文件
 154     private List<String> requiredFiles = null;   // list of required filenames
 155 
 156     /**【分配一个新的云任务对象】
 157      * Allocates a new Cloudlet object. The Cloudlet length, input and output
 158      * file sizes should be greater than or equal to 1.
 159      * By default this constructor sets the history of this object.
 160      *
 161      * @param cloudletId            the unique ID of this Cloudlet
 162      * @param cloudletLength        the length or size (in MI) of this cloudlet
 163      * to be executed in a PowerDatacenter
 164      * @param cloudletFileSize      the file size (in byte) of this cloudlet
 165      * <tt>BEFORE</tt> submitting to a PowerDatacenter
 166      * @param cloudletOutputSize    the file size (in byte) of this cloudlet
 167      * <tt>AFTER</tt> finish executing by
 168      * a PowerDatacenter
 169      * @param pesNumber the pes number
 170      * @param utilizationModelCpu the utilization model cpu
 171      * @param utilizationModelRam the utilization model ram
 172      * @param utilizationModelBw the utilization model bw
 173      *
 174      * @pre cloudletID >= 0
 175      * @pre cloudletLength >= 0.0
 176      * @pre cloudletFileSize >= 1
 177      * @pre cloudletOutputSize >= 1
 178      * @post $none
 179      */
 180     public Cloudlet(
 181             final int cloudletId, //加了一个final表示不能修改传入的参数的值
 182             final long cloudletLength,
 183             final int pesNumber,
 184             final long cloudletFileSize,
 185             final long cloudletOutputSize,
 186             final UtilizationModel utilizationModelCpu,
 187             final UtilizationModel utilizationModelRam,
 188             final UtilizationModel utilizationModelBw) {
 189         this(cloudletId, cloudletLength, pesNumber, cloudletFileSize, cloudletOutputSize, utilizationModelCpu, utilizationModelRam, utilizationModelBw, true);
 190         this.vmId=-1;
 191         this.accumulatedBwCost=0.0;
 192         this.costPerBw=0.0;
 193 
 194         this.requiredFiles = new LinkedList<String>();
 195     }//this通常指当前对象 引用当前对象的某种东西,比如当前对象的某个方法,或当前对象的某个成员,你便可以利用this来实现这个目的,this的另一个用途是调用当前对象的另一个构造函数
 196 
 197     /**
 198      * Allocates a new Cloudlet object. The Cloudlet length, input and output
 199      * file sizes should be greater than or equal to 1.
 200      *
 201      * @param cloudletId            the unique ID of this cloudlet
 202      * @param cloudletLength        the length or size (in MI) of this cloudlet
 203      * to be executed in a PowerDatacenter
 204      * @param cloudletFileSize      the file size (in byte) of this cloudlet
 205      * <tt>BEFORE</tt> submitting to a PowerDatacenter
 206      * @param cloudletOutputSize    the file size (in byte) of this cloudlet
 207      * <tt>AFTER</tt> finish executing by
 208      * a PowerDatacenter
 209      * @param record               record the history of this object or not
 210      * @param fileList                list of files required by this cloudlet
 211      * @param pesNumber the pes number
 212      * @param utilizationModelCpu the utilization model cpu
 213      * @param utilizationModelRam the utilization model ram
 214      * @param utilizationModelBw the utilization model bw
 215      *
 216      * @pre cloudletID >= 0
 217      * @pre cloudletLength >= 0.0
 218      * @pre cloudletFileSize >= 1
 219      * @pre cloudletOutputSize >= 1
 220      * @post $none
 221      */
 222     public Cloudlet(
 223             final int cloudletId,
 224             final long cloudletLength,
 225             final int pesNumber,
 226             final long cloudletFileSize,
 227             final long cloudletOutputSize,
 228             final UtilizationModel utilizationModelCpu,
 229             final UtilizationModel utilizationModelRam,
 230             final UtilizationModel utilizationModelBw,
 231             final boolean record,
 232             final List<String> fileList) {
 233         this(cloudletId, cloudletLength, pesNumber, cloudletFileSize, cloudletOutputSize, utilizationModelCpu, utilizationModelRam, utilizationModelBw, record);
 234         this.vmId=-1;
 235         this.accumulatedBwCost=0.0;//统计的带宽费用
 236         this.costPerBw=0.0;
 237 
 238         this.requiredFiles = fileList;
 239     }  //与上一个对象大部分一样!
 240 
 241     /**
 242      * Allocates a new Cloudlet object. The Cloudlet length, input and output
 243      * file sizes should be greater than or equal to 1.
 244      * By default this constructor sets the history of this object.
 245      *
 246      * @param cloudletId            the unique ID of this Cloudlet
 247      * @param cloudletLength        the length or size (in MI) of this cloudlet
 248      * to be executed in a PowerDatacenter
 249      * @param cloudletFileSize      the file size (in byte) of this cloudlet
 250      * <tt>BEFORE</tt> submitting to a PowerDatacenter
 251      * @param cloudletOutputSize    the file size (in byte) of this cloudlet
 252      * <tt>AFTER</tt> finish executing by
 253      * a PowerDatacenter
 254      * @param fileList                list of files required by this cloudlet
 255      * @param pesNumber the pes number
 256      * @param utilizationModelCpu the utilization model cpu
 257      * @param utilizationModelRam the utilization model ram
 258      * @param utilizationModelBw the utilization model bw
 259      *
 260      * @pre cloudletID >= 0
 261      * @pre cloudletLength >= 0.0
 262      * @pre cloudletFileSize >= 1
 263      * @pre cloudletOutputSize >= 1
 264      * @post $none
 265      */
 266     public Cloudlet(
 267             final int cloudletId,
 268             final long cloudletLength,
 269             final int pesNumber,
 270             final long cloudletFileSize,
 271             final long cloudletOutputSize,
 272             final UtilizationModel utilizationModelCpu,
 273             final UtilizationModel utilizationModelRam,
 274             final UtilizationModel utilizationModelBw,
 275             final List<String> fileList) {
 276         this(cloudletId, cloudletLength, pesNumber, cloudletFileSize, cloudletOutputSize, utilizationModelCpu, utilizationModelRam, utilizationModelBw, true);
 277         this.vmId=-1;
 278         this.accumulatedBwCost=0.0;
 279         this.costPerBw=0.0;
 280 
 281         this.requiredFiles = fileList;
 282     }
 283 
 284     /**
 285      * Allocates a new Cloudlet object. The Cloudlet length, input and output
 286      * file sizes should be greater than or equal to 1.
 287      *
 288      * @param cloudletId            the unique ID of this cloudlet
 289      * @param cloudletLength        the length or size (in MI) of this cloudlet
 290      * to be executed in a PowerDatacenter
 291      * @param cloudletFileSize      the file size (in byte) of this cloudlet
 292      * <tt>BEFORE</tt> submitting to a PowerDatacenter
 293      * @param cloudletOutputSize    the file size (in byte) of this cloudlet
 294      * <tt>AFTER</tt> finish executing by
 295      * a PowerDatacenter
 296      * @param record               record the history of this object or not
 297      * @param pesNumber the pes number
 298      * @param utilizationModelCpu the utilization model cpu
 299      * @param utilizationModelRam the utilization model ram
 300      * @param utilizationModelBw the utilization model bw
 301      *
 302      * @pre cloudletID >= 0
 303      * @pre cloudletLength >= 0.0
 304      * @pre cloudletFileSize >= 1
 305      * @pre cloudletOutputSize >= 1
 306      * @post $none
 307      */
 308     public Cloudlet(
 309             final int cloudletId,
 310             final long cloudletLength,
 311             final int pesNumber,
 312             final long cloudletFileSize,
 313             final long cloudletOutputSize,
 314             final UtilizationModel utilizationModelCpu,
 315             final UtilizationModel utilizationModelRam,
 316             final UtilizationModel utilizationModelBw,
 317             final boolean record) {
 318         this.userId = -1;          // 代理或用户设置 to be set by a Broker or user
 319         this.status = CREATED; //任务状态
 320         this.cloudletId = cloudletId;
 321         this.pesNumber = pesNumber;
 322         this.execStartTime = 0.0;
 323         this.finishTime = -1.0;    // 任务还没还没完成 meaning this Cloudlet hasn't finished yet
 324         this.classType = 0; //类别
 325         this.netToS = 0;
 326 
 327         // Cloudlet length, Input and Output size should be at least 1 byte.至少一个字节
 328         this.cloudletLength = Math.max(1, cloudletLength);
 329         this.cloudletFileSize = Math.max(1, cloudletFileSize);
 330         this.cloudletOutputSize = Math.max(1, cloudletOutputSize);
 331 
 332         // Normally, a Cloudlet is only executed on a resource without being
 333         // migrated to others. Hence, to reduce memory consumption, set the
 334         // size of this ArrayList to be less than the default one.设置内存大小数组列表小于默认值
 335         this.resList = new ArrayList<Resource>(2);
 336         this.index = -1;
 337         this.record = record;
 338 
 339         this.vmId = -1;
 340         this.accumulatedBwCost = 0.0;
 341         this.costPerBw = 0.0;
 342 
 343         this.requiredFiles = new LinkedList<String>();
 344 
 345         setUtilizationModelCpu(utilizationModelCpu);
 346         setUtilizationModelRam(utilizationModelRam);
 347         setUtilizationModelBw(utilizationModelBw);
 348     }
 349 
 350 //【内部类】
 351     //////////////////////// INTERNAL CLASS ///////////////////////////////////
 352 
 353     /**
 354      * Internal class that keeps track Cloudlet's movement in different
 355      * CloudResources.(不同的资源中登记云任务动向)
 356      */
 357     private static class Resource {
 358 
 359         /** Cloudlet's submission time to a CloudResource. */
 360         public double submissionTime = 0.0;//云任务的提交时间
 361 
 362         /** The time of this Cloudlet resides in a CloudResource (from arrival time until departure time). */
 363         public double wallClockTime = 0.0; //云任务从到达到撤离时间
 364 
 365         /** The total execution time of this Cloudlet in a CloudResource. */
 366         public double actualCPUTime = 0.0;//云任务执行时间
 367 
 368         /** Cost per second a CloudResource charge to execute this Cloudlet. */
 369         public double costPerSec = 0.0;//云资源每秒费用
 370 
 371         /** Cloudlet's length finished so far. */
 372         public long finishedSoFar = 0; //已完成的云任务长度
 373 
 374         /** a CloudResource id. */
 375         public int resourceId = -1;//云资源ID
 376 
 377         /** a CloudResource name. */
 378         public String resourceName = null;//云资源名
 379 
 380     } // end of internal class
 381 //【结束内部类】
 382     //////////////////////// End of Internal Class //////////////////////////
 383 
 384     /**设置预约ID
 385      * Sets the id of the reservation made for this cloudlet.
 386      *
 387      * @param resId the reservation ID
 388      *
 389      * @return <tt>true</tt> if the ID has successfully been set or
 390      * <tt>false</tt> otherwise.
 391      */
 392     public boolean setReservationId(final int resId) {//预约的ID是资源的ID?
 393         if(resId <= 0) {
 394             return false;
 395         }
 396         reservationId = resId;
 397         return true;
 398     }
 399 
 400     /**获取预约ID
 401      * Gets the reservation ID that owns this Cloudlet.
 402      *
 403      * @return a reservation ID
 404      *
 405      * @pre $none
 406      * @post $none
 407      */
 408     public int getReservationId() {
 409         return reservationId;
 410     }
 411 
 412     /**云任务是否通过预约来提交
 413      * Checks whether this Cloudlet is submitted by reserving or not.
 414      *
 415      * @return <tt>true</tt> if this Cloudlet has reserved before,
 416      * <tt>false</tt> otherwise
 417      */
 418     public boolean hasReserved() {
 419         if (reservationId == -1) {
 420             return false;
 421         }
 422         return true;
 423     }
 424 
 425     /**设置云任务长度
 426      * Sets the length or size (in MI) of this Cloudlet
 427      * to be executed in a CloudResource.
 428      * This Cloudlet length is calculated for 1 Pe only <tt>not</tt> the total
 429      * length.
 430      *
 431      * @param cloudletLength     the length or size (in MI) of this Cloudlet
 432      * to be executed in a CloudResource
 433      *
 434      * @return <tt>true</tt> if it is successful, <tt>false</tt> otherwise
 435      *
 436      * @pre cloudletLength > 0
 437      * @post $none
 438      */
 439     public boolean setCloudletLength(final long cloudletLength) {
 440         if (cloudletLength <= 0) {
 441             return false;
 442         }
 443 
 444         this.cloudletLength = cloudletLength;
 445         return true;
 446     }
 447 
 448     /**设置服务等级【可以尝试】
 449      * Sets the network service level for sending this cloudlet over a network.
 450      *
 451      * @param netServiceLevel   determines the kind of service this cloudlet
 452      * receives in the network (applicable to
 453      * selected PacketScheduler class only)
 454      *
 455      * @return <code>true</code> if successful.
 456      *
 457      * @pre netServiceLevel >= 0
 458      * @post $none
 459      */
 460     public boolean setNetServiceLevel(final int netServiceLevel) {
 461         boolean success = false;
 462         if (netServiceLevel > 0)  {
 463             netToS = netServiceLevel;
 464             success = true;
 465         }
 466 
 467         return success;
 468     }
 469 
 470     /**获取服务等级
 471      * Gets the network service level for sending this cloudlet over a network.
 472      *
 473      * @return the network service level
 474      *
 475      * @pre $none
 476      * @post $none
 477      */
 478     public int getNetServiceLevel() {
 479         return netToS;
 480     }
 481 
 482     /**获取云任务等待时间
 483      * Gets the waiting time of this cloudlet executed on a resource.
 484      *
 485      * @return the waiting time
 486      *
 487      * @pre $none
 488      * @post $none
 489      */
 490     public double getWaitingTime() {
 491         if (index == -1) {
 492             return 0;
 493         }
 494 
 495         // use the latest resource submission time
 496         final double subTime = resList.get(index).submissionTime;
 497         return execStartTime - subTime;//执行开始时间-提交时间
 498     }
 499 
 500     /**任务类别(优先权)【尝试扩展使用】
 501      * Sets the classType or priority of this Cloudlet for scheduling on a
 502      * resource.
 503      *
 504      * @param classType classType of this Cloudlet
 505      *
 506      * @return <tt>true</tt> if it is successful, <tt>false</tt> otherwise
 507      *
 508      * @pre classType > 0
 509      * @post $none
 510      */
 511     public boolean setClassType(final int classType) {
 512         boolean success = false;
 513         if (classType > 0) {
 514             this.classType = classType;
 515             success = true;
 516         }
 517 
 518         return success;
 519     }
 520 
 521     /**获取任务类别(优先权)
 522      * Gets the classtype or priority of this Cloudlet for scheduling on a
 523      * resource.
 524      *
 525      * @return classtype of this cloudlet
 526      *
 527      * @pre $none
 528      * @post $none
 529      */
 530     public int getClassType() {
 531         return classType;
 532     }
 533 
 534     /**任务请求的PE
 535      * Sets the number of PEs required to run this Cloudlet. <br>
 536      * NOTE: The Cloudlet length is computed only for 1 Pe for simplicity. <br>
 537      * For example, this Cloudlet has a length of 500 MI and requires 2 PEs.
 538      * This means each Pe will execute 500 MI of this Cloudlet.每个PE都执行500 不是各分担250???
 539      *
 540      * @param pesNumber     number of Pe
 541      *
 542      * @return <tt>true</tt> if it is successful, <tt>false</tt> otherwise
 543      *
 544      * @pre numPE > 0
 545      * @post $none
 546      */
 547     public boolean setPesNumber(final int pesNumber) {
 548         if (pesNumber > 0) {
 549             this.pesNumber = pesNumber;
 550             return true;
 551         }
 552         return false;
 553     }
 554 
 555     /**
 556      * Gets the number of PEs required to run this Cloudlet.
 557      *
 558      * @return number of PEs
 559      *
 560      * @pre $none
 561      * @post $none
 562      */
 563     public int getPesNumber() {
 564         return pesNumber;
 565     }
 566 
 567     /**云任务历史记录
 568      * Gets the history of this Cloudlet. The layout of this history is in a
 569      * readable table column with <tt>time</tt> and <tt>description</tt>
 570      * as headers.
 571      *
 572      * @return a String containing the history of this Cloudlet object.
 573      *
 574      * @pre $none
 575      * @post $result != null
 576      */
 577     public String getCloudletHistory() {
 578         String msg = null;
 579         if (history == null) {
 580             msg = "No history is recorded for Cloudlet #" + cloudletId;
 581         } else {
 582             msg = history.toString();
 583         }
 584 
 585         return msg;
 586     }
 587 
 588     /**任务已执行长度(适合 迁移任务或取消)
 589      * Gets the length of this Cloudlet that has been executed so far
 590      * from the latest CloudResource. This
 591      * method is useful when trying to move this Cloudlet into different
 592      * CloudResources or to cancel it.
 593      *
 594      * @return the length of a partially executed Cloudlet or the full Cloudlet
 595      * length if it is completed
 596      *
 597      * @pre $none
 598      * @post $result >= 0.0
 599      */
 600     public long getCloudletFinishedSoFar() {
 601         if (index == -1) {
 602             return cloudletLength;
 603         }
 604 
 605         final long finish = resList.get(index).finishedSoFar;//resList 资源列表?
 606         if (finish > cloudletLength) {
 607             return cloudletLength;
 608         }
 609 
 610         return finish;
 611     }
 612 
 613     /**检验云任务是否执行完毕
 614      * Checks whether this Cloudlet has finished execution or not.
 615      *
 616      * @return <tt>true</tt> if this Cloudlet has finished execution,
 617      * <tt>false</tt> otherwise
 618      *
 619      * @pre $none
 620      * @post $none
 621      */
 622     public boolean isFinished() {
 623         if (index == -1) {
 624             return false;
 625         }
 626 
 627         boolean completed = false;
 628 
 629         // if result is 0 or -ve then this Cloudlet has finished
 630         final long finish = resList.get(index).finishedSoFar;
 631         final long result = cloudletLength - finish;
 632         if (result <= 0.0) {
 633             completed = true;
 634         }
 635 
 636         return completed;
 637     }
 638 
 639     /**设置任务执行长度
 640      * Sets the length of this Cloudlet that has been executed so far.
 641      * This method is used by ResCloudlet class when an application
 642      * is decided to cancel or to move this Cloudlet into different
 643      * CloudResources.
 644      *
 645      * @param length    length of this Cloudlet
 646      *
 647      * @see gridsim.AllocPolicy
 648      * @see gridsim.ResCloudlet
 649      * @pre length >= 0.0
 650      * @post $none
 651      */
 652     public void setCloudletFinishedSoFar(final long length) {
 653         // if length is -ve then ignore
 654         if (length < 0.0 || index < 0) {
 655             return;
 656         }
 657 
 658         final Resource res = resList.get(index);
 659         res.finishedSoFar = length;
 660 
 661         if (record) {
 662             write("Sets the length's finished so far to " + length);
 663         }
 664     }
 665 
 666     /**设置用户ID
 667      * Sets the user or owner ID of this Cloudlet. It is <tt>VERY</tt> important
 668      * to set the user ID, otherwise this Cloudlet will not be executed in a
 669      * CloudResource.
 670      *
 671      * @param id  the user ID
 672      *
 673      * @pre id >= 0
 674      * @post $none
 675      */
 676     public void setUserId(final int id) {
 677         userId = id;
 678         if (record) {
 679             write("Assigns the Cloudlet to " + CloudSim.getEntityName(id) + " (ID #" + id + ")");
 680         }
 681     }
 682 
 683     /**
 684      * Gets the user or owner ID of this Cloudlet.
 685      *
 686      * @return the user ID or <tt>-1</tt> if the user ID has not been set before
 687      *
 688      * @pre $none
 689      * @post $result >= -1
 690      */
 691     public int getUserId() {
 692         return userId;
 693     }
 694 
 695     /**资源ID
 696      * Gets the latest resource ID that processes this Cloudlet.
 697      *
 698      * @return the resource ID or <tt>-1</tt> if none
 699      *
 700      * @pre $none
 701      * @post $result >= -1
 702      */
 703     public int getResourceId() {
 704         if (index == -1) {
 705             return -1;
 706         }
 707         return resList.get(index).resourceId;
 708     }
 709 
 710     /**获取输入文件大小
 711      * Gets the input file size of this Cloudlet <tt>BEFORE</tt>
 712      * submitting to a CloudResource.
 713      *
 714      * @return the input file size of this Cloudlet
 715      *
 716      * @pre $none
 717      * @post $result >= 1
 718      */
 719     public long getCloudletFileSize() {
 720         return cloudletFileSize;
 721     }
 722 
 723     /**获取输出文件大小
 724      * Gets the output size of this Cloudlet <tt>AFTER</tt> submitting and
 725      * executing to a CloudResource.
 726      *
 727      * @return the Cloudlet output file size
 728      *
 729      * @pre $none
 730      * @post $result >= 1
 731      */
 732     public long getCloudletOutputSize() {
 733         return cloudletOutputSize;
 734     }
 735 
 736     /**通过资源实体设置资源参数
 737      * Sets the resource parameters for which this Cloudlet is going to be
 738      * executed. <br>
 739      * NOTE: This method <tt>should</tt> be called only by a 【resource entity】,
 740      * not the user or owner of this Cloudlet.
 741      *
 742      * @param resourceID   the CloudResource ID
 743      * @param cost   the cost running this CloudResource per second
 744      *
 745      * @pre resourceID >= 0
 746      * @pre cost > 0.0
 747      * @post $none
 748      */
 749     public void setResourceParameter(final int resourceID, final double cost) {
 750         final Resource res = new Resource();
 751         res.resourceId = resourceID;
 752         res.costPerSec = cost;
 753         res.resourceName = CloudSim.getEntityName(resourceID);
 754 
 755         // add into a list if moving to a new grid resource
 756         resList.add(res);
 757 
 758         if (index == -1 && record) {
 759             write("Allocates this Cloudlet to " + res.resourceName + " (ID #" + resourceID + ") with cost = $" + cost + "/sec");
 760         } else if (record) {
 761             final int id = resList.get(index).resourceId;
 762             final String name = resList.get(index).resourceName;
 763             write("Moves Cloudlet from " + name + " (ID #" + id + ") to " +
 764                   res.resourceName + " (ID #" + resourceID +
 765                   ") with cost = $" + cost + "/sec");
 766         }
 767 
 768         index++;  // initially, index = -1
 769     }
 770 
 771     /**设置 提交  到达 时间
 772      * Sets the submission or arrival time of this Cloudlet into a CloudResource.
 773      *
 774      * @param clockTime  提交时间     the submission time
 775      *
 776      * @pre clockTime >= 0.0
 777      * @post $none
 778      */
 779     public void setSubmissionTime(final double clockTime) {
 780         if (clockTime < 0.0 || index < 0) {
 781             return;
 782         }
 783 
 784         final Resource res = resList.get(index);
 785         res.submissionTime = clockTime;
 786 
 787         if (record) {
 788             write( "Sets the submission time to " + num.format(clockTime) );
 789         }
 790     }
 791 
 792     /**
 793      * Gets the submission or arrival time of this Cloudlet from
 794      * the latest CloudResource.
 795      *
 796      * @return the submission time or <tt>0.0</tt> if none
 797      *
 798      * @pre $none
 799      * @post $result >= 0.0
 800      */
 801     public double getSubmissionTime() {
 802         if (index == -1) {
 803             return 0.0;
 804         }
 805         return resList.get(index).submissionTime;
 806     }
 807 
 808     /**设置执行开始时间 (取消 暂停 重启)
 809      * Sets the execution start time of this Cloudlet inside a CloudResource.
 810      * <b>NOTE:</b> With new functionalities, such as being able to cancel /
 811      * to pause / to resume this Cloudlet, the execution start time only holds
 812      * the latest one. Meaning, all previous execution start time are ignored.
 813      *
 814      * @param clockTime     the latest execution start time
 815      *
 816      * @pre clockTime >= 0.0
 817      * @post $none
 818      */
 819     public void setExecStartTime(final double clockTime) {
 820         execStartTime = clockTime;
 821         if (record) {
 822             write("Sets the execution start time to " + num.format(clockTime));
 823         }
 824     }
 825 
 826     /**
 827      * Gets the latest execution start time.
 828      *
 829      * @return the latest execution start time
 830      *
 831      * @pre $none
 832      * @post $result >= 0.0
 833      */
 834     public double getExecStartTime() {
 835         return execStartTime;
 836     }
 837 
 838     /**云任务执行参数设置
 839      * Sets this Cloudlet's execution parameters. These parameters are set by
 840      * the CloudResource before departure or sending back to the original
 841      * Cloudlet's owner.
 842      *
 843      * @param wallTime  (云任务停留时间)  the time of this Cloudlet resides in
 844      * a CloudResource (from arrival time until
 845      * departure time).
 846      * @param actualTime  (执行时间)  the total execution time of this Cloudlet in a
 847      * CloudResource.
 848      *
 849      * @pre wallTime >= 0.0
 850      * @pre actualTime >= 0.0
 851      * @post $none
 852      */
 853     public void setExecParam(final double wallTime, final double actualTime) {
 854         if (wallTime < 0.0 || actualTime < 0.0 || index < 0) {
 855             return;
 856         }
 857 
 858         final Resource res = resList.get(index);
 859         res.wallClockTime = wallTime;
 860         res.actualCPUTime = actualTime;
 861 
 862         if (record) {
 863             write("Sets the wall clock time to "+ num.format(wallTime)+
 864                   " and the actual CPU time to " + num.format(actualTime));
 865         }
 866     }
 867 
 868     /**云任务状态设置
 869      * Sets the status code of this Cloudlet.
 870      *
 871      * @param newStatus    the status code of this Cloudlet
 872      *
 873      * @throws Exception   Invalid range of Cloudlet status
 874      *
 875      * @pre newStatus >= 0 && newStatus <= 8
 876      * @post $none
 877      */
 878     public void setCloudletStatus(final int newStatus) throws Exception {
 879         // if the new status is same as current one, then ignore the rest
 880         if (status == newStatus) {
 881             return;
 882         }
 883 
 884         // throws an exception if the new status is outside the range
 885         if (newStatus < Cloudlet.CREATED || newStatus > Cloudlet.FAILED_RESOURCE_UNAVAILABLE) {
 886             throw new Exception("Cloudlet.setCloudletStatus() : Error - Invalid integer range for Cloudlet status.");
 887         }//newStatus  Cloudlet.CREATED 有可比性
 888 
 889         if (newStatus == Cloudlet.SUCCESS) {
 890             finishTime = CloudSim.clock();
 891         }
 892 
 893         if (record) {
 894             write("Sets Cloudlet status from " + getCloudletStatusString() + " to " + Cloudlet.getStatusString(newStatus));
 895         }
 896 
 897         this.status = newStatus;
 898     }
 899 
 900     /**
 901      * Gets the status code of this Cloudlet.
 902      *
 903      * @return the status code of this Cloudlet
 904      *
 905      * @pre $none
 906      * @post $result >= 0
 907      */
 908     public int getCloudletStatus() {
 909         return status;
 910     }
 911 
 912     /**代表此刻云任务状态
 913      * Gets the string representation of the current Cloudlet status code.
 914      *
 915      * @return the Cloudlet status code as a string or <tt>null</tt> if the
 916      * status code is unknown
 917      *
 918      * @pre $none
 919      * @post $none
 920      */
 921     public String getCloudletStatusString() {
 922         return Cloudlet.getStatusString(status);
 923     }
 924 
 925     /**
 926      * Gets the string representation of the given Cloudlet status code.
 927      *
 928      * @param status    the Cloudlet status code
 929      *
 930      * @return the Cloudlet status code as a string or <tt>null</tt> if the
 931      * status code is unknown
 932      *
 933      * @pre $none
 934      * @post $none
 935      */
 936     public static String getStatusString(final int status) {
 937         String statusString = null;
 938         switch (status)
 939         {
 940             case Cloudlet.CREATED://创建
 941                 statusString = "Created";
 942                 break;
 943 
 944             case Cloudlet.READY://准备
 945                 statusString = "Ready";
 946                 break;
 947 
 948             case Cloudlet.INEXEC://执行
 949                 statusString = "InExec";
 950                 break;
 951 
 952             case Cloudlet.SUCCESS://成功
 953                 statusString = "Success";
 954                 break;
 955 
 956             case Cloudlet.QUEUED://排队等候
 957                 statusString = "Queued";
 958                 break;
 959 
 960             case Cloudlet.FAILED://失败
 961                 statusString = "Failed";
 962                 break;
 963 
 964             case Cloudlet.CANCELED://取消
 965                 statusString = "Canceled";
 966                 break;
 967 
 968             case Cloudlet.PAUSED://暂停
 969                 statusString = "Paused";
 970                 break;
 971 
 972             case Cloudlet.RESUMED://重启
 973                 statusString = "Resumed";
 974                 break;
 975 
 976             case Cloudlet.FAILED_RESOURCE_UNAVAILABLE ://无可用资源
 977                 statusString = "Failed_resource_unavailable";
 978                 break;
 979 
 980             default:
 981                 break;
 982         }
 983 
 984         return statusString;
 985     }
 986 
 987     /**获取云任务长度
 988      * Gets the length of this Cloudlet.
 989      *
 990      * @return the length of this Cloudlet
 991      *
 992      * @pre $none
 993      * @post $result >= 0.0
 994      */
 995     public long getCloudletLength() {
 996         return cloudletLength;
 997     }
 998 
 999     /**获取任务总长度
1000      * Gets the total length (across all PEs) of this Cloudlet.
1001      *
1002      * @return the total length of this Cloudlet
1003      *
1004      * @pre $none
1005      * @post $result >= 0.0
1006      */
1007     public long getCloudletTotalLength() {
1008         return getCloudletLength() * getPesNumber();//为什么乘以PE数
1009     }
1010 
1011     /**云资源上的执行费用
1012      * Gets the cost running this Cloudlet in the latest CloudResource.
1013      *
1014      * @return the cost associated with running this Cloudlet
1015      * or <tt>0.0</tt> if none
1016      *
1017      * @pre $none
1018      * @post $result >= 0.0
1019      */
1020     public double getCostPerSec() {
1021         if (index == -1) {
1022             return 0.0;
1023         }
1024         return resList.get(index).costPerSec;
1025     }
1026 
1027     /**云任务停留时间在最近的云资源上 (云资源   是指  虚拟机??)
1028      * Gets the time of this Cloudlet resides in the latest CloudResource
1029      * (from arrival time until departure time).
1030      *
1031      * @return the time of this Cloudlet resides in a CloudResource
1032      *
1033      * @pre $none
1034      * @post $result >= 0.0
1035      */
1036     public double getWallClockTime() {
1037         if (index == -1) {
1038             return 0.0;
1039         }
1040         return resList.get(index).wallClockTime;
1041     }
1042 
1043     /**执行云任务的所有资源名称
1044      * Gets all the CloudResource names that executed this Cloudlet.
1045      *
1046      * @return an array of CloudResource names or <tt>null</tt> if it has none
1047      *
1048      * @pre $none
1049      * @post $none
1050      */
1051     public String[] getAllResourceName() {
1052         final int size = resList.size();
1053         String[] data = null;
1054 
1055         if (size > 0) {
1056             data = new String[size];
1057             for (int i = 0; i < size; i++) {
1058                 data[i] = resList.get(i).resourceName;
1059             }
1060         }
1061 
1062         return data;
1063     }
1064 
1065     /**执行云任务的所有资源ID号
1066      * Gets all the CloudResource IDs that executed this Cloudlet.
1067      *
1068      * @return an array of CloudResource IDs or <tt>null</tt> if it has none
1069      *
1070      * @pre $none
1071      * @post $none
1072      */
1073     public int[] getAllResourceId() {
1074         final int size = resList.size();
1075         int[] data = null;
1076 
1077         if (size > 0) {
1078             data = new int[size];
1079             for (int i = 0; i < size; i++) {
1080                 data[i] = resList.get(i).resourceId;
1081             }
1082         }
1083 
1084         return data;
1085     }
1086 
1087     /**云任务执行的总时间
1088      * Gets the total execution time of this Cloudlet in a given CloudResource ID.
1089      *
1090      * @param resId  a CloudResource entity ID
1091      *
1092      * @return the total execution time of this Cloudlet in a CloudResource
1093      * or <tt>0.0</tt> if not found
1094      *
1095      * @pre resId >= 0
1096      * @post $result >= 0.0
1097      */
1098     public double getActualCPUTime(final int resId) {
1099         Resource resource = getResourceById(resId);
1100         if (resource != null) {
1101             return resource.actualCPUTime;
1102         }
1103         return 0.0;
1104     }
1105 
1106     /**指定的资源上运行云任务的费用
1107      * Gets the cost running this Cloudlet in a given CloudResource ID.
1108      *
1109      * @param resId  a CloudResource entity ID
1110      *
1111      * @return the cost associated with running this Cloudlet
1112      * or <tt>0.0</tt> if not found
1113      *
1114      * @pre resId >= 0
1115      * @post $result >= 0.0
1116      */
1117     public double getCostPerSec(final int resId) {
1118         Resource resource = getResourceById(resId);
1119         if (resource != null) {
1120             return resource.costPerSec;
1121         }
1122         return 0.0;
1123     }
1124 
1125     /**指定的资源上获取云任务已执行的长度 (取消 或 移动任务至不同的云资源)
1126      * Gets the length of this Cloudlet that has been executed so far in a given
1127      * CloudResource ID. This method is useful when trying to move this Cloudlet
1128      * into different CloudResources or to cancel it.
1129      *
1130      * @param resId  a CloudResource entity ID
1131      *
1132      * @return the length of a partially executed Cloudlet or the full Cloudlet
1133      * length if it is completed or <tt>0.0</tt> if not found
1134      *
1135      * @pre resId >= 0
1136      * @post $result >= 0.0
1137      */
1138     public long getCloudletFinishedSoFar(final int resId) {
1139         Resource resource = getResourceById(resId);
1140         if (resource != null) {
1141             return resource.finishedSoFar;
1142         }
1143         return 0;
1144     }
1145 
1146     /**指定的资源上获取云任务提交  到达时间
1147      * Gets the submission or arrival time of this Cloudlet in the
1148      * given CloudResource ID.
1149      *
1150      * @param resId  a CloudResource entity ID
1151      *
1152      * @return the submission time or <tt>0.0</tt> if not found
1153      *
1154      * @pre resId >= 0
1155      * @post $result >= 0.0
1156      */
1157     public double getSubmissionTime(final int resId) {
1158         Resource resource = getResourceById(resId);
1159         if (resource != null) {
1160             return resource.submissionTime;
1161         }
1162         return 0.0;
1163     }
1164 
1165     /**指定的资源上云任务停留的时间
1166      * Gets the time of this Cloudlet resides in a given CloudResource ID
1167      * (from arrival time until departure time).
1168      *
1169      * @param resId  a CloudResource entity ID
1170      *
1171      * @return the time of this Cloudlet resides in the CloudResource
1172      * or <tt>0.0</tt> if not found
1173      *
1174      * @pre resId >= 0
1175      * @post $result >= 0.0
1176      */
1177     public double getWallClockTime(final int resId) {
1178         Resource resource = getResourceById(resId);
1179         if (resource != null) {
1180             return resource.wallClockTime;
1181         }
1182         return 0.0;
1183     }
1184 
1185     /**在ID基础上获取云资源名
1186      * Gets the CloudResource name based on its ID.
1187      *
1188      * @param resId  a CloudResource entity ID
1189      *
1190      * @return the CloudResource name or <tt>null</tt> if not found
1191      *
1192      * @pre resId >= 0
1193      * @post $none
1194      */
1195     public String getResourceName(final int resId) {
1196         Resource resource = getResourceById(resId);
1197         if (resource != null) {
1198             return resource.resourceName;
1199         }
1200         return null;
1201     }
1202 
1203     /**由ID获取资源
1204      * Gets the resource by id.
1205      *
1206      * @param resourceId the resource id
1207      *
1208      * @return the resource by id
1209      */
1210     public Resource getResourceById(final int resourceId) {
1211         for (Resource resource : resList) {
1212             if (resource.resourceId == resourceId) {
1213                 return resource;
1214             }
1215         }
1216         return null;
1217     }
1218 
1219     /**获取云任务在资源中完成时间
1220      * Gets the finish time of this Cloudlet in a CloudResource.
1221      *
1222      * @return the finish or completion time of this Cloudlet or <tt>-1</tt> if
1223      * not finished yet.
1224      *
1225      * @pre $none
1226      * @post $result >= -1
1227      */
1228     public double getFinishTime() {
1229         return finishTime;
1230     }
1231 
1232     ////////////////////////// PROTECTED METHODS //////////////////////////////
1233 
1234     /**记录云任务特别交易历史
1235      * Writes this particular history transaction of this Cloudlet into a log.
1236      *
1237      * @param str   a history transaction of this Cloudlet
1238      *
1239      * @pre str != null
1240      * @post $none
1241      */
1242     protected void write(final String str) {
1243         if (!record) {
1244             return;
1245         }
1246 
1247         if (num == null || history == null) { // Creates the history or transactions of this Cloudlet
1248             newline = System.getProperty("line.separator");
1249             num = new DecimalFormat("#0.00#"); // with 3 decimal spaces
1250             history = new StringBuffer(1000);
1251             history.append("Time below denotes the simulation time.");
1252             history.append( System.getProperty("line.separator") );
1253             history.append("Time (sec)       Description Cloudlet #"+cloudletId);
1254             history.append( System.getProperty("line.separator") );
1255             history.append("------------------------------------------");
1256             history.append( System.getProperty("line.separator") );
1257             history.append( num.format(CloudSim.clock()) );
1258             history.append("   Creates Cloudlet ID #" + cloudletId);
1259             history.append( System.getProperty("line.separator") );
1260         }
1261 
1262         history.append(num.format(CloudSim.clock()));
1263         history.append("   " + str + newline);
1264     }
1265 
1266     /**云任务状态
1267      * Get the status of the Cloudlet.
1268      *
1269      * @return status of the Cloudlet
1270      *
1271      * @pre $none
1272      * @post $none
1273      */
1274     public int getStatus(){
1275         return getCloudletStatus();
1276     }
1277 
1278     /**获取任务ID
1279      * Gets the ID of this Cloudlet.
1280      *
1281      * @return Cloudlet Id
1282      *
1283      * @pre $none
1284      * @post $none
1285      */
1286     public int getCloudletId() {
1287         return this.cloudletId;
1288     }
1289 
1290     /**获取运行云任务的虚拟机ID
1291      * Gets the ID of the VM that will run this Cloudlet.
1292      *
1293      * @return VM Id, -1 if the Cloudlet was not assigned to a VM
1294      *
1295      * @pre $none
1296      * @post $none
1297      */
1298     public int getVmId() {
1299         return vmId;
1300     }
1301 
1302     /**设置虚拟机ID
1303      * Sets the ID of the VM that will run this Cloudlet.
1304      *
1305      * @param vmId the vm id
1306      *
1307      * @pre id >= 0
1308      * @post $none
1309      */
1310     public void setVmId(final int vmId) {
1311         this.vmId = vmId;
1312     }
1313 
1314     /**
1315      * Returns the time the Cloudlet actually run.
1316      *
1317      * @return time in which the Cloudlet was running
1318      *
1319      * @pre $none
1320      * @post $none
1321      */
1322     public double getActualCPUTime(){
1323         return getFinishTime() - getExecStartTime();
1324     }
1325 
1326        /**设置资源参数
1327         * Sets the resource parameters for which this Cloudlet is going to be
1328         * executed. <br>
1329         * NOTE: This method <tt>should</tt> be called only by a resource entity,
1330         * not the user or owner of this Cloudlet.
1331         *
1332         * @param resourceID   the CloudResource ID
1333         * @param costPerCPU   the cost running this Cloudlet per second
1334         * @param costPerBw    the cost of data transfer to this PowerDatacenter
1335         *
1336         * @pre resourceID >= 0
1337         * @pre cost > 0.0
1338         * @post $none
1339         */
1340     public void setResourceParameter(final int resourceID, final double costPerCPU, final double costPerBw) {
1341         setResourceParameter(resourceID, costPerCPU);
1342         this.costPerBw = costPerBw;
1343            this.accumulatedBwCost = costPerBw * getCloudletFileSize();
1344 
1345     }
1346 
1347     /**执行云任务总费用
1348      * Gets the total cost of processing or executing this Cloudlet
1349      * <tt>Processing Cost = input data transfer + processing cost + output transfer cost</tt>.
1350      *
1351      * @return the total cost of processing Cloudlet
1352      *
1353      * @pre $none
1354      * @post $result >= 0.0
1355      */
1356     public double getProcessingCost() {
1357         //cloudlet cost: execution cost...
1358         //double cost = getProcessingCost();//处理费用
1359         double cost = 0;
1360         //...plus input data transfer cost...//数据传送费用
1361         cost += this.accumulatedBwCost;
1362         //...plus output cost输出费用
1363         cost += this.costPerBw * getCloudletOutputSize();
1364         return cost;
1365     }
1366 
1367     // Data cloudlet
1368 
1369     /**
1370      * Gets the required files.
1371      *
1372      * @return the required files
1373      */
1374     public List<String> getRequiredFiles() {
1375         return requiredFiles;
1376     }
1377 
1378     /**设置请求文件    (是指什么呢???)
1379      * Sets the required files.
1380      *
1381      * @param requiredFiles the new required files
1382      */
1383     protected void setRequiredFiles(final List<String> requiredFiles) {
1384         this.requiredFiles = requiredFiles;
1385     }
1386 
1387     /**
1388      * Adds the required filename to the list.
1389      *
1390      * @param fileName  the required filename
1391      *
1392      * @return <tt>true</tt> if succesful, <tt>false</tt> otherwise
1393      */
1394     public boolean addRequiredFile(final String fileName) {
1395         // if the list is empty
1396         if (getRequiredFiles() == null) {
1397             setRequiredFiles(new LinkedList<String>());
1398         }
1399 
1400         // then check whether filename already exists or not
1401         boolean result = false;
1402         for (int i = 0; i < getRequiredFiles().size(); i++) {
1403             final String temp = getRequiredFiles().get(i);
1404             if (temp.equals(fileName)) {
1405                 result = true;
1406                 break;
1407             }
1408         }
1409 
1410         if (!result) {
1411             getRequiredFiles().add(fileName);
1412         }
1413 
1414         return result;
1415     }
1416 
1417     /**删除给出的问就爱你名
1418      * Deletes the given filename from the list.
1419      *
1420      * @param filename  the given filename to be deleted
1421      *
1422      * @return <tt>true</tt> if succesful, <tt>false</tt> otherwise
1423      */
1424     public boolean deleteRequiredFile(final String filename) {
1425         boolean result = false;
1426         if (getRequiredFiles() == null) {
1427             return result;
1428         }
1429 
1430         for (int i = 0; i < getRequiredFiles().size(); i++) {
1431             final String temp = getRequiredFiles().get(i);
1432 
1433             if (temp.equals(filename)) {
1434                 getRequiredFiles().remove(i);
1435                 result = true;
1436 
1437                 break;
1438             }
1439         }
1440 
1441         return result;
1442     }
1443 
1444     /**
1445      * Checks whether this cloudlet requires any files or not.
1446      *
1447      * @return <tt>true</tt> if required, <tt>false</tt> otherwise
1448      */
1449     public boolean requiresFiles() {
1450         boolean result = false;
1451         if (getRequiredFiles() != null && getRequiredFiles().size() > 0) {
1452             result = true;
1453         }
1454 
1455         return result;
1456     }
1457 
1458     //【设置 cpu ram bw 利用率】
1459     /**
1460      * Gets the utilization model cpu.
1461      *
1462      * @return the utilization model cpu
1463      */
1464     public UtilizationModel getUtilizationModelCpu() {
1465         return utilizationModelCpu;
1466     }
1467 
1468     /**
1469      * Sets the utilization model cpu.
1470      *
1471      * @param utilizationModelCpu the new utilization model cpu
1472      */
1473     public void setUtilizationModelCpu(final UtilizationModel utilizationModelCpu) {
1474         this.utilizationModelCpu = utilizationModelCpu;
1475     }
1476 
1477     /**
1478      * Gets the utilization model ram.
1479      *
1480      * @return the utilization model ram
1481      */
1482     public UtilizationModel getUtilizationModelRam() {
1483         return utilizationModelRam;
1484     }
1485 
1486     /**
1487      * Sets the utilization model ram.
1488      *
1489      * @param utilizationModelRam the new utilization model ram
1490      */
1491     public void setUtilizationModelRam(final UtilizationModel utilizationModelRam) {
1492         this.utilizationModelRam = utilizationModelRam;
1493     }
1494 
1495     /**
1496      * Gets the utilization model bw.
1497      *
1498      * @return the utilization model bw
1499      */
1500     public UtilizationModel getUtilizationModelBw() {
1501         return utilizationModelBw;
1502     }
1503 
1504     /**
1505      * Sets the utilization model bw.
1506      *
1507      * @param utilizationModelBw the new utilization model bw
1508      */
1509     public void setUtilizationModelBw(final UtilizationModel utilizationModelBw) {
1510         this.utilizationModelBw = utilizationModelBw;
1511     }
1512 
1513     /**
1514      * Gets the total utilization of cpu.
1515      *
1516      * @param time the time
1517      *
1518      * @return the utilization of cpu
1519      */
1520     public double getUtilizationOfCpu(final double time) {
1521         return getUtilizationModelCpu().getUtilization(time);
1522     }
1523 
1524     /**
1525      * Gets the utilization of memory.
1526      *
1527      * @param time the time
1528      *
1529      * @return the utilization of memory
1530      */
1531     public double getUtilizationOfRam(final double time) {
1532         return getUtilizationModelRam().getUtilization(time);
1533     }
1534 
1535     /**
1536      * Gets the utilization of bw.
1537      *
1538      * @param time the time
1539      *
1540      * @return the utilization of bw
1541      */
1542     public double getUtilizationOfBw(final double time) {
1543         return getUtilizationModelBw().getUtilization(time);
1544     }
1545 
1546 }

/*

 * Title:        CloudSim Toolkit

 * Description:  CloudSim (Cloud Simulation) Toolkit for Modeling and Simulation of Clouds

 * Licence:      GPL - http://www.gnu.org/copyleft/gpl.html

 *

 * Copyright (c) 2009-2010, The University of Melbourne, Australia

 */

 

package org.cloudbus.cloudsim;

 

import java.text.DecimalFormat;//小数的  十进制的

import java.util.ArrayList;//数组

import java.util.LinkedList;//链接表

import java.util.List;//java.util集合框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类

 

import org.cloudbus.cloudsim.core.CloudSim;

 

/**

 * Cloudlet is an extension to the cloudlet. It stores, despite all the information

 * encapsulated in the Cloudlet, the ID of the VM running it.

 *

 * @authorRodrigo N. Calheiros

 * @authorAnton Beloglazov

 * @sinceCloudSim Toolkit 1.0

 */

public class Cloudlet {

 

    // the User or Broker ID. It is advisable that broker set this ID

    // with its own ID, so that CloudResource returns to it after the execution

    /** The user id. */ //用户ID

    private int userId;

 

    // the size of this Cloudlet to be executed in a CloudResource (unit: in MI)

    /** The cloudlet length. */ //云任务长度   单位:MI

    private long cloudletLength;

 

    // the input file size of this Cloudlet before execution (unit: in byte)

    /** The cloudlet file size. */ //云任务文件大小  单位:字节

    private final long cloudletFileSize;   // in byte = program + input data size //字节=程序+输入数据大小

 

    // the output file size of this Cloudlet after execution (unit: in byte)

    /** The cloudlet output size. */ //云任务输出文件大小

    private final long cloudletOutputSize;

 

    /** The pes number. *///执行任务请求的PE

    private int pesNumber;              // num of Pe required to execute this job

 

    /** The cloudlet id. */ //云任务ID

    private final int cloudletId;          // this Cloudlet ID

 

    /** The status. */ //云任务状态

    private int status;             // status of this Cloudlet

 

    /** The num. */ //十进制格式

    private DecimalFormat num;      // to format the decimal number

 

    /** The finish time. */ //云任务完成时间

    private double finishTime;      // the time where this Cloudlet completes

 

    // start time of executing this Cloudlet.

    // With new functionalities, such as CANCEL, PAUSED and RESUMED, this

    // attribute only stores the latest execution time. Previous execution time

    // are ignored.

    /** The exec start time. */ //执行仿真开始时间

    private double execStartTime;   // in simulation time

 

    /** The reservation id. */  //云任务预约ID  资源的ID?(预约资源)

    private int reservationId = -1; // the ID of a reservation made for this cloudlet

 

    // records the transaction history for this Cloudlet //记录云任务的交易历史

    /** The record. */ //是否记录?

    private final boolean record;         // record a history or not

 

    /** The newline. */ //换行?

    private String newline;

 

    /** The history. */ //交易历史   String类是字符串常量,是不可更改的常量。而StringBuffer是字符串变量,它的对象是可以扩充和修改的

    private StringBuffer history;

 

    /** The res list. */ //资源列表?

    private final List<Resource> resList;

 

    /** The index. */ //索引

    private int index;

 

    // differentiated service 不同的服务

    /** The class type. */ //云任务类别

    private int classType;    // class type of Cloudlet for resource scheduling

 

    /** The net to s. */ //TOS(terms of service)服务条款 ?

    private int netToS;       // ToS for sending Cloudlet over the network

 

 

//私有访问控制符private 只能被该类自身所访问和修改,而且不能被任何其他类(包括该类的子类)来获取和引用。private修饰符用来声明那些类的私有成员,它提供了最高的保护级别

    ////////////////////////////////////////////

    // Below are CONSTANTS attributes 以下是常量属性

    /** The Cloudlet has been created and added to the CloudletList object. */

    public static final int CREATED = 0;//云任务创建并加入云任务列表对象

 

    /** The Cloudlet has been assigned to a CloudResource object as planned. */

    public static final int READY = 1; //云任务按照计划分配给资源

 

    /** The Cloudlet has moved to a Cloud node. */

    public static final int QUEUED = 2; //云任务提交给一个【云节点】 虚拟机吗??

 

    /** The Cloudlet is in execution in a Cloud node. */

    public static final int INEXEC = 3; //云任务执行

 

    /** The Cloudlet has been executed successfully. */

    public static final int SUCCESS = 4; //云任务成功执行

 

    /** The Cloudlet is failed. */

    public static final int FAILED = 5; //执行失败

 

    /** The Cloudlet has been canceled. */

    public static final int CANCELED = 6; //云任务被取消

 

    /** The Cloudlet has been paused. It can be resumed by changing the status into <tt>RESUMED</tt>. */

    public static final int PAUSED = 7; //云任务执行暂停

 

    /** The Cloudlet has been resumed from <tt>PAUSED</tt> state. */

    public static final int RESUMED = 8; //重启执行云任务

 

    /** The cloudlet has failed due to a resource failure. */

    public static final int FAILED_RESOURCE_UNAVAILABLE = 9;//由于资源失败 云任务失败

 

    //公有访问控制符public  Java的类是通过包的概念来组织的,包是类的一个松散的集合。具有了被其他包中的类访问的可能性,只要这些其他包中的类在程序中使用import语句引入public类,就可以访问和引用这个类

/** The vm id. */ //虚拟机编号

protected int vmId;

 

/** The cost per bw. */ //带宽费用

protected double costPerBw;

 

/** The accumulated bw cost. */ //累计的带宽费用

protected double accumulatedBwCost;

 

//protected 被三种类所引用:该类自身、与它在同一个包中的其它类、在其他包中的该类的子类。使用protected修饰符的主要作用是允许其他包中该类的子类来访问父类的特定属性。

 

 

// Utilization 【利用率】

 

/** The utilization of cpu model. */ //CPU利用模型

private UtilizationModel utilizationModelCpu;

 

/** The utilization of memory model. */ //memory利用模型

private UtilizationModel utilizationModelRam;

 

/** The utilization of bw model. */ //BW利用模型

private UtilizationModel utilizationModelBw;

 

 

// Data cloudlet 数据 云任务 ???

    /** The required files. */ //请求的文件

private List<String> requiredFiles = null;   // list of required filenames

 

    /**【分配一个新的云任务对象】

     * Allocates a new Cloudlet object. The Cloudlet length, input and output

     * file sizes should be greater than or equal to 1.

     * By default this constructor sets the history of this object.

     *

     * @param cloudletId            the unique ID of this Cloudlet

     * @param cloudletLength        the length or size (in MI) of this cloudlet

     * to be executed in a PowerDatacenter

     * @param cloudletFileSize      the file size (in byte) of this cloudlet

     * <tt>BEFORE</tt> submitting to a PowerDatacenter

     * @param cloudletOutputSize    the file size (in byte) of this cloudlet

     * <tt>AFTER</tt> finish executing by

     * a PowerDatacenter

     * @param pesNumber the pes number

     * @param utilizationModelCpu the utilization model cpu

     * @param utilizationModelRam the utilization model ram

     * @param utilizationModelBw the utilization model bw

     *

     * @pre cloudletID >= 0

     * @pre cloudletLength >= 0.0

     * @pre cloudletFileSize >= 1

     * @pre cloudletOutputSize >= 1

     * @post $none

     */

public Cloudlet(

final int cloudletId, //加了一个final表示不能修改传入的参数的值

final long cloudletLength,

final int pesNumber,

final long cloudletFileSize,

final long cloudletOutputSize,

final UtilizationModel utilizationModelCpu,

final UtilizationModel utilizationModelRam,

final UtilizationModel utilizationModelBw) {

this(cloudletId, cloudletLength, pesNumber, cloudletFileSize, cloudletOutputSize, utilizationModelCpu, utilizationModelRam, utilizationModelBw, true);

this.vmId=-1;

this.accumulatedBwCost=0.0;

this.costPerBw=0.0;

 

this.requiredFiles = new LinkedList<String>();

}//this通常指当前对象 引用当前对象的某种东西,比如当前对象的某个方法,或当前对象的某个成员,你便可以利用this来实现这个目的,this的另一个用途是调用当前对象的另一个构造函数

 

    /**

     * Allocates a new Cloudlet object. The Cloudlet length, input and output

     * file sizes should be greater than or equal to 1.

     *

     * @param cloudletId            the unique ID of this cloudlet

     * @param cloudletLength        the length or size (in MI) of this cloudlet

     * to be executed in a PowerDatacenter

     * @param cloudletFileSize      the file size (in byte) of this cloudlet

     * <tt>BEFORE</tt> submitting to a PowerDatacenter

     * @param cloudletOutputSize    the file size (in byte) of this cloudlet

     * <tt>AFTER</tt> finish executing by

     * a PowerDatacenter

     * @param record               record the history of this object or not

     * @param fileList    list of files required by this cloudlet

     * @param pesNumber the pes number

     * @param utilizationModelCpu the utilization model cpu

     * @param utilizationModelRam the utilization model ram

     * @param utilizationModelBw the utilization model bw

     *

     * @pre cloudletID >= 0

     * @pre cloudletLength >= 0.0

     * @pre cloudletFileSize >= 1

     * @pre cloudletOutputSize >= 1

     * @post $none

     */

public Cloudlet(

final int cloudletId,

final long cloudletLength,

final int pesNumber,

final long cloudletFileSize,

final long cloudletOutputSize,

final UtilizationModel utilizationModelCpu,

final UtilizationModel utilizationModelRam,

final UtilizationModel utilizationModelBw,

final boolean record,

final List<String> fileList) {

this(cloudletId, cloudletLength, pesNumber, cloudletFileSize, cloudletOutputSize, utilizationModelCpu, utilizationModelRam, utilizationModelBw, record);

this.vmId=-1;

this.accumulatedBwCost=0.0;//统计的带宽费用

this.costPerBw=0.0;

 

this.requiredFiles = fileList;

}  //与上一个对象大部分一样!

 

    /**

     * Allocates a new Cloudlet object. The Cloudlet length, input and output

     * file sizes should be greater than or equal to 1.

     * By default this constructor sets the history of this object.

     *

     * @param cloudletId            the unique ID of this Cloudlet

     * @param cloudletLength        the length or size (in MI) of this cloudlet

     * to be executed in a PowerDatacenter

     * @param cloudletFileSize      the file size (in byte) of this cloudlet

     * <tt>BEFORE</tt> submitting to a PowerDatacenter

     * @param cloudletOutputSize    the file size (in byte) of this cloudlet

     * <tt>AFTER</tt> finish executing by

     * a PowerDatacenter

     * @param fileList    list of files required by this cloudlet

     * @param pesNumber the pes number

     * @param utilizationModelCpu the utilization model cpu

     * @param utilizationModelRam the utilization model ram

     * @param utilizationModelBw the utilization model bw

     *

     * @pre cloudletID >= 0

     * @pre cloudletLength >= 0.0

     * @pre cloudletFileSize >= 1

     * @pre cloudletOutputSize >= 1

     * @post $none

     */

public Cloudlet(

final int cloudletId,

final long cloudletLength,

final int pesNumber,

final long cloudletFileSize,

final long cloudletOutputSize,

final UtilizationModel utilizationModelCpu,

final UtilizationModel utilizationModelRam,

final UtilizationModel utilizationModelBw,

final List<String> fileList) {

this(cloudletId, cloudletLength, pesNumber, cloudletFileSize, cloudletOutputSize, utilizationModelCpu, utilizationModelRam, utilizationModelBw, true);

this.vmId=-1;

this.accumulatedBwCost=0.0;

this.costPerBw=0.0;

 

this.requiredFiles = fileList;

}

 

    /**

     * Allocates a new Cloudlet object. The Cloudlet length, input and output

     * file sizes should be greater than or equal to 1.

     *

     * @param cloudletId            the unique ID of this cloudlet

     * @param cloudletLength        the length or size (in MI) of this cloudlet

     * to be executed in a PowerDatacenter

     * @param cloudletFileSize      the file size (in byte) of this cloudlet

     * <tt>BEFORE</tt> submitting to a PowerDatacenter

     * @param cloudletOutputSize    the file size (in byte) of this cloudlet

     * <tt>AFTER</tt> finish executing by

     * a PowerDatacenter

     * @param record               record the history of this object or not

     * @param pesNumber the pes number

     * @param utilizationModelCpu the utilization model cpu

     * @param utilizationModelRam the utilization model ram

     * @param utilizationModelBw the utilization model bw

     *

     * @pre cloudletID >= 0

     * @pre cloudletLength >= 0.0

     * @pre cloudletFileSize >= 1

     * @pre cloudletOutputSize >= 1

     * @post $none

     */

public Cloudlet(

final int cloudletId,

final long cloudletLength,

final int pesNumber,

final long cloudletFileSize,

final long cloudletOutputSize,

final UtilizationModel utilizationModelCpu,

final UtilizationModel utilizationModelRam,

final UtilizationModel utilizationModelBw,

final boolean record) {

        this.userId = -1;          // 代理或用户设置 to be set by a Broker or user

        this.status = CREATED; //任务状态

        this.cloudletId = cloudletId;

        this.pesNumber = pesNumber;

        this.execStartTime = 0.0;

        this.finishTime = -1.0;    // 任务还没还没完成 meaning this Cloudlet hasn't finished yet

        this.classType = 0; //类别

        this.netToS = 0;

 

        // Cloudlet length, Input and Output size should be at least 1 byte.至少一个字节

        this.cloudletLength = Math.max(1, cloudletLength);

        this.cloudletFileSize = Math.max(1, cloudletFileSize);

        this.cloudletOutputSize = Math.max(1, cloudletOutputSize);

 

        // Normally, a Cloudlet is only executed on a resource without being

        // migrated to others. Hence, to reduce memory consumption, set the

        // size of this ArrayList to be less than the default one.设置内存大小数组列表小于默认值

        this.resList = new ArrayList<Resource>(2);

        this.index = -1;

        this.record = record;

 

this.vmId = -1;

this.accumulatedBwCost = 0.0;

this.costPerBw = 0.0;

 

this.requiredFiles = new LinkedList<String>();

 

setUtilizationModelCpu(utilizationModelCpu);

setUtilizationModelRam(utilizationModelRam);

setUtilizationModelBw(utilizationModelBw);

}

 

//【内部类】

    //////////////////////// INTERNAL CLASS ///////////////////////////////////

 

    /**

     * Internal class that keeps track Cloudlet's movement in different

     * CloudResources.(不同的资源中登记云任务动向)

     */

    private static class Resource {

 

        /** Cloudlet's submission time to a CloudResource. */

        public double submissionTime = 0.0;//云任务的提交时间

 

        /** The time of this Cloudlet resides in a CloudResource (from arrival time until departure time). */

        public double wallClockTime = 0.0; //云任务从到达到撤离时间

 

        /** The total execution time of this Cloudlet in a CloudResource. */

        public double actualCPUTime = 0.0;//云任务执行时间

 

        /** Cost per second a CloudResource charge to execute this Cloudlet. */

        public double costPerSec = 0.0;//云资源每秒费用

 

        /** Cloudlet's length finished so far. */

        public long finishedSoFar = 0; //已完成的云任务长度

 

        /** a CloudResource id. */

        public int resourceId = -1;//云资源ID

 

        /** a CloudResource name. */

        public String resourceName = null;//云资源名

 

    } // end of internal class

//【结束内部类】

    //////////////////////// End of Internal Class //////////////////////////

 

    /**设置预约ID

     * Sets the id of the reservation made for this cloudlet.

     *

     * @param resId the reservation ID

     *

     * @return <tt>true</tt> if the ID has successfully been set or

     * <tt>false</tt> otherwise.

     */

    public boolean setReservationId(final int resId) {//预约的ID是资源的ID

    if(resId <= 0) {

    return false;

    }

    reservationId = resId;

    return true;

    }

 

    /**获取预约ID

     * Gets the reservation ID that owns this Cloudlet.

     *

     * @return a reservation ID

     *

     * @pre $none

     * @post $none

     */

    public int getReservationId() {

        return reservationId;

    }

 

    /**云任务是否通过预约来提交

     * Checks whether this Cloudlet is submitted by reserving or not.

     *

     * @return <tt>true</tt> if this Cloudlet has reserved before,

     * <tt>false</tt> otherwise

     */

    public boolean hasReserved() {

        if (reservationId == -1) {

            return false;

        }

        return true;

    }

 

    /**设置云任务长度

     * Sets the length or size (in MI) of this Cloudlet

     * to be executed in a CloudResource.

     * This Cloudlet length is calculated for 1 Pe only <tt>not</tt> the total

     * length.

     *

     * @param cloudletLength     the length or size (in MI) of this Cloudlet

     * to be executed in a CloudResource

     *

     * @return <tt>true</tt> if it is successful, <tt>false</tt> otherwise

     *

     * @pre cloudletLength > 0

     * @post $none

     */

    public boolean setCloudletLength(final long cloudletLength) {

        if (cloudletLength <= 0) {

            return false;

        }

 

        this.cloudletLength = cloudletLength;

        return true;

    }

 

    /**设置服务等级【可以尝试】

     * Sets the network service level for sending this cloudlet over a network.

     *

     * @param netServiceLevel   determines the kind of service this cloudlet

     * receives in the network (applicable to

     * selected PacketScheduler class only)

     *

     * @return <code>true</code> if successful.

     *

     * @pre netServiceLevel >= 0

     * @post $none

     */

    public boolean setNetServiceLevel(final int netServiceLevel) {

        boolean success = false;

        if (netServiceLevel > 0)  {

            netToS = netServiceLevel;

            success = true;

        }

 

        return success;

    }

 

    /**获取服务等级

     * Gets the network service level for sending this cloudlet over a network.

     *

     * @return the network service level

     *

     * @pre $none

     * @post $none

     */

    public int getNetServiceLevel() {

        return netToS;

    }

 

    /**获取云任务等待时间

     * Gets the waiting time of this cloudlet executed on a resource.

     *

     * @return the waiting time

     *

     * @pre $none

     * @post $none

     */

    public double getWaitingTime() {

        if (index == -1) {

            return 0;

        }

 

        // use the latest resource submission time

        final double subTime = resList.get(index).submissionTime;

        return execStartTime - subTime;//执行开始时间-提交时间

    }

 

    /**任务类别(优先权)【尝试扩展使用】

     * Sets the classType or priority of this Cloudlet for scheduling on a

     * resource.

     *

     * @param classType classType of this Cloudlet

     *

     * @return <tt>true</tt> if it is successful, <tt>false</tt> otherwise

     *

     * @pre classType > 0

     * @post $none

     */

    public boolean setClassType(final int classType) {

        boolean success = false;

        if (classType > 0) {

            this.classType = classType;

            success = true;

        }

 

        return success;

    }

 

    /**获取任务类别(优先权)

     * Gets the classtype or priority of this Cloudlet for scheduling on a

     * resource.

     *

     * @return classtype of this cloudlet

     *

     * @pre $none

     * @post $none

     */

    public int getClassType() {

        return classType;

    }

 

    /**任务请求的PE

     * Sets the number of PEs required to run this Cloudlet. <br>

     * NOTE: The Cloudlet length is computed only for 1 Pe for simplicity. <br>

     * For example, this Cloudlet has a length of 500 MI and requires 2 PEs.

     * This means each Pe will execute 500 MI of this Cloudlet.每个PE都执行500 不是各分担250???

     *

     * @param pesNumber     number of Pe

     *

     * @return <tt>true</tt> if it is successful, <tt>false</tt> otherwise

     *

     * @pre numPE > 0

     * @post $none

     */

public boolean setPesNumber(final int pesNumber) {

if (pesNumber > 0) {

this.pesNumber = pesNumber;

return true;

}

return false;

}

 

    /**

     * Gets the number of PEs required to run this Cloudlet.

     *

     * @return number of PEs

     *

     * @pre $none

     * @post $none

     */

    public int getPesNumber() {

        return pesNumber;

    }

 

    /**云任务历史记录

     * Gets the history of this Cloudlet. The layout of this history is in a

     * readable table column with <tt>time</tt> and <tt>description</tt>

     * as headers.

     *

     * @return a String containing the history of this Cloudlet object.

     *

     * @pre $none

     * @post $result != null

     */

public String getCloudletHistory() {

String msg = null;

if (history == null) {

msg = "No history is recorded for Cloudlet #" + cloudletId;

} else {

msg = history.toString();

}

 

return msg;

}

 

    /**任务已执行长度(适合 迁移任务或取消)

     * Gets the length of this Cloudlet that has been executed so far

     * from the latest CloudResource. This

     * method is useful when trying to move this Cloudlet into different

     * CloudResources or to cancel it.

     *

     * @return the length of a partially executed Cloudlet or the full Cloudlet

     * length if it is completed

     *

     * @pre $none

     * @post $result >= 0.0

     */

public long getCloudletFinishedSoFar() {

if (index == -1) {

return cloudletLength;

}

 

final long finish = resList.get(index).finishedSoFar;//resList 资源列表?

if (finish > cloudletLength) {

return cloudletLength;

}

 

return finish;

}

 

    /**检验云任务是否执行完毕

     * Checks whether this Cloudlet has finished execution or not.

     *

     * @return <tt>true</tt> if this Cloudlet has finished execution,

     * <tt>false</tt> otherwise

     *

     * @pre $none

     * @post $none

     */

public boolean isFinished() {

if (index == -1) {

return false;

}

 

boolean completed = false;

 

// if result is 0 or -ve then this Cloudlet has finished

final long finish = resList.get(index).finishedSoFar;

final long result = cloudletLength - finish;

if (result <= 0.0) {

completed = true;

}

 

return completed;

}

 

    /**设置任务执行长度

     * Sets the length of this Cloudlet that has been executed so far.

     * This method is used by ResCloudlet class when an application

     * is decided to cancel or to move this Cloudlet into different

     * CloudResources.

     *

     * @param length    length of this Cloudlet

     *

     * @see gridsim.AllocPolicy

     * @see gridsim.ResCloudlet

     * @pre length >= 0.0

     * @post $none

     */

public void setCloudletFinishedSoFar(final long length) {

// if length is -ve then ignore

if (length < 0.0 || index < 0) {

return;

}

 

final Resource res = resList.get(index);

res.finishedSoFar = length;

 

if (record) {

write("Sets the length's finished so far to " + length);

}

}

 

    /**设置用户ID

     * Sets the user or owner ID of this Cloudlet. It is <tt>VERY</tt> important

     * to set the user ID, otherwise this Cloudlet will not be executed in a

     * CloudResource.

     *

     * @param id  the user ID

     *

     * @pre id >= 0

     * @post $none

     */

public void setUserId(final int id) {

userId = id;

if (record) {

write("Assigns the Cloudlet to " + CloudSim.getEntityName(id) + " (ID #" + id + ")");

}

}

 

    /**

     * Gets the user or owner ID of this Cloudlet.

     *

     * @return the user ID or <tt>-1</tt> if the user ID has not been set before

     *

     * @pre $none

     * @post $result >= -1

     */

    public int getUserId() {

        return userId;

    }

 

    /**资源ID

     * Gets the latest resource ID that processes this Cloudlet.

     *

     * @return the resource ID or <tt>-1</tt> if none

     *

     * @pre $none

     * @post $result >= -1

     */

public int getResourceId() {

if (index == -1) {

return -1;

}

return resList.get(index).resourceId;

}

 

    /**获取输入文件大小

     * Gets the input file size of this Cloudlet <tt>BEFORE</tt>

     * submitting to a CloudResource.

     *

     * @return the input file size of this Cloudlet

     *

     * @pre $none

     * @post $result >= 1

     */

    public long getCloudletFileSize() {

        return cloudletFileSize;

    }

 

    /**获取输出文件大小

     * Gets the output size of this Cloudlet <tt>AFTER</tt> submitting and

     * executing to a CloudResource.

     *

     * @return the Cloudlet output file size

     *

     * @pre $none

     * @post $result >= 1

     */

    public long getCloudletOutputSize() {

        return cloudletOutputSize;

    }

 

    /**通过资源实体设置资源参数

     * Sets the resource parameters for which this Cloudlet is going to be

     * executed. <br>

     * NOTE: This method <tt>should</tt> be called only by a resource entity,

     * not the user or owner of this Cloudlet.

     *

     * @param resourceID   the CloudResource ID

     * @param cost   the cost running this CloudResource per second

     *

     * @pre resourceID >= 0

     * @pre cost > 0.0

     * @post $none

     */

    public void setResourceParameter(final int resourceID, final double cost) {

        final Resource res = new Resource();

        res.resourceId = resourceID;

        res.costPerSec = cost;

        res.resourceName = CloudSim.getEntityName(resourceID);

 

        // add into a list if moving to a new grid resource

        resList.add(res);

 

        if (index == -1 && record) {

            write("Allocates this Cloudlet to " + res.resourceName + " (ID #" + resourceID + ") with cost = $" + cost + "/sec");

        } else if (record) {

            final int id = resList.get(index).resourceId;

            final String name = resList.get(index).resourceName;

            write("Moves Cloudlet from " + name + " (ID #" + id + ") to " +

                  res.resourceName + " (ID #" + resourceID +

                  ") with cost = $" + cost + "/sec");

        }

 

        index++;  // initially, index = -1

    }

 

    /**设置 提交  到达 时间

     * Sets the submission or arrival time of this Cloudlet into a CloudResource.

     *

     * @param clockTime  提交时间     the submission time

     *

     * @pre clockTime >= 0.0

     * @post $none

     */

    public void setSubmissionTime(final double clockTime) {

        if (clockTime < 0.0 || index < 0) {

            return;

        }

 

        final Resource res = resList.get(index);

        res.submissionTime = clockTime;

 

        if (record) {

            write( "Sets the submission time to " + num.format(clockTime) );

        }

    }

 

    /**

     * Gets the submission or arrival time of this Cloudlet from

     * the latest CloudResource.

     *

     * @return the submission time or <tt>0.0</tt> if none

     *

     * @pre $none

     * @post $result >= 0.0

     */

    public double getSubmissionTime() {

        if (index == -1) {

            return 0.0;

        }

        return resList.get(index).submissionTime;

    }

 

    /**设置执行开始时间 (取消 暂停 重启)

     * Sets the execution start time of this Cloudlet inside a CloudResource.

     * <b>NOTE:</b> With new functionalities, such as being able to cancel /

     * to pause / to resume this Cloudlet, the execution start time only holds

     * the latest one. Meaning, all previous execution start time are ignored.

     *

     * @param clockTime     the latest execution start time

     *

     * @pre clockTime >= 0.0

     * @post $none

     */

    public void setExecStartTime(final double clockTime) {

        execStartTime = clockTime;

        if (record) {

            write("Sets the execution start time to " + num.format(clockTime));

        }

    }

 

    /**

     * Gets the latest execution start time.

     *

     * @return the latest execution start time

     *

     * @pre $none

     * @post $result >= 0.0

     */

    public double getExecStartTime() {

        return execStartTime;

    }

 

    /**云任务执行参数设置

     * Sets this Cloudlet's execution parameters. These parameters are set by

     * the CloudResource before departure or sending back to the original

     * Cloudlet's owner.

     *

     * @param wallTime  (云任务停留时间)  the time of this Cloudlet resides in

     * a CloudResource (from arrival time until

     * departure time).

     * @param actualTime  (执行时间)  the total execution time of this Cloudlet in a

     * CloudResource.

     *

     * @pre wallTime >= 0.0

     * @pre actualTime >= 0.0

     * @post $none

     */

    public void setExecParam(final double wallTime, final double actualTime) {

        if (wallTime < 0.0 || actualTime < 0.0 || index < 0) {

            return;

        }

 

        final Resource res = resList.get(index);

        res.wallClockTime = wallTime;

        res.actualCPUTime = actualTime;

 

        if (record) {

            write("Sets the wall clock time to "+ num.format(wallTime)+

                  " and the actual CPU time to " + num.format(actualTime));

        }

    }

 

    /**云任务状态设置

     * Sets the status code of this Cloudlet.

     *

     * @param newStatus    the status code of this Cloudlet

     *

     * @throws Exception   Invalid range of Cloudlet status

     *

     * @pre newStatus >= 0 && newStatus <= 8

     * @post $none

     */

    public void setCloudletStatus(final int newStatus) throws Exception {

        // if the new status is same as current one, then ignore the rest

        if (status == newStatus) {

            return;

        }

 

        // throws an exception if the new status is outside the range

        if (newStatus < Cloudlet.CREATED || newStatus > Cloudlet.FAILED_RESOURCE_UNAVAILABLE) {

            throw new Exception("Cloudlet.setCloudletStatus() : Error - Invalid integer range for Cloudlet status.");

        }//newStatus  Cloudlet.CREATED 有可比性

 

        if (newStatus == Cloudlet.SUCCESS) {

            finishTime = CloudSim.clock();

        }

 

        if (record) {

            write("Sets Cloudlet status from " + getCloudletStatusString() + " to " + Cloudlet.getStatusString(newStatus));

        }

 

        this.status = newStatus;

    }

 

    /**

     * Gets the status code of this Cloudlet.

     *

     * @return the status code of this Cloudlet

     *

     * @pre $none

     * @post $result >= 0

     */

    public int getCloudletStatus() {

        return status;

    }

 

    /**代表此刻云任务状态

     * Gets the string representation of the current Cloudlet status code.

     *

     * @return the Cloudlet status code as a string or <tt>null</tt> if the

     * status code is unknown

     *

     * @pre $none

     * @post $none

     */

    public String getCloudletStatusString() {

        return Cloudlet.getStatusString(status);

    }

 

    /**

     * Gets the string representation of the given Cloudlet status code.

     *

     * @param status    the Cloudlet status code

     *

     * @return the Cloudlet status code as a string or <tt>null</tt> if the

     * status code is unknown

     *

     * @pre $none

     * @post $none

     */

    public static String getStatusString(final int status) {

        String statusString = null;

        switch (status)

        {

            case Cloudlet.CREATED://创建

                statusString = "Created";

                break;

 

            case Cloudlet.READY://准备

                statusString = "Ready";

                break;

 

            case Cloudlet.INEXEC://执行

                statusString = "InExec";

                break;

 

            case Cloudlet.SUCCESS://成功

                statusString = "Success";

                break;

 

            case Cloudlet.QUEUED://排队等候

                statusString = "Queued";

                break;

 

            case Cloudlet.FAILED://失败

                statusString = "Failed";

                break;

 

            case Cloudlet.CANCELED://取消

                statusString = "Canceled";

                break;

 

            case Cloudlet.PAUSED://暂停

                statusString = "Paused";

                break;

 

            case Cloudlet.RESUMED://重启

                statusString = "Resumed";

                break;

 

            case Cloudlet.FAILED_RESOURCE_UNAVAILABLE ://无可用资源

                statusString = "Failed_resource_unavailable";

                break;

 

            default:

                break;

        }

 

        return statusString;

    }

 

    /**获取云任务长度

     * Gets the length of this Cloudlet.

     *

     * @return the length of this Cloudlet

     *

     * @pre $none

     * @post $result >= 0.0

     */

    public long getCloudletLength() {

    return cloudletLength;

    }

 

    /**获取任务总长度

     * Gets the total length (across all PEs) of this Cloudlet.

     *

     * @return the total length of this Cloudlet

     *

     * @pre $none

     * @post $result >= 0.0

     */

    public long getCloudletTotalLength() {

        return getCloudletLength() * getPesNumber();//为什么乘以PE

    }

 

    /**云资源上的执行费用

     * Gets the cost running this Cloudlet in the latest CloudResource.

     *

     * @return the cost associated with running this Cloudlet

     * or <tt>0.0</tt> if none

     *

     * @pre $none

     * @post $result >= 0.0

     */

    public double getCostPerSec() {

        if (index == -1) {

            return 0.0;

        }

        return resList.get(index).costPerSec;

    }

 

    /**云任务停留时间在最近的云资源上 (云资源   是指  虚拟机??)

     * Gets the time of this Cloudlet resides in the latest CloudResource

     * (from arrival time until departure time).

     *

     * @return the time of this Cloudlet resides in a CloudResource

     *

     * @pre $none

     * @post $result >= 0.0

     */

    public double getWallClockTime() {

        if (index == -1) {

            return 0.0;

        }

        return resList.get(index).wallClockTime;

    }

 

    /**执行云任务的所有资源名称

     * Gets all the CloudResource names that executed this Cloudlet.

     *

     * @return an array of CloudResource names or <tt>null</tt> if it has none

     *

     * @pre $none

     * @post $none

     */

    public String[] getAllResourceName() {

        final int size = resList.size();

        String[] data = null;

 

        if (size > 0) {

            data = new String[size];

            for (int i = 0; i < size; i++) {

                data[i] = resList.get(i).resourceName;

            }

        }

 

        return data;

    }

 

    /**执行云任务的所有资源ID

     * Gets all the CloudResource IDs that executed this Cloudlet.

     *

     * @return an array of CloudResource IDs or <tt>null</tt> if it has none

     *

     * @pre $none

     * @post $none

     */

    public int[] getAllResourceId() {

        final int size = resList.size();

        int[] data = null;

 

        if (size > 0) {

            data = new int[size];

            for (int i = 0; i < size; i++) {

                data[i] = resList.get(i).resourceId;

            }

        }

 

        return data;

    }

 

    /**云任务执行的总时间

     * Gets the total execution time of this Cloudlet in a given CloudResource ID.

     *

     * @param resId  a CloudResource entity ID

     *

     * @return the total execution time of this Cloudlet in a CloudResource

     * or <tt>0.0</tt> if not found

     *

     * @pre resId >= 0

     * @post $result >= 0.0

     */

    public double getActualCPUTime(final int resId) {

        Resource resource = getResourceById(resId);

        if (resource != null) {

        return resource.actualCPUTime;

        }

        return 0.0;

    }

 

    /**指定的资源上运行云任务的费用

     * Gets the cost running this Cloudlet in a given CloudResource ID.

     *

     * @param resId  a CloudResource entity ID

     *

     * @return the cost associated with running this Cloudlet

     * or <tt>0.0</tt> if not found

     *

     * @pre resId >= 0

     * @post $result >= 0.0

     */

    public double getCostPerSec(final int resId) {

        Resource resource = getResourceById(resId);

        if (resource != null) {

        return resource.costPerSec;

        }

        return 0.0;

    }

 

    /**指定的资源上获取云任务已执行的长度 (取消 或 移动任务至不同的云资源)

     * Gets the length of this Cloudlet that has been executed so far in a given

     * CloudResource ID. This method is useful when trying to move this Cloudlet

     * into different CloudResources or to cancel it.

     *

     * @param resId  a CloudResource entity ID

     *

     * @return the length of a partially executed Cloudlet or the full Cloudlet

     * length if it is completed or <tt>0.0</tt> if not found

     *

     * @pre resId >= 0

     * @post $result >= 0.0

     */

    public long getCloudletFinishedSoFar(final int resId) {

        Resource resource = getResourceById(resId);

        if (resource != null) {

        return resource.finishedSoFar;

        }

        return 0;

    }

 

    /**指定的资源上获取云任务提交  到达时间

     * Gets the submission or arrival time of this Cloudlet in the

     * given CloudResource ID.

     *

     * @param resId  a CloudResource entity ID

     *

     * @return the submission time or <tt>0.0</tt> if not found

     *

     * @pre resId >= 0

     * @post $result >= 0.0

     */

    public double getSubmissionTime(final int resId) {

        Resource resource = getResourceById(resId);

        if (resource != null) {

        return resource.submissionTime;

        }

        return 0.0;

    }

 

    /**指定的资源上云任务停留的时间

     * Gets the time of this Cloudlet resides in a given CloudResource ID

     * (from arrival time until departure time).

     *

     * @param resId  a CloudResource entity ID

     *

     * @return the time of this Cloudlet resides in the CloudResource

     * or <tt>0.0</tt> if not found

     *

     * @pre resId >= 0

     * @post $result >= 0.0

     */

    public double getWallClockTime(final int resId) {

        Resource resource = getResourceById(resId);

        if (resource != null) {

        return resource.wallClockTime;

        }

        return 0.0;

    }

 

    /**ID基础上获取云资源名

     * Gets the CloudResource name based on its ID.

     *

     * @param resId  a CloudResource entity ID

     *

     * @return the CloudResource name or <tt>null</tt> if not found

     *

     * @pre resId >= 0

     * @post $none

     */

    public String getResourceName(final int resId) {

        Resource resource = getResourceById(resId);

        if (resource != null) {

        return resource.resourceName;

        }

        return null;

    }

 

    /**ID获取资源

     * Gets the resource by id.

     *

     * @param resourceId the resource id

     *

     * @return the resource by id

     */

    public Resource getResourceById(final int resourceId) {

    for (Resource resource : resList) {

    if (resource.resourceId == resourceId) {

    return resource;

    }

}

    return null;

    }

 

    /**获取云任务在资源中完成时间

     * Gets the finish time of this Cloudlet in a CloudResource.

     *

     * @return the finish or completion time of this Cloudlet or <tt>-1</tt> if

     * not finished yet.

     *

     * @pre $none

     * @post $result >= -1

     */

    public double getFinishTime() {

        return finishTime;

    }

 

    ////////////////////////// PROTECTED METHODS //////////////////////////////

 

    /**记录云任务特别交易历史

     * Writes this particular history transaction of this Cloudlet into a log.

     *

     * @param str   a history transaction of this Cloudlet

     *

     * @pre str != null

     * @post $none

     */

    protected void write(final String str) {

        if (!record) {

            return;

        }

 

        if (num == null || history == null) { // Creates the history or transactions of this Cloudlet

            newline = System.getProperty("line.separator");

            num = new DecimalFormat("#0.00#"); // with 3 decimal spaces

            history = new StringBuffer(1000);

            history.append("Time below denotes the simulation time.");

            history.append( System.getProperty("line.separator") );

            history.append("Time (sec)       Description Cloudlet #"+cloudletId);

            history.append( System.getProperty("line.separator") );

            history.append("------------------------------------------");

            history.append( System.getProperty("line.separator") );

            history.append( num.format(CloudSim.clock()) );

            history.append("   Creates Cloudlet ID #" + cloudletId);

            history.append( System.getProperty("line.separator") );

        }

 

        history.append(num.format(CloudSim.clock()));

        history.append("   " + str + newline);

    }

 

/**云任务状态

 * Get the status of the Cloudlet.

 *

 * @return status of the Cloudlet

 *

 * @pre $none

 * @post $none

 */

public int getStatus(){

return getCloudletStatus();

}

 

/**获取任务ID

 * Gets the ID of this Cloudlet.

 *

 * @return Cloudlet Id

 *

 * @pre $none

 * @post $none

 */

public int getCloudletId() {

return this.cloudletId;

}

 

/**获取运行云任务的虚拟机ID

 * Gets the ID of the VM that will run this Cloudlet.

 *

 * @return VM Id, -1 if the Cloudlet was not assigned to a VM

 *

 * @pre $none

 * @post $none

 */

public int getVmId() {

return vmId;

}

 

/**设置虚拟机ID

 * Sets the ID of the VM that will run this Cloudlet.

 *

 * @param vmId the vm id

 *

 * @pre id >= 0

 * @post $none

 */

public void setVmId(final int vmId) {

this.vmId = vmId;

}

 

/**

 * Returns the time the Cloudlet actually run.

 *

 * @return time in which the Cloudlet was running

 *

 * @pre $none

 * @post $none

 */

    public double getActualCPUTime(){

return getFinishTime() - getExecStartTime();

    }

 

   /**设置资源参数

    * Sets the resource parameters for which this Cloudlet is going to be

    * executed. <br>

    * NOTE: This method <tt>should</tt> be called only by a resource entity,

    * not the user or owner of this Cloudlet.

    *

    * @param resourceID   the CloudResource ID

    * @param costPerCPU   the cost running this Cloudlet per second

    * @param costPerBw    the cost of data transfer to this PowerDatacenter

    *

    * @pre resourceID >= 0

    * @pre cost > 0.0

    * @post $none

    */

public void setResourceParameter(final int resourceID, final double costPerCPU, final double costPerBw) {

    setResourceParameter(resourceID, costPerCPU);

this.costPerBw = costPerBw;

   this.accumulatedBwCost = costPerBw * getCloudletFileSize();

 

    }

 

    /**执行云任务总费用

     * Gets the total cost of processing or executing this Cloudlet

     * <tt>Processing Cost = input data transfer + processing cost + output transfer cost</tt>.

     *

     * @return the total cost of processing Cloudlet

     *

     * @pre $none

     * @post $result >= 0.0

     */

    public double getProcessingCost() {

    //cloudlet cost: execution cost...

    //double cost = getProcessingCost();//处理费用

    double cost = 0;

    //...plus input data transfer cost...//数据传送费用

cost += this.accumulatedBwCost;

    //...plus output cost输出费用

cost += this.costPerBw * getCloudletOutputSize();

        return cost;

    }

 

    // Data cloudlet

 

/**

     * Gets the required files.

     *

     * @return the required files

     */

    public List<String> getRequiredFiles() {

return requiredFiles;

}

 

/**设置请求文件    (是指什么呢???)

 * Sets the required files.

 *

 * @param requiredFiles the new required files

 */

protected void setRequiredFiles(final List<String> requiredFiles) {

this.requiredFiles = requiredFiles;

}

 

    /**

     * Adds the required filename to the list.

     *

     * @param fileName  the required filename

     *

     * @return <tt>true</tt> if succesful, <tt>false</tt> otherwise

     */

    public boolean addRequiredFile(final String fileName) {

        // if the list is empty

        if (getRequiredFiles() == null) {

            setRequiredFiles(new LinkedList<String>());

        }

 

        // then check whether filename already exists or not

        boolean result = false;

        for (int i = 0; i < getRequiredFiles().size(); i++) {

            final String temp = getRequiredFiles().get(i);

            if (temp.equals(fileName)) {

                result = true;

                break;

            }

        }

 

        if (!result) {

        getRequiredFiles().add(fileName);

        }

 

        return result;

    }

 

    /**删除给出的问就爱你名

     * Deletes the given filename from the list.

     *

     * @param filename  the given filename to be deleted

     *

     * @return <tt>true</tt> if succesful, <tt>false</tt> otherwise

     */

    public boolean deleteRequiredFile(final String filename) {

        boolean result = false;

        if (getRequiredFiles() == null) {

            return result;

        }

 

        for (int i = 0; i < getRequiredFiles().size(); i++) {

            final String temp = getRequiredFiles().get(i);

 

            if (temp.equals(filename)) {

            getRequiredFiles().remove(i);

                result = true;

 

                break;

            }

        }

 

        return result;

    }

 

    /**

     * Checks whether this cloudlet requires any files or not.

     *

     * @return <tt>true</tt> if required, <tt>false</tt> otherwise

     */

    public boolean requiresFiles() {

        boolean result = false;

        if (getRequiredFiles() != null && getRequiredFiles().size() > 0) {

            result = true;

        }

 

        return result;

    }

 

    //【设置 cpu ram bw 利用率】

/**

 * Gets the utilization model cpu.

 *

 * @return the utilization model cpu

 */

public UtilizationModel getUtilizationModelCpu() {

return utilizationModelCpu;

}

 

/**

 * Sets the utilization model cpu.

 *

 * @param utilizationModelCpu the new utilization model cpu

 */

public void setUtilizationModelCpu(final UtilizationModel utilizationModelCpu) {

this.utilizationModelCpu = utilizationModelCpu;

}

 

/**

 * Gets the utilization model ram.

 *

 * @return the utilization model ram

 */

public UtilizationModel getUtilizationModelRam() {

return utilizationModelRam;

}

 

/**

 * Sets the utilization model ram.

 *

 * @param utilizationModelRam the new utilization model ram

 */

public void setUtilizationModelRam(final UtilizationModel utilizationModelRam) {

this.utilizationModelRam = utilizationModelRam;

}

 

/**

 * Gets the utilization model bw.

 *

 * @return the utilization model bw

 */

public UtilizationModel getUtilizationModelBw() {

return utilizationModelBw;

}

 

/**

 * Sets the utilization model bw.

 *

 * @param utilizationModelBw the new utilization model bw

 */

public void setUtilizationModelBw(final UtilizationModel utilizationModelBw) {

this.utilizationModelBw = utilizationModelBw;

}

 

/**

 * Gets the total utilization of cpu.

 *

 * @param time the time

 *

 * @return the utilization of cpu

 */

public double getUtilizationOfCpu(final double time) {

return getUtilizationModelCpu().getUtilization(time);

}

 

/**

 * Gets the utilization of memory.

 *

 * @param time the time

 *

 * @return the utilization of memory

 */

public double getUtilizationOfRam(final double time) {

return getUtilizationModelRam().getUtilization(time);

}

 

/**

 * Gets the utilization of bw.

 *

 * @param time the time

 *

 * @return the utilization of bw

 */

public double getUtilizationOfBw(final double time) {

return getUtilizationModelBw().getUtilization(time);

}

 

}

原文地址:https://www.cnblogs.com/xiaoxiaoweng/p/7412224.html