package edu.usc.enl.dynamicmeasurement.algorithms.tasks.multitask.singleswitch.resourceallocation.dream.distributor; import edu.usc.enl.dynamicmeasurement.algorithms.tasks.multitask.singleswitch.resourceallocation.AllocationTaskView; import edu.usc.enl.dynamicmeasurement.algorithms.tasks.multitask.singleswitch.resourceallocation.dream.DreamTaskRecord; import edu.usc.enl.dynamicmeasurement.algorithms.tasks.multitask.singleswitch.resourceallocation.dream.DummyTaskRecord; import edu.usc.enl.dynamicmeasurement.algorithms.tasks.multitask.singleswitch.resourceallocation.dream.ThresholdGuaranteeAlgorithm2; import edu.usc.enl.dynamicmeasurement.util.ControlledBufferWriter; import edu.usc.enl.dynamicmeasurement.util.IntegerWrapper; import java.util.Collections; import java.util.LinkedList; import java.util.List; /** * Created with IntelliJ IDEA. * User: masoud * Date: 9/24/13 * Time: 9:13 PM */ public class WeightedResourceDistributor extends AbstractResourceDistributor { public WeightedResourceDistributor(ThresholdGuaranteeAlgorithm2 algorithm) { super(algorithm); } public void distribute(List<DreamTaskRecord> richTasks, List<DreamTaskRecord> poorTasks) { //I want to take resources from those that can give more IntegerWrapper sumGive = new IntegerWrapper(0); for (DreamTaskRecord richTask : richTasks) { sumGive.add(richTask.getReductionStep2()); richTask.setTempToGiveGet(richTask.getReductionStep2()); } IntegerWrapper sumGet = new IntegerWrapper(0); for (DreamTaskRecord poorTask : poorTasks) { sumGet.add(poorTask.getAdditionStep2()); poorTask.setTempToGiveGet(poorTask.getAdditionStep2()); } DummyTaskRecord dummyTaskRecord = algorithm.getDummyTaskRecord(); if (dummyTaskRecord.isRich()) { LinkedList<DreamTaskRecord> richTasks1 = new LinkedList<>(); richTasks1.add(dummyTaskRecord); IntegerWrapper dummyGive = new IntegerWrapper(dummyTaskRecord.getTempToGiveGet()); if (poorTasks.size() > 0) { distribute(richTasks1, poorTasks, dummyGive, sumGet); } if (dummyGive.getValue() > 0) { if (sumGet.getValue() > 0) { richTasks1.clear(); richTasks1.add(dummyTaskRecord); flush(poorTasks, sumGet, richTasks1); } else { //giveToAll(dummyGive, algorithm); } } } if (richTasks.size() > 0 && poorTasks.size() > 0 && sumGet.getValue() > 0) { distribute(richTasks, poorTasks, sumGive, sumGet); if (sumGet.getValue() > 0 && sumGive.getValue() > 0) { flush(poorTasks, sumGet, richTasks); } } } protected void flush(List<DreamTaskRecord> poorTasks, IntegerWrapper sumGet2, List<DreamTaskRecord> richTasks) { //flush dummy resource ControlledBufferWriter logWriter = algorithm.getLogWriter(); Collections.sort(richTasks); Collections.sort(poorTasks, Collections.reverseOrder()); for (DreamTaskRecord richTaskRecord : richTasks) { if (richTaskRecord.getTempToGiveGet() > 0) { int i = 0; int toGive = richTaskRecord.getTempToGiveGet(); while (toGive > 0 && sumGet2.getValue() > 0) { if (i >= poorTasks.size()) { System.err.println("Check it sumget>0 but no poor in need?"); } DreamTaskRecord poorTaskRecord = poorTasks.get(i++); int toGet = poorTaskRecord.getTempToGiveGet(); if (toGet > 0) { int transfer = Math.min(toGet, toGive); AllocationTaskView richTask = richTaskRecord.getTask(); AllocationTaskView poorTask = poorTaskRecord.getTask(); logWriter.println(richTask + "-!>" + transfer + "-!>" + poorTask); poorTask.setResourceShare(poorTask.getResourceShare() + transfer); toGive -= transfer; sumGet2.add(-transfer); poorTaskRecord.setTempToGiveGet(toGet - transfer); richTask.setResourceShare(richTask.getResourceShare() - transfer); } } richTaskRecord.setTempToGiveGet(toGive); } } } void distribute(List<DreamTaskRecord> richTasks, List<DreamTaskRecord> poorTasks, IntegerWrapper sumGive, IntegerWrapper sumGet) { int originalSumGet = sumGet.getValue(); int originalSumGive = sumGive.getValue(); ControlledBufferWriter logWriter = algorithm.getLogWriter(); if (sumGet.getValue() > sumGive.getValue()) { //distribute among poors based on weights //added value is sumGive*get/sumGet for (DreamTaskRecord poorTaskRecord : poorTasks) { int toGet = (int) (1.0 * poorTaskRecord.getTempToGiveGet() / originalSumGet * originalSumGive); AllocationTaskView poorTask = poorTaskRecord.getTask(); while (true) { if (richTasks.size() == 0) { System.err.println("Rich task not found"); break; } DreamTaskRecord richTaskRecord = richTasks.remove(0); AllocationTaskView richTask = richTaskRecord.getTask(); int toGive = richTaskRecord.getTempToGiveGet(); int transfer = Math.min(toGet, toGive); logWriter.println(richTask + "-p>" + transfer + "->" + poorTask); richTask.setResourceShare(richTask.getResourceShare() - transfer); poorTask.setResourceShare(poorTask.getResourceShare() + transfer); sumGet.add(-transfer); sumGive.add(-transfer); toGive -= transfer; toGet -= transfer; richTaskRecord.setTempToGiveGet(toGive); poorTaskRecord.setTempToGiveGet(poorTaskRecord.getTempToGiveGet() - transfer);//need ot update this for later flush if (toGive > 0) { //rich should stay for next poor richTasks.add(richTaskRecord); } if (toGet == 0) { //this poor is finished break; } } } } else { for (DreamTaskRecord richTaskRecord : richTasks) { int toGive = (int) (1.0 * richTaskRecord.getTempToGiveGet() / originalSumGive * originalSumGet); AllocationTaskView richTask = richTaskRecord.getTask(); while (true) { if (poorTasks.size() == 0) { System.err.println("Poor task not found"); break; } DreamTaskRecord poorTaskRecord = poorTasks.remove(0); AllocationTaskView poorTask = poorTaskRecord.getTask(); int toGet = poorTaskRecord.getTempToGiveGet(); int transfer = Math.min(toGet, toGive); logWriter.println(richTask + "-r>" + transfer + "->" + poorTask); richTask.setResourceShare(richTask.getResourceShare() - transfer); poorTask.setResourceShare(poorTask.getResourceShare() + transfer); sumGet.add(-transfer); sumGive.add(-transfer); toGet -= transfer; toGive -= transfer; poorTaskRecord.setTempToGiveGet(toGet); richTaskRecord.setTempToGiveGet(richTaskRecord.getTempToGiveGet() - transfer);//need for flush as it may not be used up because of int if (toGet > 0) {//this poor should stay poorTasks.add(poorTaskRecord); } if (toGive == 0) { break; //this rich is finished } } } } } }