以循环方式返回数字,但附加条款

时间:2013-09-17 08:34:54

标签: java algorithm round-robin

有一个名为busyList的LinkedList可以跟踪所有繁忙的机器。机器可能正忙或可用。机器的id会从列表中删除获得自由。

以下是在机器空闲/忙碌时被触发的方法

@Override
public void cloudSimEventFired(CloudSimEvent e) {
    if(e.getId() == CloudSimEvents.EVENT_CLOUDLET_ALLOCATED_TO_VM) {
        int vmId = (Integer) e.getParameter(Constants.PARAM_VM_ID);
        busyList.add(vmId);
    }else if(e.getId() == CloudSimEvents.EVENT_VM_FINISHED_CLOUDLET) {
        int vmId = (Integer) e.getParameter(Constants.PARAM_VM_ID);
        busyList.remove(new Integer(vmId));
    }
}

名为allMap的地图(用于分配地图)将机器的ID作为其键,并将class VmAllocation的对象作为其值。VmAllocation的属性为:

maxAlloc (which tells the maximum times a machine can be returned)
currAlloc (which tells the current count)

/*
   allMap.put(id, new VmAllocation(o.getMemory()/512, 0));

   o.getMemory()/512 => maxAlloc
   0 => currAlloc

   This map has been initialized earlier.Like for 3 machines id will be 0,1,2
   As the machine will be returned currAlloc will be incremented by 1
   but it cannot exceed maxAlloc.  
*/

我必须以循环方式返回机器,同时保持视野,我不会返回当前忙碌的机器。如果busyList.contains(id)返回true,则表示机器正忙,并且返回下一个可用的机器(在allMap中),同时保持视图不会超过maxAlloc设置。例如,如果1忙碌,如果2不忙且2未超过currAlloc

,则会返回maxAlloc

以下是必须返回机器的方法,并且从封闭类外部多次调用。

@Override
    public int getNextAvailableVm() {
                  // return the id
    }   

这是算法应用的一般方法:

Let the id of the machines inside the allMap be :
     0,1,2,3,4
     0 has maxAlloc of 4
     1 has maxAlloc of 4
     2,3 has maxAlloc of 2
     4 has maxAlloc of 1

    The ideal order of returning will be :
    0000 1111 22 33 4 0000 1111 22 33 4 00....

但是只有当机器都没有忙时才会发生这种情况。但如果机器忙碌,订单可能就像:

0 0 1 2 0 1 0 1 ....

请注意,返回计算机的次数不能超过maxAlloc,如果发现计算机忙于将要返回的下一台计算机,那么该计算机可能就在当前正忙的计算机旁边本身不忙(还有currAlloc不应超过maxAlloc)

如果maxAlloc = 5,则cu​​rrAlloc限制为4.因为其计数从0开始

我无法实现此逻辑。帮我这样做。

2 个答案:

答案 0 :(得分:1)

应该适合您的代码的函数如下:

public Integer getNextAvailable() {
    Integer machineId = null;
    VMallocation allocation;

    // busyListIsFull is a volatile variable that has to be shared between the 2 classes:
    // the one that contains getNext... and the one that modifies busyList
    //this should be added to the code that modifies busyList
    /*
    if(busyList.containsAll(mapAll.keySet())) {
    busyListIsFull = true;
    notifyAll();
    }
     */

    // all machines are busy
    while(busyListIsFull) {
        try {
            wait();
        } catch (InterruptedException e) {

        }
    }
    busyListIsFull = false;
    notifyAll();

    for(Map.Entry<Integer, VMallocation> entry: mapAll.entrySet()) {
        machineId = (Integer)(entry.getKey());
        allocation = (VMallocation)(entry.getValue());
        // allocate the next machineId if it is not busy and has available allocations
        if(!busyList.contains(machineId) &&
                allocation.getCurrentAlloc() < allocation.getMaxAlloc()) {
            System.out.println("allocating machineId:" + machineId);
            allocation.setCurrentAlloc(allocation.getCurrentAlloc() + 1);
            if(machineId != null) {
                return machineId;
            }
        }
    }
    // no machineId was returned if code execution gets here, so no
    //resource was available; now free them all
    for(Map.Entry<Integer, VMallocation> entry: mapAll.entrySet()) {
        allocation = (VMallocation)(entry.getValue());
        allocation.setCurrentAlloc(0);
    }
    // return first available machine
    return getNextAvailable();
}

答案 1 :(得分:1)

