use of net.jnellis.binpack.LinearBinPacker in project plugin-prov by ligoj.
the class ProvBudgetResource method pack.
private double pack(final ProvBudget budget, final Map<Double, AbstractQuoteVm<?>> packToQr, final Map<AbstractQuoteVm<?>, FloatingPrice<?>> prices, final List<ProvQuoteInstance> validatedQi, final List<ProvQuoteDatabase> validatedQb, final List<ProvQuoteContainer> validatedQc, final List<ProvQuoteFunction> validatedQf, final Map<ResourceType, Map<Integer, FloatingCost>> costs) {
if (packToQr.isEmpty()) {
return 0d;
}
// At least one initial cost is implied, use bin packing strategy
final var packStart = System.currentTimeMillis();
final var packer = new LinearBinPacker();
final var bins = packer.packAll(packToQr.entrySet().stream().sorted(priceOrder(prices)).map(Entry::getKey).collect(Collectors.toList()), new ArrayList<>(List.of(new LinearBin(budget.getRemainingBudget()))), new ArrayList<>(List.of(Double.MAX_VALUE)));
final var bin = bins.get(0);
bin.getPieces().stream().map(packToQr::get).forEach(i -> {
if (i.getResourceType() == ResourceType.INSTANCE) {
validatedQi.add((ProvQuoteInstance) i);
} else if (i.getResourceType() == ResourceType.DATABASE) {
validatedQb.add((ProvQuoteDatabase) i);
} else if (i.getResourceType() == ResourceType.CONTAINER) {
validatedQc.add((ProvQuoteContainer) i);
} else {
validatedQf.add((ProvQuoteFunction) i);
}
});
logLean(b -> {
log.info("Packing result: {}", b.get(0).getPieces().stream().map(packToQr::get).map(i -> i.getName() + CODE + i.getPrice().getCode() + ")").collect(Collectors.toList()));
log.info("Packing result: {}", b);
}, bins);
logPack(packStart, packToQr, budget);
var init = bin.getTotal();
if (bins.size() > 1) {
// Extra bin needs to make a new pass
budget.setRemainingBudget(FloatingCost.round(budget.getRemainingBudget() - bin.getTotal()));
final List<ProvQuoteInstance> subQi = newSubPack(packToQr, bins, ResourceType.INSTANCE);
final List<ProvQuoteDatabase> subQb = newSubPack(packToQr, bins, ResourceType.DATABASE);
final List<ProvQuoteContainer> subQc = newSubPack(packToQr, bins, ResourceType.CONTAINER);
final List<ProvQuoteFunction> subQf = newSubPack(packToQr, bins, ResourceType.FUNCTION);
init += leanRecursive(budget, subQi, subQb, subQc, subQf, costs);
} else {
// Pack is completed
}
return init;
}
Aggregations