package org.cloudbus.cloudsim.container.resourceAllocatorMigrationEnabled;
import org.cloudbus.cloudsim.container.containerSelectionPolicies.PowerContainerSelectionPolicy;
import org.cloudbus.cloudsim.container.core.*;
import org.cloudbus.cloudsim.container.hostSelectionPolicies.HostSelectionPolicy;
import org.cloudbus.cloudsim.container.lists.PowerContainerList;
import org.cloudbus.cloudsim.container.lists.PowerContainerVmList;
import org.cloudbus.cloudsim.container.vmSelectionPolicies.PowerContainerVmSelectionPolicy;
import org.cloudbus.cloudsim.Log;
import java.util.*;
/**
* Created by sareh on 11/08/15.
*/
public abstract class PowerContainerVmAllocationPolicyMigrationAbstractContainerHostSelection extends PowerContainerVmAllocationPolicyMigrationAbstractContainerAdded {
private HostSelectionPolicy hostSelectionPolicy;
public PowerContainerVmAllocationPolicyMigrationAbstractContainerHostSelection(List<? extends ContainerHost> hostList, PowerContainerVmSelectionPolicy vmSelectionPolicy,
PowerContainerSelectionPolicy containerSelectionPolicy, HostSelectionPolicy hostSelectionPolicy,
int numberOfVmTypes, int[] vmPes, float[] vmRam, long vmBw, long vmSize, double[] vmMips) {
super(hostList, vmSelectionPolicy, containerSelectionPolicy, numberOfVmTypes, vmPes, vmRam, vmBw, vmSize, vmMips);
setHostSelectionPolicy(hostSelectionPolicy);
}
@Override
public Map<String, Object> findHostForContainer(Container container, Set<? extends ContainerHost> excludedHosts, boolean checkForVM) {
PowerContainerHost allocatedHost = null;
ContainerVm allocatedVm = null;
Map<String, Object> map = new HashMap<>();
Set<ContainerHost> excludedHost1 = new HashSet<>();
if(excludedHosts.size() == getContainerHostList().size()){
return map;}
excludedHost1.addAll(excludedHosts);
while (true) {
if(getContainerHostList().size()==0){
return map;
}
ContainerHost host = getHostSelectionPolicy().getHost(getContainerHostList(), container, excludedHost1);
boolean findVm = false;
List<ContainerVm> vmList = host.getVmList();
PowerContainerVmList.sortByCpuUtilization(vmList);
for (int i = 0; i < vmList.size(); i++) {
ContainerVm vm = vmList.get(vmList.size() - 1 - i);
if(checkForVM){
if(vm.isInWaiting()){
continue;
}
}
if (vm.isSuitableForContainer(container)) {
// if vm is overutilized or host would be overutilized after the allocation, this host is not chosen!
if (!isVmOverUtilized(vm)) {
continue;
}
if (getUtilizationOfCpuMips((PowerContainerHost) host) != 0 && isHostOverUtilizedAfterContainerAllocation((PowerContainerHost) host, vm, container)) {
continue;
}
vm.containerCreate(container);
allocatedVm = vm;
findVm = true;
allocatedHost = (PowerContainerHost) host;
break;
}
}
if (findVm) {
map.put("vm", allocatedVm);
map.put("host", allocatedHost);
map.put("container", container);
excludedHost1.clear();
return map;
} else {
excludedHost1.add(host);
if (getContainerHostList().size() == excludedHost1.size()) {
excludedHost1.clear();
return map;
}
}
}
}
@Override
protected Collection<? extends Map<String, Object>> getContainerMigrationMapFromUnderUtilizedHosts(List<PowerContainerHostUtilizationHistory> overUtilizedHosts, List<Map<String, Object>> previouseMap) {
List<Map<String, Object>> migrationMap = new LinkedList<Map<String, Object>>();
List<PowerContainerHost> switchedOffHosts = getSwitchedOffHosts();
// over-utilized hosts + hosts that are selected to migrate VMs to from over-utilized hosts
Set<PowerContainerHost> excludedHostsForFindingUnderUtilizedHost = new HashSet<>();
excludedHostsForFindingUnderUtilizedHost.addAll(overUtilizedHosts);
excludedHostsForFindingUnderUtilizedHost.addAll(switchedOffHosts);
excludedHostsForFindingUnderUtilizedHost.addAll(extractHostListFromMigrationMap(previouseMap));
// over-utilized + under-utilized hosts
Set<PowerContainerHost> excludedHostsForFindingNewContainerPlacement = new HashSet<PowerContainerHost>();
excludedHostsForFindingNewContainerPlacement.addAll(overUtilizedHosts);
excludedHostsForFindingNewContainerPlacement.addAll(switchedOffHosts);
int numberOfHosts = getContainerHostList().size();
while (true) {
if (numberOfHosts == excludedHostsForFindingUnderUtilizedHost.size()) {
break;
}
PowerContainerHost underUtilizedHost = getUnderUtilizedHost(excludedHostsForFindingUnderUtilizedHost);
if (underUtilizedHost == null) {
break;
}
Log.printConcatLine("Under-utilized host: host #", underUtilizedHost.getId(), "\n");
excludedHostsForFindingUnderUtilizedHost.add(underUtilizedHost);
excludedHostsForFindingNewContainerPlacement.add(underUtilizedHost);
List<? extends Container> containersToMigrateFromUnderUtilizedHost = getContainersToMigrateFromUnderUtilizedHost(underUtilizedHost);
if (containersToMigrateFromUnderUtilizedHost.isEmpty()) {
continue;
}
Log.print("Reallocation of Containers from the under-utilized host: ");
if (!Log.isDisabled()) {
for (Container container : containersToMigrateFromUnderUtilizedHost) {
Log.print(container.getId() + " ");
}
}
Log.printLine();
List<Map<String, Object>> newContainerPlacement = getNewContainerPlacementFromUnderUtilizedHost(
containersToMigrateFromUnderUtilizedHost,
excludedHostsForFindingNewContainerPlacement);
//Sareh
if (newContainerPlacement == null) {
// Add the host to the placement founder option
excludedHostsForFindingNewContainerPlacement.remove(underUtilizedHost);
}
excludedHostsForFindingUnderUtilizedHost.addAll(extractHostListFromMigrationMap(newContainerPlacement));
//The migration mapp does not have a value for container since the whole vm would be migrated.
migrationMap.addAll(newContainerPlacement);
Log.printLine();
}
switchedOffHosts.clear();
excludedHostsForFindingUnderUtilizedHost.clear();
excludedHostsForFindingNewContainerPlacement.clear();
return migrationMap;
}
/**
* Gets the vms to migrate from under utilized host.
*
* @param host the host
* @return the vms to migrate from under utilized host
*/
protected List<? extends Container> getContainersToMigrateFromUnderUtilizedHost(PowerContainerHost host) {
List<Container> containersToMigrate = new LinkedList<>();
for (ContainerVm vm : host.getVmList()) {
if (!vm.isInMigration()) {
for (Container container : vm.getContainerList()) {
if (!container.isInMigration()) {
containersToMigrate.add(container);
}
}
}
}
return containersToMigrate;
}
/**
* Gets the new vm placement from under utilized host.
*
* @param containersToMigrate the vms to migrate
* @param excludedHosts the excluded hosts
* @return the new vm placement from under utilized host
*/
protected List<Map<String, Object>> getNewContainerPlacementFromUnderUtilizedHost(
List<? extends Container> containersToMigrate,
Set<? extends ContainerHost> excludedHosts) {
List<Map<String, Object>> migrationMap = new LinkedList<Map<String, Object>>();
PowerContainerList.sortByCpuUtilization(containersToMigrate);
for (Container container : containersToMigrate) {
Map<String, Object> allocatedMap = findHostForContainer(container, excludedHosts, true);
if (allocatedMap.get("vm") != null && allocatedMap.get("host")!= null) {
Log.printConcatLine("Container# ",container.getId(),"allocated to VM # ", ((ContainerVm)allocatedMap.get("vm")).getId()
, " on host# ", ((ContainerHost)allocatedMap.get("host")).getId());
migrationMap.add(allocatedMap);
} else {
Log.printLine("Not all Containers can be reallocated from the host, reallocation cancelled");
allocatedMap.clear();
migrationMap.clear();
break;
}
}
return migrationMap;
}
@Override
protected Map<String, Object> findAvailableHostForContainer(Container container,
List<Map<String, Object>> createdVm) {
PowerContainerHost allocatedHost = null;
ContainerVm allocatedVm = null;
Map<String, Object> map = new HashMap<>();
Set<ContainerHost> excludedHost1 = new HashSet<>();
List<ContainerHost> underUtilizedHostList = new ArrayList<>();
for(Map<String, Object> map1:createdVm){
ContainerHost host=(ContainerHost) map1.get("host");
if(!underUtilizedHostList.contains(host)){
underUtilizedHostList.add(host);}
}
while (true) {
ContainerHost host = getHostSelectionPolicy().getHost(underUtilizedHostList, container, excludedHost1);
List<ContainerVm> vmList = new ArrayList<>();
for(Map<String, Object> map2:createdVm){
if(map2.get("host")== host){
vmList.add((ContainerVm) map2.get("vm"));
}
}
boolean findVm = false;
PowerContainerVmList.sortByCpuUtilization(vmList);
for (int i = 0; i < vmList.size(); i++) {
ContainerVm vm = vmList.get(vmList.size() - 1 - i);
if (vm.isSuitableForContainer(container)) {
// if vm is overutilized or host would be overutilized after the allocation, this host is not chosen!
if (!isVmOverUtilized(vm)) {
continue;
}
vm.containerCreate(container);
allocatedVm = vm;
findVm = true;
allocatedHost = (PowerContainerHost) host;
break;
}
}
if (findVm) {
map.put("vm", allocatedVm);
map.put("host", allocatedHost);
map.put("container", container);
excludedHost1.clear();
return map;
} else {
if(host != null){
excludedHost1.add(host);
}
if (underUtilizedHostList.size() == excludedHost1.size()) {
excludedHost1.clear();
return map;
}
}
}
}
public void setHostSelectionPolicy(HostSelectionPolicy hostSelectionPolicy) {
this.hostSelectionPolicy = hostSelectionPolicy;
}
public HostSelectionPolicy getHostSelectionPolicy() {
return hostSelectionPolicy;
}
}