From: <mar...@us...> - 2008-02-18 04:25:19
|
Revision: 106 http://gridsim.svn.sourceforge.net/gridsim/?rev=106&view=rev Author: marcos_dias Date: 2008-02-17 20:25:19 -0800 (Sun, 17 Feb 2008) Log Message: ----------- This update includes the final version of the multiple partition conservative policies. One of the policies supports advance reservations. Modified Paths: -------------- branches/gridsim4.0-branch3/examples/examples/WorkloadWithReservation.java branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleCBMultiQueues01.java branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleCBMultiQueues02.java branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEBMultiQueues01.java branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEBMultiQueues02.java branches/gridsim4.0-branch3/source/gridsim/GridResource.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARTGridResource.java branches/gridsim4.0-branch3/source/gridsim/turbo/Lublin99Workload.java branches/gridsim4.0-branch3/source/gridsim/turbo/MPAvailabilityProfile.java branches/gridsim4.0-branch3/source/gridsim/turbo/QueuePartitionPredicate.java branches/gridsim4.0-branch3/source/gridsim/turbo/TResourceCharacteristics.java Added Paths: ----------- branches/gridsim4.0-branch3/examples/examples/QueuePredicateExample.java branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARCBMultipleQueuesExample01.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARCBMultiplePartitions.java branches/gridsim4.0-branch3/source/gridsim/turbo/CBMultiplePartitions.java branches/gridsim4.0-branch3/source/gridsim/turbo/EBMultiplePartitions.java Removed Paths: ------------- branches/gridsim4.0-branch3/examples/examples/workload/parallel/QueuePredicateExample.java branches/gridsim4.0-branch3/source/gridsim/turbo/ARCBMultipleQueues.java branches/gridsim4.0-branch3/source/gridsim/turbo/CBMultipleQueues.java branches/gridsim4.0-branch3/source/gridsim/turbo/EBMultipleQueues.java Copied: branches/gridsim4.0-branch3/examples/examples/QueuePredicateExample.java (from rev 105, branches/gridsim4.0-branch3/examples/examples/workload/parallel/QueuePredicateExample.java) =================================================================== --- branches/gridsim4.0-branch3/examples/examples/QueuePredicateExample.java (rev 0) +++ branches/gridsim4.0-branch3/examples/examples/QueuePredicateExample.java 2008-02-18 04:25:19 UTC (rev 106) @@ -0,0 +1,63 @@ +package examples; + +import gridsim.turbo.QueuePartitionPredicate; +import gridsim.turbo.SSGridlet; +import gridsim.turbo.SSReservation; +import gridsim.turbo.ScheduleItem; + +/** + * Example of queue predicate. This predicate filters + * gridlets according to their runtime + * + * @author Marcos Dias de Assuncao + */ +public class QueuePredicateExample implements QueuePartitionPredicate { + int minRuntime_; + int maxRuntime_; + int resRating_; + + /* + * Default constructor + */ + public QueuePredicateExample(int minRuntime, + int maxRuntime, int rating) { + this.minRuntime_ = minRuntime; + this.maxRuntime_ = maxRuntime; + this.resRating_ = rating; + } + + /* + * (non-Javadoc) + * @see gridsim.turbo.QueuePredicate#match(gridsim.turbo.ScheduleItem) + */ + public boolean match(ScheduleItem item) { + double runtime = 0; + if(!item.isAdvanceReservation()) + runtime = forecastExecutionTime((SSGridlet)item); + else + runtime = ((SSReservation)item).getDurationTime(); + + if(runtime < minRuntime_ || runtime >= maxRuntime_) + return false; + + return true; + } + + /* + * Forecast execution time of a Gridlet. + * <tt>execution time = length / available rating</tt> + * @param gridlet the gridlet to be considered + * @return Gridlet's execution time. + */ + private double forecastExecutionTime(SSGridlet gridlet) { + double executionTime = (gridlet.getLength() / resRating_); + + // This is as a safeguard since the finish time can be extremely + // small close to 0.0, such as 4.5474735088646414E-14. Hence causing + // some Gridlets never to be finished and consequently hang the program + if (executionTime < 1.0) { + executionTime = 1.0; + } + return executionTime; + } +} \ No newline at end of file Modified: branches/gridsim4.0-branch3/examples/examples/WorkloadWithReservation.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/WorkloadWithReservation.java 2008-02-17 05:40:32 UTC (rev 105) +++ branches/gridsim4.0-branch3/examples/examples/WorkloadWithReservation.java 2008-02-18 04:25:19 UTC (rev 106) @@ -608,8 +608,7 @@ Sim_event ev = new Sim_event(); Object[] reservObj = null; - while ( Sim_system.running() - && counter < gridletID_ ) { + while ( Sim_system.running() && counter < gridletID_ ) { super.sim_get_next(ev); // get the next available event data = ev.get_data(); // get the event's data @@ -629,10 +628,12 @@ // creates a new reservation Reservation reservation = null; - reservation = super.createReservation(startTime, duration, resGl.getNumPE(), resID_); + reservation = super.createReservation(startTime, duration, + resGl.getNumPE(), resID_); success = true; - if(reservation == null || reservation.getStatus() == Reservation.STATUS_FAILED) { + if(reservation == null || + reservation.getStatus() == Reservation.STATUS_FAILED) { success = false; } @@ -661,10 +662,13 @@ catch(Exception ex) { } - list_.add(resGl); } } - counter++; + + if(!success) { + list_.add(resGl); + counter++; + } } // get the Gridlet data @@ -673,11 +677,6 @@ list_.add(gl); counter++; } - - // if all the Gridlets have been collected - if (counter == gridletID_) { - break; - } } // shut down all the entities, including GridStatistics entity since Added: branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARCBMultipleQueuesExample01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARCBMultipleQueuesExample01.java (rev 0) +++ branches/gridsim4.0-branch3/examples/examples/workload/ar/TurboARCBMultipleQueuesExample01.java 2008-02-18 04:25:19 UTC (rev 106) @@ -0,0 +1,206 @@ + +package examples.workload.ar; + +import examples.QueuePredicateExample; +import examples.WorkloadWithReservation; +import gridsim.GridResource; +import gridsim.GridSim; +import gridsim.Machine; +import gridsim.MachineList; +import gridsim.ResourceCalendar; +import gridsim.turbo.ARCBMultiplePartitions; +import gridsim.turbo.ARTGridResource; +import gridsim.turbo.TResourceCharacteristics; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.LinkedList; +import java.util.Random; + + +/** + * Test Driver class for this example. This example just tests + * the same features provided by the ParallelSpaceShared policy + */ +public class TurboARCBMultipleQueuesExample01 +{ + /** + * Creates main() to run this example + */ + public static void main(String[] args) + { + long startTime = System.currentTimeMillis(); + if(args.length == 0){ + System.out.println("Please provide the location of the workload file!"); + System.exit(1); + } + + try { + + ////////////////////////////////////////// + // Get the workload to be used The format should be: + // ASCII text, gzip or zip. + + String fileName = args[0]; + ArrayList<GridResource> resources = new ArrayList<GridResource>(); + + ////////////////////////////////////////// + // Initialize the GridSim package. It should be called + // before creating any entities. We can't run this example without + // initializing GridSim first. We will get run-time exception + // error. + + // number of grid user entities + any Workload entities. + int num_user = 1; + Calendar calendar = Calendar.getInstance(); + boolean trace_flag = false; // mean trace GridSim events + + // Initialize the GridSim package without any statistical + // functionalities. Hence, no GridSim_stat.txt file is created. + System.out.println("Initializing GridSim package"); + GridSim.init(num_user, calendar, trace_flag); + + ////////////////////////////////////////// + // Creates one or more GridResource entities + int totalResource = 1; // total number of Grid resources + int rating = 377; // rating of each PE in MIPS + int totalPE = 9; // total number of PEs for each Machine + int totalMachine = 128; // total number of Machines + int i = 0; + + String[] resArray = new String[totalResource]; + for (i = 0; i < totalResource; i++) + { + String resName = "Res_" + i; + GridResource resource = createGridResource(resName, rating, totalMachine, totalPE); + resources.add(resource); + + // add a resource name into an array + resArray[i] = resName; + } + + ////////////////////////////////////////// + // Creates one Workload trace entity. + + int resID = 0; + Random r = new Random(); + resID = r.nextInt(totalResource); + WorkloadWithReservation workload = + new WorkloadWithReservation("Load_1", fileName, resArray[resID], rating); + + // sets how long in advance the reservations are made (24 hours here) + workload.setARTimeInAdvance( 24 * 60 * 60 ); + + // sets the probability of a job read from the trace file being an advance reservation + workload.setReservationProbability(0.5); + + ////////////////////////////////////////// + // Starts the simulation in debug mode +// GridSim.startGridSimulation(true); + + // Start the simulation in normal mode + GridSim.startGridSimulation(); + + ////////////////////////////////////////// + // Final step: Prints the Gridlets when simulation is over + long finishTime = System.currentTimeMillis(); + System.out.println("The simulation took " + (finishTime - startTime) + " milliseconds"); + + // prints the Gridlets inside a Workload entity + // workload.printGridletList(trace_flag); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Creates one Grid resource. A Grid resource contains one or more + * Machines. Similarly, a Machine contains one or more PEs (Processing + * Elements or CPUs). + * @param name a Grid Resource name + * @param peRating rating of each PE + * @param totalMachine total number of Machines + * @param totalPE total number of PEs for each Machine + */ + private static GridResource createGridResource(String name, int peRating, + int totalMachine, int totalPE) + { + + ////////////////////////////////////////// + // Here are the steps needed to create a Grid resource: + // 1. We need to create an object of MachineList to store one or more + // Machines + MachineList mList = new MachineList(); + + for (int i = 0; i < totalMachine; i++) + { + ////////////////////////////////////////// + // 4. Create one Machine with its id and list of PEs or CPUs + mList.add( new Machine(i, totalPE, peRating) ); + } + + ////////////////////////////////////////// + // 5. Create a ResourceCharacteristics object that stores the + // properties of a Grid resource: architecture, OS, list of + // Machines, allocation policy: time- or space-shared, time zone + // and its price (G$/PE time unit). + String arch = "Sun Ultra"; // system architecture + String os = "Solaris"; // operating system + double time_zone = 0.0; // time zone this resource located + double cost = 3.0; // the cost of using this resource + + TResourceCharacteristics resConfig = + new TResourceCharacteristics(arch, os, mList, + TResourceCharacteristics.ARCB_MULTI_PARTITIONS, + time_zone, cost); + + ARCBMultiplePartitions policy = null; + try { + policy = new ARCBMultiplePartitions(name, "Policy", 3); + } catch (Exception e1) { + e1.printStackTrace(); + } + + // creates three partitions, one for small jobs, one for medium size jobs + // and another for long jobs + QueuePredicateExample express = new QueuePredicateExample(0, 1000, peRating); + QueuePredicateExample medium = new QueuePredicateExample(1000, 10000, peRating); + QueuePredicateExample large = new QueuePredicateExample(10000, Integer.MAX_VALUE, peRating); + + policy.createPartition(0, resConfig.getNumPE() / 3, express); + policy.createPartition(1, resConfig.getNumPE() / 3, medium); + policy.createPartition(2, resConfig.getNumPE() / 3, large); + + ////////////////////////////////////////// + // 6. Finally, we need to create a GridResource object. + double baud_rate = 10000.0; // communication speed + long seed = 11L*13*17*19*23+1; + double peakLoad = 0.0; // the resource load during peak hour + double offPeakLoad = 0.0; // the resource load during off-peak hr + double holidayLoad = 0.0; // the resource load during holiday + + // incorporates weekends so the grid resource is on 7 days a week + LinkedList weekends = new LinkedList(); + weekends.add(new Integer(Calendar.SATURDAY)); + weekends.add(new Integer(Calendar.SUNDAY)); + + // incorporates holidays. However, no holidays are set in this example + LinkedList holidays = new LinkedList(); + ResourceCalendar resCalendar = new ResourceCalendar(time_zone, + peakLoad, offPeakLoad, holidayLoad, weekends, + holidays, seed); + + ARTGridResource gridRes = null; + try { + gridRes = new ARTGridResource(name, baud_rate, resConfig, resCalendar, policy); + } + catch (Exception e) { + e.printStackTrace(); + } + + System.out.println("Creates one Grid resource with name = " + name); + return gridRes; + } +} // end class + Deleted: branches/gridsim4.0-branch3/examples/examples/workload/parallel/QueuePredicateExample.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/QueuePredicateExample.java 2008-02-17 05:40:32 UTC (rev 105) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/QueuePredicateExample.java 2008-02-18 04:25:19 UTC (rev 106) @@ -1,63 +0,0 @@ -package examples.workload.parallel; - -import gridsim.turbo.QueuePartitionPredicate; -import gridsim.turbo.SSGridlet; -import gridsim.turbo.SSReservation; -import gridsim.turbo.ScheduleItem; - -/** - * Example of queue predicate. This predicate filters - * gridlets according to their runtime - * - * @author Marcos Dias de Assuncao - */ -class QueuePredicateExample implements QueuePartitionPredicate { - int minRuntime_; - int maxRuntime_; - int resRating_; - - /* - * Default constructor - */ - public QueuePredicateExample(int minRuntime, - int maxRuntime, int rating) { - this.minRuntime_ = minRuntime; - this.maxRuntime_ = maxRuntime; - this.resRating_ = rating; - } - - /* - * (non-Javadoc) - * @see gridsim.turbo.QueuePredicate#match(gridsim.turbo.ScheduleItem) - */ - public boolean match(ScheduleItem item) { - double runtime = 0; - if(!item.isAdvanceReservation()) - runtime = forecastExecutionTime((SSGridlet)item); - else - runtime = ((SSReservation)item).getDurationTime(); - - if(runtime < minRuntime_ || runtime >= maxRuntime_) - return false; - - return true; - } - - /* - * Forecast execution time of a Gridlet. - * <tt>execution time = length / available rating</tt> - * @param gridlet the gridlet to be considered - * @return Gridlet's execution time. - */ - private double forecastExecutionTime(SSGridlet gridlet) { - double executionTime = (gridlet.getLength() / resRating_); - - // This is as a safeguard since the finish time can be extremely - // small close to 0.0, such as 4.5474735088646414E-14. Hence causing - // some Gridlets never to be finished and consequently hang the program - if (executionTime < 1.0) { - executionTime = 1.0; - } - return executionTime; - } -} \ No newline at end of file Modified: branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleCBMultiQueues01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleCBMultiQueues01.java 2008-02-17 05:40:32 UTC (rev 105) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleCBMultiQueues01.java 2008-02-18 04:25:19 UTC (rev 106) @@ -8,7 +8,7 @@ import gridsim.MachineList; import gridsim.ResourceCalendar; import gridsim.ResourceCharacteristics; -import gridsim.turbo.EBMultipleQueues; +import gridsim.turbo.EBMultiplePartitions; import gridsim.turbo.TResourceCharacteristics; import gridsim.util.Workload; @@ -144,7 +144,7 @@ // this resource will use an aggressive backfilling policy (EASY) TResourceCharacteristics resConfig = new TResourceCharacteristics(arch, os, mList, - TResourceCharacteristics.MULTI_CONSERVATIVE_BACKFILLING_QUEUES, + TResourceCharacteristics.CB_MULTI_PARTITIONS, time_zone, cost); ////////////////////////////////////////// Modified: branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleCBMultiQueues02.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleCBMultiQueues02.java 2008-02-17 05:40:32 UTC (rev 105) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleCBMultiQueues02.java 2008-02-18 04:25:19 UTC (rev 106) @@ -1,13 +1,14 @@ package examples.workload.parallel; +import examples.QueuePredicateExample; import gridsim.GridResource; import gridsim.GridSim; import gridsim.Machine; import gridsim.MachineList; import gridsim.ResourceCalendar; -import gridsim.turbo.CBMultipleQueues; -import gridsim.turbo.EBMultipleQueues; +import gridsim.turbo.CBMultiplePartitions; +import gridsim.turbo.EBMultiplePartitions; import gridsim.turbo.TResourceCharacteristics; import gridsim.util.Workload; @@ -142,12 +143,12 @@ // this resource will use an aggressive backfilling policy (EASY) TResourceCharacteristics resConfig = new TResourceCharacteristics( - arch, os, mList, TResourceCharacteristics.MULTI_CONSERVATIVE_BACKFILLING_QUEUES, + arch, os, mList, TResourceCharacteristics.CB_MULTI_PARTITIONS, time_zone, cost); - CBMultipleQueues policy = null; + CBMultiplePartitions policy = null; try { - policy = new CBMultipleQueues(name, "Policy", 3); + policy = new CBMultiplePartitions(name, "Policy", 3); } catch (Exception e1) { e1.printStackTrace(); } Modified: branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEBMultiQueues01.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEBMultiQueues01.java 2008-02-17 05:40:32 UTC (rev 105) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEBMultiQueues01.java 2008-02-18 04:25:19 UTC (rev 106) @@ -8,7 +8,7 @@ import gridsim.MachineList; import gridsim.ResourceCalendar; import gridsim.ResourceCharacteristics; -import gridsim.turbo.EBMultipleQueues; +import gridsim.turbo.EBMultiplePartitions; import gridsim.turbo.TResourceCharacteristics; import gridsim.util.Workload; @@ -143,7 +143,7 @@ // this resource will use an aggressive backfilling policy (EASY) TResourceCharacteristics resConfig = new TResourceCharacteristics( - arch, os, mList, TResourceCharacteristics.MULTI_EASY_BACKFILLING_QUEUES, + arch, os, mList, TResourceCharacteristics.EB_MULTI_PARTITIONS, time_zone, cost); ////////////////////////////////////////// Modified: branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEBMultiQueues02.java =================================================================== --- branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEBMultiQueues02.java 2008-02-17 05:40:32 UTC (rev 105) +++ branches/gridsim4.0-branch3/examples/examples/workload/parallel/TurboExampleEBMultiQueues02.java 2008-02-18 04:25:19 UTC (rev 106) @@ -1,12 +1,13 @@ package examples.workload.parallel; +import examples.QueuePredicateExample; import gridsim.GridResource; import gridsim.GridSim; import gridsim.Machine; import gridsim.MachineList; import gridsim.ResourceCalendar; -import gridsim.turbo.EBMultipleQueues; +import gridsim.turbo.EBMultiplePartitions; import gridsim.turbo.TResourceCharacteristics; import gridsim.util.Workload; @@ -140,12 +141,12 @@ // this resource will use an aggressive backfilling policy (EASY) TResourceCharacteristics resConfig = new TResourceCharacteristics( - arch, os, mList, TResourceCharacteristics.MULTI_EASY_BACKFILLING_QUEUES, + arch, os, mList, TResourceCharacteristics.EB_MULTI_PARTITIONS, time_zone, cost); - EBMultipleQueues policy = null; + EBMultiplePartitions policy = null; try { - policy = new EBMultipleQueues(name, "Policy", 3); + policy = new EBMultiplePartitions(name, "Policy", 3); } catch (Exception e1) { e1.printStackTrace(); } Modified: branches/gridsim4.0-branch3/source/gridsim/GridResource.java =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/GridResource.java 2008-02-17 05:40:32 UTC (rev 105) +++ branches/gridsim4.0-branch3/source/gridsim/GridResource.java 2008-02-18 04:25:19 UTC (rev 106) @@ -10,11 +10,12 @@ package gridsim; import gridsim.net.*; +import gridsim.turbo.ARCBMultiplePartitions; import gridsim.turbo.ARParallelSpaceShared; -import gridsim.turbo.CBMultipleQueues; +import gridsim.turbo.CBMultiplePartitions; import gridsim.turbo.EBParallelSpaceShared; import gridsim.turbo.CBParallelSpaceShared; -import gridsim.turbo.EBMultipleQueues; +import gridsim.turbo.EBMultiplePartitions; import gridsim.turbo.TResourceCharacteristics; import gridsim.index.*; @@ -535,12 +536,10 @@ super.sim_get_next(ev); // if the simulation finishes then exit the loop - if (ev.get_tag() == GridSimTags.END_OF_SIMULATION) - { + if (ev.get_tag() == GridSimTags.END_OF_SIMULATION) { policy_.setEndSimulation(); break; } - // process the received event processEvent(ev); } @@ -648,16 +647,21 @@ break; // creates the scheduler with only one queue - case TResourceCharacteristics.MULTI_EASY_BACKFILLING_QUEUES: - policy_ = new EBMultipleQueues(super.get_name(), + case TResourceCharacteristics.EB_MULTI_PARTITIONS: + policy_ = new EBMultiplePartitions(super.get_name(), "EBMultipleQueues", 1); break; - case TResourceCharacteristics.MULTI_CONSERVATIVE_BACKFILLING_QUEUES: - policy_ = new CBMultipleQueues(super.get_name(), + case TResourceCharacteristics.CB_MULTI_PARTITIONS: + policy_ = new CBMultiplePartitions(super.get_name(), "CBMultipleQueues", 1); break; + case TResourceCharacteristics.ARCB_MULTI_PARTITIONS: + policy_ = new ARCBMultiplePartitions(super.get_name(), + "ARCBMultipleQueues", 1); + break; + default: throw new Exception(super.get_name()+" : Error - supports"+ " only TimeShared or SpaceShared policy."); Copied: branches/gridsim4.0-branch3/source/gridsim/turbo/ARCBMultiplePartitions.java (from rev 105, branches/gridsim4.0-branch3/source/gridsim/turbo/ARCBMultipleQueues.java) =================================================================== --- branches/gridsim4.0-branch3/source/gridsim/turbo/ARCBMultiplePartitions.java (rev 0) +++ branches/gridsim4.0-branch3/source/gridsim/turbo/ARCBMultiplePartitions.java 2008-02-18 04:25:19 UTC (rev 106) @@ -0,0 +1,1144 @@ +/* + * Title: GridSim Toolkit + * Description: GridSim (Grid Simulation) Toolkit for Modelling and Simulation + * of Parallel and Distributed Systems such as Clusters and Grids + * Licence: GPL - http://www.gnu.org/copyleft/gpl.html + */ + +package gridsim.turbo; + +import eduni.simjava.Sim_event; +import gridsim.GridSim; +import gridsim.GridSimTags; +import gridsim.Gridlet; +import gridsim.IO_data; +import gridsim.gui.AllocationAction; + +import java.util.Calendar; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; + +/** + * This class implements a non-FCFS policy to schedule parallel jobs. The + * policy is based on conservative backfilling and supports advance reservation. + * This policy can use multiple partitions or queues and the jobs can be + * directed to these partitions using a partition predicate + * ({@link QueuePartitionPredicate}. A partition can borrow resources from + * another when it requires and the resources are not being used by the + * other partition. + * + * We use an availability profile to store the availability of processing + * elements. In order to represent the pivots (i.e. the first jobs in the + * partitions), we schedule them creating the entries in the availability + * profile. This way, we do not need to store the pivots' start times + * (or shadow times) and extra nodes in different variables. It also makes + * the search for available resources for a new pivot easier. + * <p> + * <b>LIMITATIONS:</b><br> + * <ul> + * <li> The list of machines comprising this resource must be + * homogeneous. + * <li> Local load is not considered. If you would like to simulate this, + * you have to model the local load as gridlets. It is more precise + * and faster. To do so, please check {@link Lublin99Workload}. + * <li> Gridlets cannot be paused nor migrated. + * </ul> + * + * @see gridsim.GridSim + * @see gridsim.ResourceCharacteristics + * @see gridsim.turbo.TAllocPolicy + * @see gridsim.turbo.CBMultiplePartitions + * @see gridsim.turbo.QueuePartitionPredicate + * @see gridsim.turbo.PERange + * @see gridsim.turbo.PERangeList + */ + +public class ARCBMultiplePartitions extends + CBMultiplePartitions implements ARTPolicy { + + // a new reservation table + private LinkedHashMap<Integer, SSReservation> reservTable_; + + // a table that contains expired reservations + private LinkedHashMap<Integer, SSReservation> expiryTable_; + + // default booking/reservation commit period + private int commitPeriod_; + + // internal event tags used by this gridlet + // a tag to denote expiry time + private final int EXPIRY_TIME = 12; + + // last time the expiration of reservations was checked + private double lastCheckExpiryTime_; + + /** + * Allocates a new <tt>CBMultipleQueues</tt> object. + * If the policy is create with only one partition, it will then work as + * a normal aggressive (EASY) backfilling scheduler. + * + * @param resourceName the <tt>GridResource</tt> entity name that will + * contain this allocation policy + * @param entityName this object entity name + * @param numPartitions The number of partitions of the scheduling queue + * @throws Exception This happens when one of the following scenarios occur: + * <ul> + * <li> Creating this entity before initialising GridSim package + * <li> The entity name is <tt>null</tt> or empty + * <li> The entity has <tt>zero</tt> number of PEs (Processing + * Elements). <br> + * No PEs, which means that the Gridlets cannot be processed. + * A GridResource must contain one or more Machines. + * A Machine must contain one or more PEs. + * </ul> + * + * @see gridsim.GridSim#init(int, Calendar, boolean, + * String[], String[], String) + */ + public ARCBMultiplePartitions(String resourceName, + String entityName, int numPartitions) throws Exception { + super(resourceName, entityName, numPartitions); + commitPeriod_ = 30*60; // set the expiration time into 30 mins + init(); + } + + /** + * Allocates a new <tt>CBMultipleQueues</tt> object. + * If the policy is create with only one partition, it will then work as + * a normal aggressive (EASY) backfilling scheduler. + * + * @param resourceName the <tt>GridResource</tt> entity name that will + * contain this allocation policy + * @param entityName this object entity name + * @param numPartitions The number of partitions of the scheduling queue + * @param commitPeriod a default commit period time for a user to commit + * a reservation (unit is in second). <b>NOTE:</b> once it is set, you cannot + * change the time again. + * @throws Exception This happens when one of the following scenarios occur: + * <ul> + * <li> Creating this entity before initialising GridSim package + * <li> The entity name is <tt>null</tt> or empty + * <li> The entity has <tt>zero</tt> number of PEs (Processing + * Elements). <br> + * No PEs, which means that the Gridlets cannot be processed. + * A GridResource must contain one or more Machines. + * A Machine must contain one or more PEs. + * </ul> + * + * @see gridsim.GridSim#init(int, Calendar, boolean, + * String[], String[], String) + */ + public ARCBMultiplePartitions(String resourceName, + String entityName, int numPartitions, + int commitPeriod) throws Exception { + super(resourceName, entityName, numPartitions); + if (commitPeriod <= 0) { + throw new Exception(resourceName + "." + entityName + + ": Error - Invalid expiry time."); + } + commitPeriod_ = commitPeriod; + init(); + } + + /** + * Handles internal events that come to this entity. + */ + public void body() { + super.body(); + reservTable_.clear(); + expiryTable_.clear(); + lastCheckExpiryTime_ = 0.0D; + } + + // -------------------- GRIDLET RELATED METHODS --------------------- + + /** + * Schedules a new <tt>Gridlet</tt> received by the <tt>GridResource</tt> entity. + * @param gridlet a Gridlet object to be executed + * @param ack an acknowledgement, i.e. <tt>true</tt> if the + * user wants to know whether this operation is successful + * or not, <tt>false</tt> otherwise. + */ + public void gridletSubmit(Gridlet gridlet, boolean ack) { + if(!gridlet.hasReserved()) { + super.gridletSubmit(gridlet, ack); + } + else { + handleReservationGridlet(gridlet, ack); + } + } + + /** + * Schedules a new Gridlet received by the <tt>ARTGridResource</tt> + * entity and for which an advance reservation has been made. + * @param gridlet a Gridlet object to be executed + * @param ack an acknowledgement, i.e. <tt>true</tt> if the + * user wants to know whether this operation is successful + * or not, <tt>false</tt> otherwise. + */ + private void handleReservationGridlet(Gridlet gridlet, boolean ack) { + + double currentTime = GridSim.clock(); + + int freePE; + int reqPE = gridlet.getNumPE(); + // gets the advance reservation + SSReservation sRes = reservTable_.get(gridlet.getReservationID()); + + // create an SSGridlet + SSGridlet sgl = new SSGridlet(gridlet); + + // forecast the execution time of the gridlet + double executionTime = + super.forecastExecutionTime(ratingPE_, sgl.getLength()); + + /////////////// FOR DEBUGGING PURPOSES ONLY //////// + + GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_ARRIVED, true, sgl); + + ///////////////////////////////////////////////////// + + boolean success = true; + if(sRes == null) { + String userName = GridSim.getEntityName( gridlet.getUserID() ); + System.out.println(super.get_name() + ".gridletSubmit(): " + + " Gridlet #" + gridlet.getGridletID() + " from " + + userName + " cannot be accepted because the reservation #" + + gridlet.getReservationID() + " has not been found."); + success = false; + } + // check if the gridlet is requiring more PEs than what + // the reservation currently has + else if( (freePE = sRes.getNumRemainingPE()) < reqPE ) { + String userName = GridSim.getEntityName( gridlet.getUserID() ); + System.out.println(super.get_name() + ".gridletSubmit(): " + + " Gridlet #" + gridlet.getGridletID() + " from " + + userName + " cannot be accepted because the reservation #" + + sRes.getID() + " has only " + freePE + " PEs."); + success = false; + } + // check whether the gridlet is expected to run for longer than + // the time previously reserved + else if (executionTime >= sRes.getDurationTime()) { + String userName = GridSim.getEntityName( gridlet.getUserID() ); + System.out.println(super.get_name() + ".gridletSubmit(): " + + " Gridlet #" + gridlet.getGridletID() + " from " + + userName + " cannot be accepted because the reservation #" + + sRes.getID() + " is for " + sRes.getDurationTime() + + " while the gridlet is expected to run for " + + executionTime + " seconds."); + success = false; + } + + if(!success) { + try { + gridlet.setGridletStatus(Gridlet.FAILED); + super.sendFinishGridlet(gridlet); + return; + } + catch(Exception ex){ + System.out.println(super.get_name() + + ": Exception on submission of a Gridlet. Message = " + + ex.getMessage()); + return; + } + } + else { + // selects a list of ranges for the gridlet from the PEs available + // for the reservation + PERangeList selected = null; + success = ( ( selected = sRes.selectPERangeList(reqPE) ) != null ); + + sgl.setPERangeList(selected); + double resStartTime = sRes.getStartTime(); + sgl.setStartTime(resStartTime); + sgl.setFinishTime(resStartTime + executionTime); + sgl.setStatus(Gridlet.QUEUED); + queuedGridlets_.add(sgl); + + // if the reservation has not been committed, then commit the + // reservation + if (sRes.getStatus() == Reservation.STATUS_NOT_COMMITTED) { + sRes.setStatus(Reservation.STATUS_COMMITTED); + super.sendInternalEvent(resStartTime - currentTime, + CBParallelSpaceShared.UPDATE_SCHEDULE_TAG); + } + // if the reservation has already started, then update the + // schedule, which will force the gridlets in the queue to + // be started + else if(sRes.getStatus() == Reservation.STATUS_IN_PROGRESS) { + super.sendInternalEvent(resStartTime - currentTime, + CBParallelSpaceShared.UPDATE_SCHEDULE_TAG); + } + } + + //------------------ FOR DEBUGGING PURPOSES ONLY ---------------- + + // Notifies the listeners that a Gridlet has been either scheduled + // to run immediately or put in the waiting queue + GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_SCHEDULED, true, sgl); + + //--------------------------------------------------------------- + + // sends back an ack if required + if (ack == true) { + super.sendAck(GridSimTags.GRIDLET_SUBMIT_ACK, true, + gridlet.getGridletID(), gridlet.getUserID() + ); + } + } + + //---------------- RESERVATION RELATED PUBLIC METHODS --------------------- + + /** + * Handles an advance reservation request.<br> + * @param message the advance reservation message received + * @pre message != null + */ + public void handleCreateReservation(ARMessage message) { + double currentTime = GridSim.clock(); + + // gets the reservation object and extract some + // information from it + Reservation reservation = message.getReservation(); + double startTime = reservation.getStartTime(); + int duration = reservation.getDurationTime(); + int reqPE = reservation.getNumPE(); + + // creates a Server Side Reservation (i.e. SSReservation) + SSReservation sRes = new SSReservation(reservation); + sRes.setPartitionID(profile_.getCorrespondingPartitionID(sRes)); + double expTime = Double.NaN; + + // creates a response message to be sent to the requester + ARMessage response = message.createResponse(); + + //-------------- FOR DEBUGGING PURPOSES ONLY -------------- + + // informs the listeners that a reservation request has arrived + GridSim.notifyListeners(this.get_id(), + AllocationAction.ITEM_ARRIVED, true, sRes); + + //---------------------------------------------------------- + + if (reqPE > super.totalPE_) { + String userName = GridSim.getEntityName( message.getSourceID() ); + System.out.println(super.get_name() + ".handleCreateReservation():" + + " Reservation #" + reservation.getID() + " from " + + userName + " user requires " + reservation.getNumPE() + + " PEs from " + startTime + " to " + (startTime + duration)); + System.out.println("--> The resource has only " + + super.totalPE_ + " PEs available."); + + reservation.setStatus(Reservation.STATUS_FAILED); + response.setErrorCode(ARMessage.EC_OPERATION_FAILURE); + sendARMessage(response); + return; + } + + boolean success = true; + + // if start time is 0, then it is an immediate reservation + if(startTime == 0 || startTime == currentTime) { + success = handleImmediateReservation(sRes); + expTime = sRes.getFinishTime(); + } + else { + success = handleAdvanceReservation(sRes); + expTime = currentTime + commitPeriod_; + } + + if(!success) { + String userName = GridSim.getEntityName( message.getSourceID() ); + System.out.println(super.get_name() + ".handleCreateReservation():" + + " Reservation #" + reservation.getID() + " from " + + userName + " user requires " + reservation.getNumPE() + + " PEs from " + startTime + " to " + (startTime + duration)); + System.out.println("--> The resource could not handle the reservation."); + + reservation.setStatus(Reservation.STATUS_FAILED); + response.setErrorCode(ARMessage.EC_OPERATION_FAILURE); + sendARMessage(response); + return; + } + + // if the expiration time is greater than the start time of the + // reservation, then set the expiration time as the start time + if(expTime > startTime) { + expTime = startTime; + } + + // if the start time of the reservation is equals to the current + // time, meaning that it is an immediate reservation, then start + // the reservation straight away. Therefore, sets the status to + // committed and sends an internal event to start the reservation + if(currentTime == startTime) { + sRes.setStatus(Reservation.STATUS_COMMITTED); + super.sendInternalEvent(GridSimTags.SCHEDULE_NOW, + CBParallelSpaceShared.UPDATE_SCHEDULE_TAG); + } + else { + sRes.setStatus(Reservation.STATUS_NOT_COMMITTED); + } + + sRes.setExpiryTime(expTime); + + // add the reservation into the reservation table and sends the + // response message to the requester + reservTable_.put(new Integer(sRes.getID()), sRes); + sendARMessage(response); + + // then send this into itself to check for expired reservations + super.sendInternalEvent(expTime - currentTime, + EXPIRY_TIME); + + //-------------- FOR DEBUGGING PURPOSES ONLY -------------- + + // Informs the listeners about the reservation that has been created + GridSim.notifyListeners(this.get_id(), AllocationAction.ITEM_SCHEDULED, + true, sRes); + } + + /** + * Handles a commit reservation request. + * @param message the advance reservation message received + */ + public void handleCommitReservation(ARMessage message) { + + // gets the reservation id of the message + int reservationId = message.getReservationID(); + SSReservation sRes = null; + + // creates a response message to be sent to the requester + ARMessage response = message.createResponse(); + boolean success = true; + + // Tries to find the reservation in the lists + if(reservTable_.containsKey(reservationId)) { + sRes = reservTable_.get(reservationId); + } + else if(expiryTable_.containsKey(reservationId)) { + sRes = expiryTable_.get(reservationId); + switch(sRes.getStatus()) { + case Reservation.STATUS_CANCELLED: + System.out.println(super.get_name() + ".handleCommitReservation()" + + " Reservation # " + reservationId + + " cannot be committed because it has" + + " previously been cancelled by the allocation policy."); + break; + case Reservation.STATUS_FINISHED: + System.out.println(super.get_name() + ".handleCommitReservation()" + + " Reservation # " + reservationId + + " cannot be committed because it has finished."); + break; + default: + System.out.println(super.get_name() + ".handleCommitReservation()" + + " Reservation # " + reservationId + + " cannot be committed because it is in the expiry list."); + break; + } + success = false; + } + else { + System.out.println(super.get_name() + ".handleCommitReservation() " + + "Reservation # " + reservationId + " cannot be committed "+ + "because the allocation policy could not find it."); + success = false; + } + + // if there was no success, then sets the error code to failure and + // sends the message back to the requester + if(!success) { + response.setErrorCode(ARMessage.EC_OPERATION_FAILURE); + sendARMessage(response); + return; + } + + // sets the reservation to committed if it has not been set before + if(sRes.getStatus() == Reservation.STATUS_NOT_COMMITTED) { + sRes.setStatus(Reservation.STATUS_COMMITTED); + + // then send this into itself to start the reservation + super.sendInternalEvent(sRes.getStartTime() - GridSim.clock(), + CBParallelSpaceShared.UPDATE_SCHEDULE_TAG); + } + + // sends the response message with no error + sendARMessage(response); + + //-------------- FOR DEBUGGING PURPOSES ONLY -------------- + + GridSim.notifyListeners(this.get_id(), + AllocationAction.ITEM_STATUS_CHANGED, true, sRes); + + //---------------------------------------------------------- + } + + /** + * Handles a modify reservation request<br> + * (NOTE: <b>NOT SUPPORTED YET</b>). + * @param message the advance reservation message received. + */ + public void handleModifyReservation(ARMessage message) { + System.out.println(super.get_name() + + ".handleModifyReservation(): not supported at the moment."); + } + + /** + * Handles a cancel reservation request<br> + * (NOTE: <b>NOT SUPPORTED YET</b>). + * @param message the advance reservation message received. + */ + public void handleCancelReservation(ARMessage message) { + System.out.println(super.get_name() + + ".handleCancelReservation(): not supported at the moment."); + } + + /** + * Handles a query free time request. + * @param message the advance reservation message received. + */ + public void handleQueryAvailability(ARMessage message) { + // gets the reservation id of the message + Reservation reservation = message.getReservation(); + + // creates a response message to be sent to the requester + ARMessage response = message.createResponse(); + + // gets the start time and finish time the user is interested in + double startTime = reservation.getStartTime(); + int duration = reservation.getDurationTime(); + + // gets the availability information from the availability profile + AvailabilityInfo availability = getAvailabilityInfo(startTime, duration); + + // sets the options as the availability over the requested period + response.getReservation().setReservationOptions(availability); + + // Sends the response back to the user + sendARMessage(response); + } + + /** + * Handles a query reservation request. + * @param message the advance reservation message received. + */ + public void handleQueryReservation(ARMessage message) { + + // gets the reservation id of the message + int reservationId = message.getReservationID(); + + // creates a response message to be sent to the requester + ARMessage response = message.createResponse(); + + // Tries to find the reservation in the lists + if(!reservTable_.containsKey(reservationId) + && !expiryTable_.containsKey(reservationId) ) { + System.out.println(super.get_name() + ".handleQueryReservation()" + + " Error querying the status of reservation # " + reservationId + + " because Grid Resource #" + super.resId_ + + " could not find it."); + response.setErrorCode(ARMessage.EC_OPERATION_FAILURE); + } + + // Just sends the message because the reply has a reference to + // the reservation object, which contains the status of the reservation + sendARMessage(response); + } + + /** + * Process and event sent to this entity + * @param ev the event to be handled + */ + public void processOtherEvent(Sim_event ev) { + + // handle an internal event + double currentTime = GridSim.clock(); + + if(ev.get_src() == myId_) { + switch(ev.get_tag()) { + + // checks the expiry time for a given gridlet + case EXPIRY_TIME: + if(currentTime > lastCheckExpiryTime_) { + checkExpiryTime(); + } + lastCheckExpiryTime_ = currentTime; + break; + + default: + super.processOtherEvent(ev); + break; + } + } + else + super.processOtherEvent(ev); + } + + // --------------------- PROTECTED METHODS ----------------------- + + /** + * This method is called to update the schedule. It removes completed + * gridlets and return them to the users and verifies whether there are + * gridlets in the waiting list that should start execution. It also + * removes old entries from the availability profile. + */ + protected void updateSchedule() { + + int itemsFinished = 0; + double currentTime = GridSim.clock(); + int itemsStarted = 0; + + // finishes the advance reservations first + itemsFinished = finishReservation(currentTime); + + // then finishes the Gridlets whose start time is smaller + // or equals to the current simulation time + itemsFinished += super.finishRunningGridlets(currentTime); + + // remove past entries from the availability profile + MPProfileEntry currentStatus = profile_.removePastEntries(currentTime); + if(currentStatus != null) { + profile_.setCurrentStatus(currentStatus); + resource_.resetFreePERanges(currentStatus.getPERanges()); + } + + // starts the advance reservations + itemsStarted = startReservation(currentTime); + + // Start the execution of Gridlets that are queued and whose + // potential start execution time is smaller than current time + itemsStarted += super.startQueuedGridlets(currentTime); + + //---------------- USED FOR DEBUGGING PURPOSES ONLY -------------------- + + // If a gridlet has started execution or one has finished, + // then inform the listeners + if(itemsStarted > 0 || itemsFinished > 0){ + GridSim.notifyListeners(this.get_id(), AllocationAction.SCHEDULE_CHANGED, true); + } + } + + /** + * This method is called to finish a reservation and consequently update + * the availability profile. + * @param refTime the time reference to check what reservations should + * be finished. All reservations whose finish time is smaller or + * equals to refTime will be completed + * @return the number of reservations completed + */ + protected int finishReservation(double refTime) { + int reservationFinished = 0; + + Iterator<SSReservation> iterRes = reservTable_.values().iterator(); + while(iterRes.hasNext()) { + SSReservation sRes = iterRes.next(); + if(sRes.getFinishTime() <= refTime) { + // Finish the reservation and include ranges in the + // list of ranges to be released + sRes.setStatus(Reservation.STATUS_FINISHED); + reservationFinished++; + iterRes.remove(); + expiryTable_.put(sRes.getID(), sRes); + } + } + + if(reservationFinished > 0) { + + //------------- USED FOR DEBUGGING PURPOSES ONLY ------------------ + + // If a gridlet has started execution or one has finished, + // then inform the listeners + GridSim.notifyListeners(this.get_id(), AllocationAction.SCHEDULE_CHANGED, true); + + //----------------------------------------------------------------- + } + + return reservationFinished; + } + + /** + * This method is called to start a reservation and consequently update + * the availability profile. + * @refTime the reservations whose start time is smaller + * or equals to refTime will be started + */ + protected int startReservation(double refTime) { + LinkedList<SSReservation> startedReservations = new LinkedList<SSReservation>(); + int numStartedRes = 0; + + Iterator<SSReservation> iterRes = reservTable_.values().iterator(); + while(iterRes.hasNext()) { + SSReservation sRes = iterRes.next(); + + if(sRes.getStartTime() <= refTime && + sRes.getStatus() == Reservation.STATUS_COMMITTED) { + + // Start the reservation and update the ranges of + // PEs currently available + sRes.setStatus(Reservation.STATUS_IN_PROGRESS); + + startedReservations.add(sRes); + + super.sendInternalEvent(sRes.getFinishTime()-refTime, + CBParallelSpaceShared.UPDATE_SCHEDULE_TAG); + + numStartedRes++; + } + } + return numStartedRes; + } + + /** + * This method returns a list that corresponds to the free time slots + * in the scheduling queue managed by this scheduler or + * resource allocation policy. + * + * @param startTime the start time in which the requester is interested. + * @param duration the duration in which the requester is interested. + * @return the list of free time slots. The list is actually a list of + * entries that correspond to the availability profile between the times + * specified by the requester. + */ + protected AvailabilityInfo getAvailabilityInfo(double startTime, int duration) { + + AvailabilityInfo list = new AvailabilityInfo(); + int anchorIndex = -1; + double currentTime = GridSim.clock(); + + // if the user specified the start time as 0, it means that the + // user is interested to know the availability starting from the + // current time, or the time when the resource received this request + if(startTime == 0) { + startTime = currentTime; + } + + list.setStartTime(startTime); + + // calculate the reservation's finish time + double finishTime = startTime + duration; + list.setFinishTime(finishTime); + + // a pointer to the anchor entry (described above) + MPProfileEntry anchorEntry = null; + int length = profile_.size(); + AvailabilityInfoEntry firstEntry = null; + + anchorEntry = (startTime <= currentTime) ? null : + profile_.getPrecedingEntry(startTime); + + // if the entry is null, then it means that the reservation is + // before the first entry of the profile, so the intersection list + // has to start with the ranges of PEs currently available + if (anchorEntry == null) { + PERangeList peList = (resource_.getFreePERanges() == null) ? + new PERangeList() : resource_.getFreePERanges().clone(); + firstEntry = + new AvailabilityInfoEntry(startTime, peList); + } + else { + PERangeList newList = anchorEntry.getPERanges(); + newList = (newList != null) ? newList.clone() : new PERangeList(); + firstEntry = new AvailabilityInfoEntry(startTime, newList); + anchorIndex = profile_.indexOf(anchorEntry); + } + + list.add(firstEntry); + AvailabilityInfoEntry previousEntry = firstEntry; + + // Iterates the availability profile and adds all the entries + // whose times are between start and finish time in the list + // to be returned. It removes repeated entries. + for(int i=anchorIndex+1; i<length; i++) { + MPProfileEntry nextEntry = profile_.get(i); + if(nextEntry.getTime() <= startTime) + continue; + if(nextEntry.getTime() > finishTime){ + break; + } + else { + PERangeList peList = nextEntry.getPERanges(); + peList = (peList != null) ? peList.clone() : new PERangeList(); + + if( !previousEntry.getAvailRanges().equals(peList)) { + AvailabilityInfoEntry tsEntry = + new AvailabilityInfoEntry(nextEntry.getTime(), peList); + list.add(tsEntry); + previousEntry = tsEntry; + } + } + } + + return list; + } + + /** + * This method returns a list that corresponds to the free time slots + * in the scheduling queue managed by this scheduler or + * resource allocation policy. This returns the resources available + * for a given partition. + * @param queueId the id of the partition whose availability is to be queried. + * @param startTime the start time in which the requester is interested. + * @param duration the duration in which the requester is interested. + * @return the list of free time slots. The list is actually a list of + * entries that correspond to the availability profile between the times + * specified by the requester. + */ + protected AvailabilityInfo getAvailabilityInfo(int queueId, + double startTime, int duration) { + + AvailabilityInfo list = new AvailabilityInfo(); + int anchorIndex = -1; + double currentTime = GridSim.clock(); + QueuePartition partition = profile_.getPartition(queueId); + + // if the user specified the start time as 0, it means that the + // user is interested to know the availability starting from the + // current time, or the time when the resource received this request + if(startTime == 0) { + startTime = currentTime; + } + + list.setStartTime(startTime); + + // calculate the reservation's finish time + double finishTime = startTime + duration; + list.setFinishTime(finishTime); + + // a pointer to the anchor entry (described above) + MPProfileEntry anchorEntry = null; + int length = profile_.size(); + AvailabilityInfoEntry firstEntry = null; + + anchorEntry = (startTime <= currentTime) ? null : + profile_.getPrecedingEntry(startTime); + + // if the entry is null, then it means that the reservation is + // before the first entry of the profile, so the intersection list + // has to start with the ranges of PEs currently available + if (anchorEntry == null) { + PERangeList peList = (partition.getIdlePERanges() == null) ? + new PERangeList() : partition.getIdlePERanges().clone(); + firstEntry = + new AvailabilityInfoEntry(startTime, peList); + } + else { + PERangeList newList = anchorEntry.getPERanges(queueId); + newList = (newList != null) ? newList.clone() : new PERangeList(); + firstEntry = new AvailabilityInfoEntry(startTime, newList); + anchorIndex = profile_.indexOf(anchorEntry); + } + + list.add(firstEntry); + AvailabilityInfoEntry previousEntry = firstEntry; + + // Iterates the availability profile and adds all the entries + // whose times are between start and finish time in the list + // to be returned. It removes repeated entries. + for(int i=anchorIndex+1; i<length; i++) { + MPProfileEntry nextEntry = profile_.get(i); + if(nextEntry.getTime() <= startTime) + continue; + if(nextEntry.getTime() > finishTime){ + break; + } + else { + PERangeList peList = nextEntry.getPERanges(queueId); + peList = (peList != null) ? peList.clone() : new PERangeList(); + + if( !previousEntry.getAvailRanges().equals(peList)) { + AvailabilityInfoEntry tsEntry = + new AvailabilityInfoEntry(nextEntry.getTime(), peList); + list.add(tsEntry); + previousEntry = tsEntry; + } + } + } + + return list; + } + + /** + * Sends a reservation message. + * @param message the message to be sent + */ + protected void sendARMessage(ARMessage message) { + // send message to the destination + super.sim_schedule(super.outputPort_, GridSimTags.SCHEDULE_NOW, + message.getMessageTyp... [truncated message content] |