/* * Copyright (c) Fabien Hermenier * * This file is part of Entropy. * * Entropy is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Entropy is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Entropy. If not, see <http://www.gnu.org/licenses/>. */ package entropy.plan.choco; import java.util.ArrayList; import java.util.Collections; import java.util.List; import entropy.configuration.Configuration; import entropy.configuration.Configurations; import entropy.configuration.ManagedElementSet; import entropy.configuration.Node; import entropy.configuration.ResourcePicker; import entropy.configuration.SimpleManagedElementSet; import entropy.configuration.VirtualMachine; import entropy.configuration.VirtualMachineComparator; import entropy.plan.choco.actionModel.ActionModel; import entropy.plan.choco.actionModel.ActionModels; import entropy.plan.choco.actionModel.VirtualMachineActionModel; import entropy.plan.choco.search.ExcludedVirtualMachines; import entropy.plan.choco.search.HosterVarSelector; import entropy.plan.choco.search.NodeGroupSelector; import entropy.plan.choco.search.PureIncomingFirst; import entropy.plan.choco.search.StayFirstSelector2; import entropy.plan.choco.search.VMGroupVarSelector; /** * A placement heuristic focused on each VM. * First place the VMs, then plan the changes. * * @author Fabien Hermenier */ public class BasicPlacementHeuristic2 implements CorePlanHeuristic { private IntDomainVar totalDuration; /** * Make a new placement heuristic. * * @param globalCost the global cost of the plan */ public BasicPlacementHeuristic2(IntDomainVar globalCost) { this.totalDuration = globalCost; } /** * To compare VMs in a descending order, wrt. their memory consumption. */ private VirtualMachineComparator dsc = new VirtualMachineComparator(false, ResourcePicker.VMRc.memoryConsumption); @Override public void add(ChocoCustomRP plan) { ReconfigurationProblem rp = plan.getModel(); Configuration src = rp.getSourceConfiguration(); //Get the VMs to move ManagedElementSet<VirtualMachine> onBadNodes = new SimpleManagedElementSet<VirtualMachine>(); //Quick hack for the VMs to run. //TODO: check //onBadNodes.addAll(src.getWaitings()); for (Node n : Configurations.futureOverloadedNodes(src)) { onBadNodes.addAll(src.getRunnings(n)); } onBadNodes.addAll(src.getSleepings()); ManagedElementSet<VirtualMachine> onGoodNodes = src.getRunnings().clone(); onGoodNodes.removeAll(onBadNodes); Collections.sort(onGoodNodes, dsc); Collections.sort(onBadNodes, dsc); List<VirtualMachineActionModel> goodActions = rp.getAssociatedActions(onGoodNodes); List<VirtualMachineActionModel> badActions = rp.getAssociatedActions(onBadNodes); //System.err.println(goodActions); //System.err.println(badActions); //Desactivate cost constraint /*for (SConstraint sc : plan.getCostConstraints()) { ((Propagator) sc).setPassive(); } */ //Go for the VMgroup variable VMGroupVarSelector vmGrp = new VMGroupVarSelector(rp); rp.addGoal(new AssignVar(vmGrp, new NodeGroupSelector(rp, NodeGroupSelector.Option.bfMem))); //Now the VMs associated to group of nodes //ManagedElementSet<VirtualMachine> inGroup = new DefaultManagedElementSet<VirtualMachine>(); if (plan.getQueue().size() != 0) { ManagedElementSet<Node> overloaded = Configurations.futureOverloadedNodes(src); ManagedElementSet<Node> underloaded = src.getAllNodes().clone(); underloaded.removeAll(Configurations.futureOverloadedNodes(src)); List<ManagedElementSet<Node>> favorites = new ArrayList<ManagedElementSet<Node>>(); favorites.add(underloaded); favorites.add(overloaded); //Get the VMs to move for exclusion issue ManagedElementSet<VirtualMachine> vmsToExlude = rp.getSourceConfiguration().getAllVirtualMachines().clone(); Collections.sort(vmsToExlude, dsc); rp.addGoal(new AssignVar(new ExcludedVirtualMachines(rp, rp.getSourceConfiguration(), vmsToExlude), new StayFirstSelector2(rp, rp.getSatisfyDSlicesHeightConstraint(), StayFirstSelector2.Option.wfMem))); //VMs to run ManagedElementSet<VirtualMachine> vmsToRun = rp.getSourceConfiguration().getWaitings().clone(); vmsToRun.removeAll(rp.getFutureWaitings()); List<VirtualMachineActionModel> runActions = rp.getAssociatedActions(vmsToRun); for (ManagedElementSet<VirtualMachine> vms : rp.getVMGroups()) { ManagedElementSet<VirtualMachine> sorted = vms.clone(); Collections.sort(sorted, dsc); List<VirtualMachineActionModel> inGroupActions = rp.getAssociatedActions(sorted); HosterVarSelector selectForInGroups = new HosterVarSelector(rp, ActionModels.extractDemandingSlices(inGroupActions)); rp.addGoal(new AssignVar(selectForInGroups, new StayFirstSelector2(rp, rp.getSatisfyDSlicesHeightConstraint(), StayFirstSelector2.Option.wfMem))); //solver.addGoal(new AssignVar(selectForInGroups, new StayFirstSelectorWithFavorites(solver, favorites, cpuPack, memPack, StayFirstSelectorWithFavorites.Option.wfMem))); //inGroup.addAll(vms); } //System.err.println("bad: " + badActions); //System.err.println("good: " + goodActions); //System.err.println("run: " + runActions); HosterVarSelector selectForBads = new HosterVarSelector(rp, ActionModels.extractDemandingSlices(badActions)); rp.addGoal(new AssignVar(selectForBads, new StayFirstSelector2(rp, rp.getSatisfyDSlicesHeightConstraint(), StayFirstSelector2.Option.wfMem))); //solver.addGoal(new AssignVar(selectForBads, new StayFirstSelectorWithFavorites(solver, favorites, cpuPack, memPack, StayFirstSelectorWithFavorites.Option.wfMem))); HosterVarSelector selectForGoods = new HosterVarSelector(rp, ActionModels.extractDemandingSlices(goodActions)); rp.addGoal(new AssignVar(selectForGoods, new StayFirstSelector2(rp, rp.getSatisfyDSlicesHeightConstraint(), StayFirstSelector2.Option.wfMem))); //solver.addGoal(new AssignVar(selectForGoods, new StayFirstSelectorWithFavorites(solver, favorites, cpuPack, memPack, StayFirstSelectorWithFavorites.Option.wfMem))); HosterVarSelector selectForRuns = new HosterVarSelector(rp, ActionModels.extractDemandingSlices(runActions)); rp.addGoal(new AssignVar(selectForRuns, new StayFirstSelector2(rp, rp.getSatisfyDSlicesHeightConstraint(), StayFirstSelector2.Option.wfMem))); } ///SCHEDULING PROBLEM List<ActionModel> actions = new ArrayList<ActionModel>(); for (VirtualMachineActionModel vma : rp.getVirtualMachineActions()) { actions.add(vma); } rp.addGoal(new AssignVar(new PureIncomingFirst(rp, actions, plan.getCostConstraints()), new MinVal())); rp.addGoal(new AssignVar(new StaticVarOrder(rp, new IntDomainVar[]{rp.getEnd(), totalDuration}), new MinVal())); } }