blob: f89b7ca0271d02c93b653482f617b97cd0d2a754 [file] [log] [blame]
/*------------------------------------------------------------------------------
-
- Copyright (c) 2015-2016 University of Padova, ITALY - Intecs SpA
- All rights reserved. This program and the accompanying materials
- are made available under the terms of the Eclipse Public License v2.0
- which accompanies this distribution, and is available at
- http://www.eclipse.org/legal/epl-v20.html
-
- Contributors:
-
- Alessandro Zovi azovi@math.unipd.it
- Stefano Puri stefano.puri@intecs.it
- Laura Baracchi laura.baracchi@intecs.it
- Nicholas Pacini nicholas.pacini@intecs.it
-
- Initial API and implementation and/or initial documentation
------------------------------------------------------------------------------*/package org.polarsys.chess.multicore.partitioning;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
/**
* The Class WorstFitBinPacker.
*/
public class WorstFitBinPacker implements BinPacker {
/** The decreasing ordering. */
private final boolean DECREASING_ORDERING = true;
// @Override
// public Map<Bin, List<Task>> pack(List<Bin> bins, List<Task> tasks) {
//
// Map<Bin, List<Task>> toReturn = new Hashtable<Bin, List<Task>> ();
// // init output
// for(Bin bin : bins)
// toReturn.put(bin, new ArrayList<Task>());
//
//
// if(tasks.size() <= bins.size()){ // trivial packing
// int i =0;
// for(Task task : tasks){
// Bin bin = bins.get(i);
// ArrayList<Task> theList = new ArrayList<Task>();
// theList.add(task);
// bin.setCapacity(bin.getCapacity()+task.computeU());
// toReturn.put(bin, theList);
// i++;
// }
// } else {// nominal case
//
// // sort the tasks by increasing/decreasing utilisation
// Object[] allTasks = tasks.toArray();
// //Arrays.sort(allTasks);
// Arrays.sort(allTasks, new Comparator<Object>() {
//
// @Override
// public int compare(Object o1, Object o2) {
// if(DECREASING_ORDERING)
// return -(((Task)o1).computeU()).compareTo(((Task)o2).computeU());
// else
// return (((Task)o1).computeU()).compareTo(((Task)o2).computeU());
// }
// });
//
// int indexEmptiestBin = 0;
// float emptiestCapacity = 0.0f;
// Object[] allBins = bins.toArray();
//
//
// for(int taskIndex = 0; taskIndex < allTasks.length; taskIndex++){
//
// Task task = (Task)allTasks[taskIndex];
// boolean found = false;
//
// Bin bin = (Bin)allBins[indexEmptiestBin];
// // try with emptiest bin
// if(bin.getCapacity() + task.computeU() <= bin.getSize())
// found = true;
// else { //try with other bins
// for(int indexCurrentBin = 0; indexCurrentBin < allBins.length; indexCurrentBin++){
// if (indexCurrentBin == indexEmptiestBin) // already visited
// continue;
// bin =(Bin)allBins[indexCurrentBin];
// if(bin.getCapacity() + task.computeU() <= bin.getSize()){
// found = true;
// break;
// }
// }
// }
//
// if(!found)
// System.out.println("PACKING FAILED");
// else {
// task.setOwner(bin);
// bin.setCapacity(bin.getCapacity()+task.computeU());
// // store to output
// List<Task> theTasks = toReturn.get(bin);
// theTasks.add(task);
// toReturn.put(bin, theTasks);
// found = true;
// // update info on emptiest bin
// emptiestCapacity = Float.MAX_VALUE;
// for(int binIndex = 0; binIndex < allBins.length; binIndex++){
// float currentCapacity = ((Bin)allBins[binIndex]).getCapacity();
// if(currentCapacity < emptiestCapacity){
// emptiestCapacity = currentCapacity;
// indexEmptiestBin = binIndex;
// }
// }
// }
// }
//
// }
// return toReturn;
// }
/* (non-Javadoc)
* @see org.polarsys.chess.multicore.partitioning.BinPacker#pack(java.util.List, java.util.List)
*/
@Override
public Map<Bin, List<Task>> pack(List<Bin> bins, List<Task> tasks) {
Map<Bin, List<Task>> toReturn = new Hashtable<Bin, List<Task>> ();
// init output
// for(Bin bin : bins)
// toReturn.put(bin, new ArrayList<Task>());
if(tasks.size() <= bins.size()){ // trivial packing
int i =0;
for(Task task : tasks){
Bin bin = bins.get(i);
ArrayList<Task> theList = new ArrayList<Task>();
theList.add(task);
bin.setCapacity(bin.getCapacity()+task.getU());
toReturn.put(bin, theList);
i++;
}
} else {// nominal case
// sort the tasks by increasing/decreasing utilization
Object[] allTasks = tasks.toArray();
//Arrays.sort(allTasks);
Arrays.sort(allTasks, new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
if(DECREASING_ORDERING)
return -(((Task)o1).getU()).compareTo(((Task)o2).getU());
else
return (((Task)o1).getU()).compareTo(((Task)o2).getU());
}
});
int indexEmptiestBin = 0;
float emptiestCapacity = 0.0f;
Object[] allBins = {new Bin(indexEmptiestBin)}; // ensure there is at least 1 bin even in case an empty list has been passed (this is the case during RUN reduction)
int indexLastBin = 0;
if(bins.size() > 0){
allBins = bins.toArray();
indexLastBin = bins.size()-1;
}
for(int taskIndex = 0; taskIndex < allTasks.length; taskIndex++){
Task task = (Task)allTasks[taskIndex];
Bin bin = (Bin)allBins[indexEmptiestBin];
// try with emptiest bin
if(bin.getCapacity() + task.getU() <= bin.getSize()){
task.setOwner(bin);
bin.setCapacity(bin.getCapacity()+task.getU());
// store to output
List<Task> theTasks = toReturn.get(bin);
if(theTasks == null) // needed because we don't initialize toReturn at the beginning, to provide input/output of variable size
theTasks = new ArrayList<Task>();
theTasks.add(task);
toReturn.put(bin, theTasks);
}
else {
//System.out.println("PARTITIONING FAILED, OPENING NEW BIN");
// open new bin
Bin newBin = new Bin(new Integer(++indexLastBin));
task.setOwner(newBin);
newBin.setCapacity(newBin.getCapacity()+task.getU());
ArrayList<Task> theList = new ArrayList<Task>();
theList.add(task);
toReturn.put(newBin, theList);
// add bin to the common array
Object[] tmpBinArray = Arrays.copyOf(allBins, allBins.length + 1);
assert(tmpBinArray.length -1 == indexLastBin);
tmpBinArray[indexLastBin] = newBin;
allBins = tmpBinArray;
}
// update info on emptiest bin
emptiestCapacity = Float.MAX_VALUE;
for(int binIndex = 0; binIndex < allBins.length; binIndex++){
float currentCapacity = ((Bin)allBins[binIndex]).getCapacity();
if(currentCapacity < emptiestCapacity){
emptiestCapacity = currentCapacity;
indexEmptiestBin = binIndex;
}
}
}
}
return toReturn;
}
}