saplingPro
saplingPro

Reputation: 21329

I have to return a value from a function that is called multiple times and I am unable to do that

I am stuck.

The following function is supposed to return currVm, an integer. But if I make a return I will break the loop and next time when this function is called,the same process will begin again.

What shall I do, so that I continue from where I left off ? I tried making static variables but I that didn't help me.

@Override
public int getNextAvailableVm() {
    Set<String> dataCenters = confMap.keySet();
    for (String dataCenter : dataCenters) {
        LinkedList<DepConfAttr> list = confMap.get(dataCenter);
        Collections.sort(list, new MemoryComparator());
        int size = list.size() - 1;
        int count = 0;
        while(size >= 0) {
            DepConfAttr dca = (DepConfAttr)list.get(count);
            int currVm = dca.getVmCount();
            int c = 0;
            while(c <= currVm) {
                allocatedVm(currVm);
                c++;
                return currVm;
            }
            count++;
            size--;
        }
    }

    return 0;
}  

The for-each loop assigns a new data center that acts as a key for the confMap.The list that I get as a value, is sorted.Then a loop is run till it escapes its size.Inside this while loop, another while loop is run from where a function named allocatedVm of the inherited class is called. A parameter named currVm is passed to it.

This is the variable that I need to return. What shall I do to return this variable ? I have to start from I left off. I mean the next call should appear to be the next step, whatever it was, while executing the loop.

Upvotes: 2

Views: 146

Answers (1)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726509

Add List<Integer> object to your class, and change your method as follows:

private Iterator<Integer> availableVms = null;
@Override
public int getNextAvailableVm() {
    if (availableVms != null) {
        if (availableVms.hasNext()) {
            return availableVms.next();
        }
        return 0;
    }
    List<Integer> tmp = new ArrayList<Integer>();
    Set<String> dataCenters = confMap.keySet();
    for (String dataCenter : dataCenters) {
        LinkedList<DepConfAttr> list = confMap.get(dataCenter);
        Collections.sort(list, new MemoryComparator());
        int size = list.size() - 1;
        int count = 0;
        while(size >= 0) {
            DepConfAttr dca = (DepConfAttr)list.get(count);
            int currVm = dca.getVmCount();
            int c = 0;
            while(c <= currVm) {
                allocatedVm(currVm);
                c++;
                tmp.add(currVm);
            }
            count++;
            size--;
        }
    }
    availableVms = tmp.iterator();
    return availableVms.hasNext() ? availableVms.next() : 0;
}

The idea is to pre-generate the entire list, and store its iterator for future use. Before entering the method you check if the availableVms iterator has been prepared. If it has been prepared, grab the next item off of it if it's available; otherwise, return zero.

If the list has not been prepared yet, run your algorithm, and add the results to a temporary list tmp. Once the list is ready, grab its iterator, and use it for subsequent invocations.

Upvotes: 1

Related Questions