package edu.usc.enl.dynamicmeasurement.algorithms.tasks.multitask.singleswitch.resourceallocation; import edu.usc.enl.dynamicmeasurement.algorithms.tasks.multitask.TaskEventPublisher; import edu.usc.enl.dynamicmeasurement.data.ConfigReader; import edu.usc.enl.dynamicmeasurement.model.monitorpoint.MonitorPoint; import edu.usc.enl.dynamicmeasurement.util.Util; import org.w3c.dom.Element; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; /** * Created with IntelliJ IDEA. * User: masoud * Date: 8/1/13 * Time: 12:50 PM */ public class FixedDropAlgorithm2 extends MultiTaskResourceControl { protected final double lowThreshold; protected final List<TaskRecord2> taskRecords; private final PriorityDropPolicy dropPolicy; private int resourceStep; private int freeCapacity; public FixedDropAlgorithm2(Element element, MonitorPoint monitorPoint) { taskRecords = new LinkedList<>(); Map<String, Element> properties = Util.getChildrenProperties(element, "Property"); this.lowThreshold = Double.parseDouble(properties.get("LowThreshold").getAttribute(ConfigReader.PROPERTY_VALUE)); int capacity = monitorPoint.getCapacity(); resourceStep = (int) (capacity * Double.parseDouble(properties.get("ResourceStep").getAttribute(ConfigReader.PROPERTY_VALUE))); freeCapacity = capacity; int dropEpochs = Integer.parseInt(properties.get("DropEpochs").getAttribute(ConfigReader.PROPERTY_VALUE)); dropPolicy = new PriorityDropPolicy(dropEpochs); } @Override public void allocate() { boolean notHelping = true; for (TaskRecord2 taskRecord : taskRecords) { AllocationTaskView task = taskRecord.getTask(); double accuracy = task.getAggregatedAccuracy(); if (accuracy < lowThreshold && ((TaskRecord) taskRecord).getFixedShare() < 0) { if (freeCapacity > 0) { giveShare(task); notHelping = false; } else { break; } } else { ((TaskRecord) taskRecord).setFixedShare(taskRecord.getTask().getResourceShare()); } } TaskRecord2 dropped = dropPolicy.checkForDrop(notHelping, taskRecords); if (dropped != null) { drop(dropped); } } private void giveShare(AllocationTaskView task) { int toGive = Math.min(freeCapacity, resourceStep); task.setResourceShare(task.getResourceShare() + toGive); freeCapacity -= toGive; } @Override public boolean addTask(AllocationTaskView task) { if (freeCapacity > 0) { giveShare(task); taskRecords.add(new TaskRecord(task, -taskRecords.size())); return true; } else { return false; } } @Override public void removeTask(AllocationTaskView task) { freeCapacity += task.getResourceShare(); task.setResourceShare(0); for (Iterator<TaskRecord2> iterator = taskRecords.iterator(); iterator.hasNext(); ) { TaskRecord2 taskRecord = iterator.next(); if (taskRecord.getTask().equals(task)) { iterator.remove(); break; } } } private void drop(TaskRecord2 task) { eventPublisher.publish(task.getTask().getTask(), TaskEventPublisher.EventType.Drop, this); } private class TaskRecord extends TaskRecord2 { private int fixedShare = -1; private TaskRecord(AllocationTaskView task, int dropPriority) { super(task, dropPriority); } private int getFixedShare() { return fixedShare; } private void setFixedShare(int fixedShare) { this.fixedShare = fixedShare; } } }