package org.cloudbus.cloudsim.container.schedulers;
import org.cloudbus.cloudsim.container.containerVmProvisioners.ContainerVmPe;
import org.cloudbus.cloudsim.container.lists.ContainerVmPeList;
import org.cloudbus.cloudsim.container.containerVmProvisioners.ContainerVmPeProvisioner;
import org.cloudbus.cloudsim.container.core.ContainerVm;
import org.cloudbus.cloudsim.Log;
import java.util.*;
/**
* Created by sareh on 14/07/15.
*/
public class ContainerVmSchedulerTimeShared extends ContainerVmScheduler {
/** The mips map requested. */
private Map<String, List<Double>> mipsMapRequested;
/** The pes in use. */
private int pesInUse;
/**
* Instantiates a new vm scheduler time shared.
*
* @param pelist the pelist
*/
public ContainerVmSchedulerTimeShared(List<? extends ContainerVmPe> pelist) {
super(pelist);
setMipsMapRequested(new HashMap<String, List<Double>>());
}
@Override
public boolean allocatePesForVm(ContainerVm containerVm, List<Double> mipsShare) {
//Log.printLine("VmSchedulerTimeShared: allocatePesForVm with mips share size......" + mipsShare.size());
if (containerVm.isInMigration()) {
if (!getVmsMigratingIn().contains(containerVm.getUid()) && !getVmsMigratingOut().contains(containerVm.getUid())) {
getVmsMigratingOut().add(containerVm.getUid());
}
} else {
if (getVmsMigratingOut().contains(containerVm.getUid())) {
getVmsMigratingOut().remove(containerVm.getUid());
}
}
boolean result = allocatePesForVm(containerVm.getUid(), mipsShare);
updatePeProvisioning();
return result;
}
/**
* Allocate pes for vm.
*
* @param vmUid the vm uid
* @param mipsShareRequested the mips share requested
* @return true, if successful
*/
protected boolean allocatePesForVm(String vmUid, List<Double> mipsShareRequested) {
//Log.printLine("VmSchedulerTimeShared: allocatePesForVm for Vmuid......"+vmUid);
double totalRequestedMips = 0;
double peMips = getPeCapacity();
for (Double mips : mipsShareRequested) {
// each virtual PE of a VM must require not more than the capacity of a physical PE
if (mips > peMips) {
return false;
}
totalRequestedMips += mips;
}
// This scheduler does not allow over-subscription
if (getAvailableMips() < totalRequestedMips) {
return false;
}
getMipsMapRequested().put(vmUid, mipsShareRequested);
setPesInUse(getPesInUse() + mipsShareRequested.size());
if (getVmsMigratingIn().contains(vmUid)) {
// the destination host only experience 10% of the migrating VM's MIPS
totalRequestedMips *= 0.1;
}
List<Double> mipsShareAllocated = new ArrayList<Double>();
for (Double mipsRequested : mipsShareRequested) {
if (getVmsMigratingOut().contains(vmUid)) {
// performance degradation due to migration = 10% MIPS
mipsRequested *= 0.9;
} else if (getVmsMigratingIn().contains(vmUid)) {
// the destination host only experience 10% of the migrating VM's MIPS
mipsRequested *= 0.1;
}
mipsShareAllocated.add(mipsRequested);
}
getMipsMap().put(vmUid, mipsShareAllocated);
setAvailableMips(getAvailableMips() - totalRequestedMips);
return true;
}
/**
* Update allocation of VMs on PEs.
*/
protected void updatePeProvisioning() {
//Log.printLine("VmSchedulerTimeShared: update the pe provisioning......");
getPeMap().clear();
// Log.printConcatLine("The Pe Map is being cleared ");
for (ContainerVmPe pe : getPeList()) {
pe.getContainerVmPeProvisioner().deallocateMipsForAllContainerVms();
}
Iterator<ContainerVmPe> peIterator = getPeList().iterator();
ContainerVmPe pe = peIterator.next();
ContainerVmPeProvisioner containerVmPeProvisioner = pe.getContainerVmPeProvisioner();
double availableMips = containerVmPeProvisioner.getAvailableMips();
for (Map.Entry<String, List<Double>> entry : getMipsMap().entrySet()) {
String vmUid = entry.getKey();
getPeMap().put(vmUid, new LinkedList<ContainerVmPe>());
for (double mips : entry.getValue()) {
// Log.printConcatLine("The mips value is: ",mips);
while (mips >= 0.1) {
if (availableMips >= mips) {
containerVmPeProvisioner.allocateMipsForContainerVm(vmUid, mips);
getPeMap().get(vmUid).add(pe);
// Log.formatLine("The allocated Mips is % f to Pe Id % d", mips, pe.getId());
availableMips -= mips;
// Log.print(getPeMap().get(vmUid));
break;
} else {
containerVmPeProvisioner.allocateMipsForContainerVm(vmUid, availableMips);
if(availableMips != 0){
getPeMap().get(vmUid).add(pe);}
mips -= availableMips;
// Log.print(getPeMap().get(vmUid));
if (mips <= 0.1) {
break;
}
if (!peIterator.hasNext()) {
Log.printConcatLine("There is no enough MIPS (", mips, ") to accommodate VM ", vmUid);
// System.exit(0);
}
pe = peIterator.next();
containerVmPeProvisioner = pe.getContainerVmPeProvisioner();
availableMips = containerVmPeProvisioner.getAvailableMips();
}
}
}
}
// Log.printConcatLine("These are the values",getPeMap().keySet());
}
@Override
public void deallocatePesForVm(ContainerVm containerVm) {
//Log.printLine("VmSchedulerTimeShared: deallocatePesForVm.....");
getMipsMapRequested().remove(containerVm.getUid());
setPesInUse(0);
getMipsMap().clear();
setAvailableMips(ContainerVmPeList.getTotalMips(getPeList()));
for (ContainerVmPe pe : getPeList()) {
pe.getContainerVmPeProvisioner().deallocateMipsForContainerVm(containerVm);
}
//Log.printLine("VmSchedulerTimeShared: deallocatePesForVm. allocates again!!!!!!!....");
for (Map.Entry<String, List<Double>> entry : getMipsMapRequested().entrySet()) {
allocatePesForVm(entry.getKey(), entry.getValue());
}
updatePeProvisioning();
}
/**
* Releases PEs allocated to all the VMs.
*
* @pre $none
* @post $none
*/
@Override
public void deallocatePesForAllContainerVms() {
super.deallocatePesForAllContainerVms();
getMipsMapRequested().clear();
setPesInUse(0);
}
/**
* Returns maximum available MIPS among all the PEs. For the time shared policy it is just all
* the avaiable MIPS.
*
* @return max mips
*/
@Override
public double getMaxAvailableMips() {
return getAvailableMips();
}
public Map<String, List<Double>> getMipsMapRequested() {
return mipsMapRequested;
}
public void setMipsMapRequested(Map<String, List<Double>> mipsMapRequested) {
this.mipsMapRequested = mipsMapRequested;
}
public int getPesInUse() {
return pesInUse;
}
public void setPesInUse(int pesInUse) {
this.pesInUse = pesInUse;
}
}