From 3f862a7c9b8338d0aad7effe1b17e6f79f298acc Mon Sep 17 00:00:00 2001
From: Stefan Derkits <stefan@derkits.at>
Date: Tue, 21 May 2013 22:43:19 +0200
Subject: [PATCH] write end Events when deploying app, fix consumption function

---
 .../lsdc/management/MachineManager.java       |  46 ++++---
 .../tuwien/lsdc/sched/AbstractScheduler.java  | 104 ++++++++--------
 src/at/ac/tuwien/lsdc/sched/SchedulerA.java   | 116 ++++++++++--------
 3 files changed, 150 insertions(+), 116 deletions(-)

diff --git a/src/at/ac/tuwien/lsdc/management/MachineManager.java b/src/at/ac/tuwien/lsdc/management/MachineManager.java
index cbdea40..7942378 100644
--- a/src/at/ac/tuwien/lsdc/management/MachineManager.java
+++ b/src/at/ac/tuwien/lsdc/management/MachineManager.java
@@ -8,28 +8,27 @@ import at.ac.tuwien.lsdc.exception.VMsRunningException;
 import at.ac.tuwien.lsdc.types.PhysicalMachine;
 
 /**
- * This class is responsible to start and stop PMs & VMs
- * also it will be used to put an application on a VM
- * move an application and get utilization data
+ * This class is responsible to start and stop PMs & VMs also it will be used to
+ * put an application on a VM move an application and get utilization data
  * 
  */
 public class MachineManager {
 
 	private HashMap<Integer, PhysicalMachine> PMs = new HashMap<Integer, PhysicalMachine>();
-	
+
 	private int numPMs;
-	
+
 	public MachineManager(int numPMs) {
 		this.numPMs = numPMs;
 	}
-	
-	
+
 	/**
 	 * Start a physical machine
+	 * 
 	 * @return the PM that was started, null if all machines already running
 	 */
 	public PhysicalMachine startPhysicalMachine() {
-		if(PMs.size() < numPMs) {
+		if (PMs.size() < numPMs) {
 			PhysicalMachine pm = new PhysicalMachine();
 			PMs.put(pm.getId(), pm);
 			pm.start();
@@ -37,37 +36,43 @@ public class MachineManager {
 		}
 		return null;
 	}
-	
+
 	/**
 	 * Stops a physical machine with the given id
-	 * @param id the id of the PM to stop
-	 * @throws VMsRunningException is thrown when there are still VMs running on this PM
+	 * 
+	 * @param id
+	 *            the id of the PM to stop
+	 * @throws VMsRunningException
+	 *             is thrown when there are still VMs running on this PM
 	 */
 	public void stopPhysicalMachine(int id) throws VMsRunningException {
-		if(PMs.containsKey(id)) {
+		if (PMs.containsKey(id)) {
 			PMs.get(id).stop();
 			PMs.remove(id);
 		}
 	}
-	
+
 	/**
 	 * Returns all running physical machines
+	 * 
 	 * @return the currently active PMs
 	 */
-	public Collection<PhysicalMachine> getPMs () {
+	public Collection<PhysicalMachine> getPMs() {
 		return PMs.values();
 	}
-	
+
 	/**
 	 * Returns the maximum number of available physical machines
+	 * 
 	 * @return the maximum number of PMs
 	 */
 	public int getMaxPMs() {
 		return numPMs;
 	}
-	
+
 	/**
 	 * Get the total size on all PMs
+	 * 
 	 * @return the total size on all PMs
 	 */
 	public int getTotalSize() {
@@ -78,9 +83,10 @@ public class MachineManager {
 		}
 		return totalSize;
 	}
-	
+
 	/**
 	 * Get the total Ram usage of all PMs
+	 * 
 	 * @return the total usage of Ram
 	 */
 	public int getTotalRam() {
@@ -91,9 +97,10 @@ public class MachineManager {
 		}
 		return totalRam;
 	}
-	
+
 	/**
 	 * Get the total Cpu usage of all PMs
+	 * 
 	 * @return the total usage of Cpu power
 	 */
 	public int getTotalCpu() {
@@ -107,6 +114,7 @@ public class MachineManager {
 
 	/**
 	 * Gets the total power consumption summed up from each PM
+	 * 
 	 * @return the total power consumption
 	 */
 	public double getCurrentConsumption() {
@@ -120,6 +128,7 @@ public class MachineManager {
 
 	/**
 	 * Gets the number of currently running PMs
+	 * 
 	 * @return the number of currently running PMs
 	 */
 	public int countCurrentlyRunningPMs() {
@@ -133,6 +142,7 @@ public class MachineManager {
 
 	/**
 	 * Gets the number of currently running VMs
+	 * 
 	 * @return the number of currently running VMs
 	 */
 	public int countCurrentlyRunningVMs() {
diff --git a/src/at/ac/tuwien/lsdc/sched/AbstractScheduler.java b/src/at/ac/tuwien/lsdc/sched/AbstractScheduler.java
index 6b6dc20..2409d47 100644
--- a/src/at/ac/tuwien/lsdc/sched/AbstractScheduler.java
+++ b/src/at/ac/tuwien/lsdc/sched/AbstractScheduler.java
@@ -40,10 +40,9 @@ public abstract class AbstractScheduler {
 	protected CSVLogger logger;
 	protected VMType vmType;
 
-
 	// this map saves the following Type of Events:
 	// start of an Application, end of an Application
-	// (start outSourced, end outSourced, start inSourced, end inSourced)	
+	// (start outSourced, end outSourced, start inSourced, end inSourced)
 	protected SortedMap<Long, LinkedList<SchedulerEvent>> eventMap;
 
 	// Scheduler has an internal Time "Abstraction"
@@ -55,7 +54,6 @@ public abstract class AbstractScheduler {
 	// it is updated with every added "EndEvent"
 	protected long endTime;
 
-	
 	public AbstractScheduler(int numPMs, int numCloudPartners,
 			File schedulerLog, SchedulerType schedulerType,
 			ScenarioType scenario) throws IOException {
@@ -66,11 +64,12 @@ public abstract class AbstractScheduler {
 		this.eventMap = new TreeMap<Long, LinkedList<SchedulerEvent>>();
 		this.logger = new CSVLogger(schedulerLog);
 		initCloudPartners(numCloudPartners);
-		
-	//	Using federation ?	
-	//	federation = new Federation(numCloudPartners);
+
+		// Using federation ?
+		// federation = new Federation(numCloudPartners);
 	}
 
+	// intialize cloudpartners for federation
 	private void initCloudPartners(int numCloudPartners) {
 		for (int i = 0; i < numCloudPartners; i++) {
 			// initialize a cloudpartner
@@ -87,10 +86,9 @@ public abstract class AbstractScheduler {
 	public ScenarioData initAndStart(LinkedList<Application> apps) {
 		for (Application app : apps) {
 			insertStartEvent(app.getTimestamp(), app);
-			insertStopEvent(app.getTimestamp() + app.getDuration(), app);
 		}
-		
-		log.info("event map = "+ eventMap.size());
+
+		log.info("event map = " + eventMap.size());
 		startScheduling();
 		try {
 			logger.close();
@@ -99,17 +97,22 @@ public abstract class AbstractScheduler {
 		}
 		// TODO make end logging work
 		return null;
-//		return doEndLogging();
+		// return doEndLogging();
 	}
-	
+
 	/**
-	 * Insert a start event into the map, at timestamp when the application should start
-	 * @param timestamp the timestamp when the application should start
-	 * @param app the application to start
+	 * Insert a start event into the map, at timestamp when the application
+	 * should start
+	 *
+	 * @param timestamp
+	 *            the timestamp when the application should start
+	 * @param app
+	 *            the application to start
 	 */
-	private void insertStartEvent(long timestamp, Application app) {
-		SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.startApplication, app);
-		if(!eventMap.containsKey(timestamp)) {
+	protected void insertStartEvent(long timestamp, Application app) {
+		SchedulerEvent evt = new SchedulerEvent(timestamp,
+				EventType.startApplication, app);
+		if (!eventMap.containsKey(timestamp)) {
 			LinkedList<SchedulerEvent> list = new LinkedList<SchedulerEvent>();
 			list.add(evt);
 			eventMap.put(timestamp, list);
@@ -118,15 +121,20 @@ public abstract class AbstractScheduler {
 			list.add(evt);
 		}
 	}
-	
+
 	/**
-	 * Insert a stop event into the map, at timestamp when the application should stop
-	 * @param timestamp the timestamp when the application should stop
-	 * @param app the application to stop
+	 * Insert a stop event into the map, at timestamp when the application
+	 * should stop
+	 *
+	 * @param timestamp
+	 *            the timestamp when the application should stop
+	 * @param app
+	 *            the application to stop
 	 */
-	private void insertStopEvent(long timestamp, Application app) {
-		SchedulerEvent evt = new SchedulerEvent(timestamp, EventType.endApplication, app);
-		if(!eventMap.containsKey(timestamp)) {
+	protected void insertStopEvent(long timestamp, Application app) {
+		SchedulerEvent evt = new SchedulerEvent(timestamp,
+				EventType.endApplication, app);
+		if (!eventMap.containsKey(timestamp)) {
 			LinkedList<SchedulerEvent> list = new LinkedList<SchedulerEvent>();
 			list.add(evt);
 			eventMap.put(timestamp, list);
@@ -134,58 +142,54 @@ public abstract class AbstractScheduler {
 			LinkedList<SchedulerEvent> list = eventMap.get(timestamp);
 			list.add(evt);
 		}
-		if(endTime < timestamp) {
+		if (endTime < timestamp) {
 			endTime = timestamp;
 		}
 	}
 
 	/**
-	 * Start the actual scheduling algorithm. 
-	 * Each scheduler will implement the method handleEvents differently
+	 * Start the actual scheduling algorithm. Each scheduler will implement the
+	 * method handleEvents differently
 	 */
 	protected void startScheduling() {
 		while (true) {
-			if(eventMap.containsKey(currTime)) {
+			if (eventMap.containsKey(currTime)) {
 				LinkedList<SchedulerEvent> events = eventMap.get(currTime);
-				log.info(events.size()+" events at timestamp "+currTime);
+				log.info(events.size() + " events at timestamp " + currTime);
 				handleEvents(events);
 				doStateLogging();
 			}
-			//advance Time to next Event
+			// advance Time to next Event
 			currTime++;
 
 			if (currTime == endTime) {
 				// reached last Event, Scheduler will shut down
-				log.info("Last event reached at time "+currTime);
+				log.info("Last event reached at time " + currTime);
 				break;
 			}
 		}
 	}
 
 	/**
-	 * this method is where the Scheduling Algorithm resides
-	 * it reads the Events (start & stop of applications)
-	 * @param events the events to be read and used by the scheduler
+	 * this method is where the Scheduling Algorithm resides it reads the Events
+	 * (start & stop of applications)
+	 *
+	 * @param events
+	 *            the events to be read and used by the scheduler
 	 */
 	protected abstract void handleEvents(LinkedList<SchedulerEvent> events);
 
 	/**
-	 * Does the logging for each timestamp.
-	 * It uses the CSVLogger to write directly to the specific
-	 * scheduler/scenario csv file
+	 * Does the logging for each timestamp. It uses the CSVLogger to write
+	 * directly to the specific scheduler/scenario csv file
 	 */
 	protected void doStateLogging() {
-		SchedulerData data = new SchedulerData(
-								currTime, 
-								manager.getTotalRam(), 
-								manager.getTotalCpu(), 
-								manager.getTotalSize(),
-								manager.countCurrentlyRunningPMs(),
-								manager.countCurrentlyRunningVMs(),
-								manager.getCurrentConsumption(), 
-								numCurrInSourced,
-								numCurrOutSourced
-							);
+		SchedulerData data = new SchedulerData(currTime, manager.getTotalRam(),
+				manager.getTotalCpu(), manager.getTotalSize(),
+				manager.countCurrentlyRunningPMs(),
+				manager.countCurrentlyRunningVMs(),
+				manager.getCurrentConsumption(), numCurrInSourced,
+				numCurrOutSourced);
 		totalConsumption += manager.getCurrentConsumption();
 		try {
 			logger.logSchedulerData(data);
@@ -195,7 +199,9 @@ public abstract class AbstractScheduler {
 	}
 
 	/**
-	 * this creates the total summary which should be written to a CSV at the end
+	 * this creates the total summary which should be written to a CSV at the
+	 * end
+	 *
 	 * @return a ScenarioData Object that holds the values to be logged
 	 */
 	protected ScenarioData doEndLogging() {
diff --git a/src/at/ac/tuwien/lsdc/sched/SchedulerA.java b/src/at/ac/tuwien/lsdc/sched/SchedulerA.java
index 266a988..3d6a7ff 100644
--- a/src/at/ac/tuwien/lsdc/sched/SchedulerA.java
+++ b/src/at/ac/tuwien/lsdc/sched/SchedulerA.java
@@ -9,7 +9,7 @@ import java.util.List;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import edu.emory.mathcs.backport.java.util.Collections;
+import java.util.Collections;
 
 import at.ac.tuwien.lsdc.exception.ActiveApplicationsException;
 import at.ac.tuwien.lsdc.types.Application;
@@ -23,110 +23,128 @@ import at.ac.tuwien.lsdc.types.SortedPhysicalMachine;
 import at.ac.tuwien.lsdc.types.VirtualMachine;
 import at.ac.tuwien.lsdc.types.VirtualMachine.VMType;
 
-
 public class SchedulerA extends AbstractScheduler {
 
 	private static final Logger log = LoggerFactory.getLogger(SchedulerA.class);
-	
+
 	public SchedulerA(int numPMs, int numCloudPartners, File schedulerLog,
 			SchedulerType schedulerType, ScenarioType scenario)
 			throws IOException {
 		super(numPMs, numCloudPartners, schedulerLog, schedulerType, scenario);
-		
+
 		this.vmType = VMType.NonResizable;
 	}
 
 	@Override
 	protected void handleEvents(LinkedList<SchedulerEvent> events) {
-		
-		for(SchedulerEvent evt : events) {
-			if(evt.getType() == EventType.endApplication) {
+
+		for (SchedulerEvent evt : events) {
+			if (evt.getType() == EventType.endApplication) {
 				VirtualMachine vm = evt.getApp().getRunningOn();
 				vm.stopApplication(evt.getApp());
 				PhysicalMachine pm = vm.getRunningOn();
 				try {
 					pm.stopVirtualMachine(vm);
 				} catch (ActiveApplicationsException e) {
-					log.warn("VM "+vm.getId()+"could not be stopped, "+e.getMessage());
+					log.warn("VM " + vm.getId() + "could not be stopped, "
+							+ e.getMessage());
 				}
 			}
 		}
-		
+
 		// sorting applications by amount of resources (descending)
 		List<SortedApplication> sortedApps = sortApps(events);
-				
-		for(Iterator<SortedApplication> iter = sortedApps.iterator(); iter.hasNext(); ) {
+
+		for (Iterator<SortedApplication> iter = sortedApps.iterator(); iter
+				.hasNext();) {
 			boolean appDeployed = false;
 			Application app = iter.next().getApp();
-			
-			if(manager.getPMs().size() == 0) {
+
+			if (manager.getPMs().size() == 0) {
 				PhysicalMachine pm = manager.startPhysicalMachine();
-				boolean enoughResources = pm.checkVM(app.getSize(), app.getRam(), app.getCpu());
-				
-				if(enoughResources) {
-					pm.startVirtualMachine(app.getSize(), app.getRam(), app.getCpu(), vmType);
+				boolean enoughResources = pm.checkVM(app.getSize(),
+						app.getRam(), app.getCpu());
+
+				if (enoughResources) {
+					pm.startVirtualMachine(app.getSize(), app.getRam(),
+							app.getCpu(), vmType);
+					insertStopEvent(currTime + app.getDuration(), app);
 					appDeployed = true;
-					log.debug("Application "+app.toString()+" started on new pm "+pm.getId());
-				}
-				else {
-					log.warn("Application "+app.toString()+" cannot be run on empty pm "+pm.getId());
+					log.debug("Application " + app.toString()
+							+ " started on new pm " + pm.getId());
+				} else {
+					log.warn("Application " + app.toString()
+							+ " cannot be run on empty pm " + pm.getId());
 				}
-			}
-			else {
-				// sorting physical machines by resource utilization (descending)
+			} else {
+				// sorting physical machines by resource utilization
+				// (descending)
 				List<SortedPhysicalMachine> sortedPMs = sortPMs();
-				
-				for(Iterator<SortedPhysicalMachine> it = sortedPMs.iterator(); iter.hasNext(); ) {
+
+				for (Iterator<SortedPhysicalMachine> it = sortedPMs.iterator(); iter
+						.hasNext();) {
 					PhysicalMachine pm = it.next().getPm();
-					boolean enoughResources = pm.checkVM(app.getSize(), app.getRam(), app.getCpu());
-					
-					if(enoughResources) {
-						VirtualMachine vm = pm.startVirtualMachine(app.getSize(), app.getRam(), app.getCpu(), vmType);
+					boolean enoughResources = pm.checkVM(app.getSize(),
+							app.getRam(), app.getCpu());
+
+					if (enoughResources) {
+						VirtualMachine vm = pm.startVirtualMachine(
+								app.getSize(), app.getRam(), app.getCpu(),
+								vmType);
 						vm.startApplication(app);
+						insertStopEvent(currTime + app.getDuration(), app);
 						appDeployed = true;
-						log.debug("Application "+app.toString()+" started on new pm "+pm.getId());
+						log.debug("Application " + app.toString()
+								+ " started on new pm " + pm.getId());
 						break;
 					}
 				}
-				if(!appDeployed  &&  (manager.getPMs().size() < manager.getMaxPMs())) {
-					
+				if (!appDeployed
+						&& (manager.getPMs().size() < manager.getMaxPMs())) {
+
 					PhysicalMachine pm = manager.startPhysicalMachine();
-					boolean enoughResources = pm.checkVM(app.getSize(), app.getRam(), app.getCpu());
-					
-					if(enoughResources) {
-						VirtualMachine vm = pm.startVirtualMachine(app.getSize(), app.getRam(), app.getCpu(), vmType);
+					boolean enoughResources = pm.checkVM(app.getSize(),
+							app.getRam(), app.getCpu());
+
+					if (enoughResources) {
+						VirtualMachine vm = pm.startVirtualMachine(
+								app.getSize(), app.getRam(), app.getCpu(),
+								vmType);
 						vm.startApplication(app);
+						insertStopEvent(currTime + app.getDuration(), app);
 						appDeployed = true;
-						log.debug("Application "+app.toString()+" started on new pm "+pm.getId());
-					}
-					else {
-						log.warn("Application "+app.toString()+" cannot be run on empty pm "+pm.getId());
+						log.debug("Application " + app.toString()
+								+ " started on new pm " + pm.getId());
+					} else {
+						log.warn("Application " + app.toString()
+								+ " cannot be run on empty pm " + pm.getId());
 					}
 				}
 			}
-			if(!appDeployed) 
-				log.warn("Application "+app.toString()+" could not be deployed on any pm");
+			if (!appDeployed)
+				log.warn("Application " + app.toString()
+						+ " could not be deployed on any pm");
 		}
 	}
-	
+
 	// sorting applications by amount of resources (descending)
 	private List<SortedApplication> sortApps(LinkedList<SchedulerEvent> events) {
 		List<SortedApplication> sortedApps = new LinkedList<SortedApplication>();
-		for(SchedulerEvent evt : events) {
-			if(evt.getType() == EventType.startApplication)
+		for (SchedulerEvent evt : events) {
+			if (evt.getType() == EventType.startApplication)
 				sortedApps.add(new SortedApplication(evt.getApp()));
 		}
 		Collections.sort(sortedApps);
 		Collections.reverse(sortedApps);
 		return sortedApps;
 	}
-	
+
 	// sorting physical machines by resource utilization (descending)
 	private List<SortedPhysicalMachine> sortPMs() {
 		List<SortedPhysicalMachine> sortedPMs = new LinkedList<SortedPhysicalMachine>();
-		for(PhysicalMachine pm  : manager.getPMs())
+		for (PhysicalMachine pm : manager.getPMs())
 			sortedPMs.add(new SortedPhysicalMachine(pm));
-		
+
 		Collections.sort(sortedPMs);
 		Collections.reverse(sortedPMs);
 		return sortedPMs;
-- 
2.43.0