我对你的问题很感兴趣,所以我提出了这个可能适合你的解决方案。该代码中没有健全性检查,它只是一个概念证明。

事件:

public class CloudSimEvent {

    private final int id;
    private final boolean allocated;

    public CloudSimEvent(int id, boolean allocated) {
        super();
        this.id = id;
        this.allocated = allocated;
    }

    public int getID() {
        return id;
    }

    public boolean allocated() {
        return allocated;
    }

    public boolean finished() {
        return !allocated;
    }

}

活动界面

public interface CloudSimEventListener {

    public void cloudSimEventFired(CloudSimEvent e);

}

VMAllocation对象

public final class VMAllocation implements Comparable<VMAllocation> {

    private final int id;
    private final int maxAlloc;
    private final int currAlloc;

    public VMAllocation(int id, int maxAlloc, int currAlloc) {
        super();
        this.id = id;
        this.maxAlloc = maxAlloc;
        this.currAlloc = currAlloc;
    }

    public VMAllocation allocate() {
        return new VMAllocation(id, maxAlloc, currAlloc + 1);
    }

    public VMAllocation finish() {
        return new VMAllocation(id, maxAlloc, currAlloc - 1);
    }

    public boolean isBusy() {
        return currAlloc >= maxAlloc;
    }

    public int getId() {
        return id;
    }

    @Override
    public int compareTo(VMAllocation o) {
        if (isBusy() && !o.isBusy()) {
            return 1;
        } else if (!isBusy() && o.isBusy()) {
            return -1;
        } else {
            return Integer.compare(id, o.id);
        }
    }

    @Override
    public String toString() {
        return "id: " + id + " currAlloc: " + currAlloc + " maxAlloc: "
                + maxAlloc + " is-busy: " + isBusy();
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + currAlloc;
        result = prime * result + id;
        result = prime * result + maxAlloc;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        VMAllocation other = (VMAllocation) obj;
        if (currAlloc != other.currAlloc)
            return false;
        if (id != other.id)
            return false;
        if (maxAlloc != other.maxAlloc)
            return false;
        return true;
    }

}

RRScheduler

import java.util.Arrays;
import java.util.Iterator;
import java.util.PriorityQueue;

public class RRSheduler implements CloudSimEventListener {

    private final PriorityQueue<VMAllocation> queue = new PriorityQueue<>();

    public void addVMAllocation(VMAllocation allocation) {
        synchronized (queue) {
            queue.add(allocation);
        }
    }

    @Override
    public void cloudSimEventFired(CloudSimEvent e) {
        VMChanged(e.getID(), e.allocated());
    }

    private void VMChanged(int id, boolean allocation) {
        synchronized (queue) {
            Iterator<VMAllocation> it = queue.iterator();
            VMAllocation newAllocation = null;
            while (it.hasNext()) {
                VMAllocation vmAllocation = it.next();
                if (vmAllocation.getId() == id) {
                    if (allocation)
                        newAllocation = vmAllocation.allocate();
                    else
                        newAllocation = vmAllocation.finish();
                    it.remove();
                    break;
                }
            }

            if (newAllocation != null)
                queue.add(newAllocation);
        }
    }

    public VMAllocation getNextFreeVMAllocation() {
        synchronized (queue) {
            VMAllocation allocation = queue.element();
            return allocation.isBusy() ? null : allocation;
        }
    }

    @Override
    public String toString() {
        synchronized (queue) {
            VMAllocation[] arr = queue.toArray(new VMAllocation[] {});
            Arrays.sort(arr);
            return Arrays.toString(arr);
        }
    }
}

简单的测试程序

public class TestRR {

    public static void main(String[] args) {
        RRSheduler rrSheduler = new RRSheduler();
        rrSheduler.addVMAllocation(new VMAllocation(0, 4, 0));
        rrSheduler.addVMAllocation(new VMAllocation(1, 4, 0));
        rrSheduler.addVMAllocation(new VMAllocation(2, 2, 0));
        rrSheduler.addVMAllocation(new VMAllocation(3, 2, 0));
        rrSheduler.addVMAllocation(new VMAllocation(4, 1, 0));

        VMAllocation nextAllocation = null;
        while ((nextAllocation = rrSheduler.getNextFreeVMAllocation()) != null) {
            System.out.println(nextAllocation);
            rrSheduler.cloudSimEventFired(new CloudSimEvent(nextAllocation
                    .getId(), true));
        }

    }
}

我没有像你一样使用地图,但你可能会想到如何解决你的问题。