2

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.

saplingPro
  • 20,769
  • 53
  • 137
  • 195
  • What you want is `yield`. Unfortunately, Java doesn't have `yield`. You'll have to switch to C# for that. :-P – C. K. Young Sep 01 '13 at 02:22
  • @ChrisJester-Young There will surely be a way out in Java – saplingPro Sep 01 '13 at 02:24
  • I'm sure there is, but it'll be ugly. :-( `yield` is a very clean and easy-to-read feature. I really do wish Java had `yield`. See also: http://stackoverflow.com/q/1980953/13 – C. K. Young Sep 01 '13 at 02:26

1 Answers1

1

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.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • so the whole algorithm will execute only once..? and next time when the function is called,`if (availableVms.hasNext())` will always execute..Is that so ? and iterator naturally preserves its state – saplingPro Sep 01 '13 at 02:46
  • @saplingPro Yes, the next time the function executes, `availableVms` wouldn't be `null`, so the `if` at the top would be entered. If you want to reuse the object once the list of vms has been exhausted, you would need to provide a `reset` method that sets `availableVms = null`. You could also reset `availableVms = null` before you return zero to reset iterations. – Sergey Kalinichenko Sep 01 '13 at 02:48