<repo_name>BeyondTheClouds/VMPlaceS<file_sep>/generate.py
#!/usr/bin/python

# This script generates a specific deployment file for the injection simulator.
# It assumes that the platform will be a cluster.
# Usage: python generate.py scheduling policies nb_nodes
# Example: python generate.py centralized 100000 32 1000

import sys, random

## centralized scheduling
largv=len(sys.argv)
nb_nodes = int(sys.argv[2])

if (sys.argv[1] == 'centralized'):
    sys.stderr.write("generate deployment file for entropy");
    sys.stdout.write("<?xml version='1.0'?>\n"
    "<!DOCTYPE platform SYSTEM \"http://simgrid.gforge.inria.fr/simgrid/simgrid.dtd\">\n"
    "<platform version=\"4\">\n"
    "  <process host=\"node%d\" function=\"injector.Injector\"> </process>\n"
    "  <process host=\"node%d\" function=\"simulation.CentralizedResolver\"> </process>\n"
    "</platform>" % (nb_nodes +1, nb_nodes));

elif (sys.argv[1] == 'example'):
    sys.stderr.write("generate deployment file for the simple example");
    sys.stdout.write("<?xml version='1.0'?>\n"
                     "<!DOCTYPE platform SYSTEM \"http://simgrid.gforge.inria.fr/simgrid/simgrid.dtd\">\n"
                     "<platform version=\"4\">\n"
                     "  <process host=\"node%d\" function=\"injector.Injector\"> </process>\n"
                     "  <process host=\"node%d\" function=\"simulation.ExampleResolver\"> </process>\n"
                     "</platform>" % (nb_nodes +1, nb_nodes));

elif (sys.argv[1] == 'without'):
    sys.stderr.write("generate deployment file for entropy");
    sys.stdout.write("<?xml version='1.0'?>\n"
                     "<!DOCTYPE platform SYSTEM \"http://simgrid.gforge.inria.fr/simgrid/simgrid.dtd\">\n"
                     "<platform version=\"4\">\n"
                     "  <process host=\"node%d\" function=\"injector.Injector\"> </process>\n"
                     "</platform>" % (nb_nodes +1));

elif (sys.argv[1] == 'hierarchical'):
        nb_servicenodes = int(sys.argv[3])
        sys.stderr.write("generate deployment file for snooze");
        sys.stdout.write("<?xml version='1.0'?>\n"
        "<!DOCTYPE platform SYSTEM \"http://simgrid.gforge.inria.fr/simgrid/simgrid.dtd\">\n"
        "<platform version=\"4\">\n"
        "  <process host=\"node%d\" function=\"injector.Injector\"> </process>\n"
        "  <process host=\"node%d\" function=\"simulation.HierarchicalResolver\"> </process>\n"
        % (nb_nodes + nb_servicenodes, nb_nodes + nb_servicenodes))

#        for i in range(0, nb_nodes):
#                line = "  <process host=\"node%d\" function=\"scheduling.hierarchical.snooze.LocalController\">\
#<argument value=\"node%d\" /><argument value=\"localController-%d\" />\
#</process>\n" % (i, i, i)
#                sys.stdout.write(line)

        for i in range(nb_nodes, nb_nodes+nb_servicenodes):

            line = "  <process host=\"node%d\" function=\"scheduling.hierarchical.snooze.GroupManager\">\
<argument value=\"node%d\" /><argument value=\"groupManager-%d\" />\
</process>\n" % (i, i, i)
            sys.stdout.write(line)

        sys.stdout.write("</platform>")

elif (sys.argv[1] == 'distributed'):
        nb_nodes = int(sys.argv[2])
        nb_cpu = int(sys.argv[3])
        total_cpu_cap = int(sys.argv[4])
        ram = int(sys.argv[5])
        port_orig = int(sys.argv[6])
        port = port_orig
        sys.stdout.write("<?xml version='1.0'?>\n"
        "<!DOCTYPE platform SYSTEM \"http://simgrid.gforge.inria.fr/simgrid/simgrid.dtd\">\n"
        "<platform version=\"4\">\n"
        "  <process host=\"node%d\" function=\"injector.Injector\"> </process>\n" % (nb_nodes))

        for i in range(0, nb_nodes - 1):

                line = "  <process host=\"node%d\" function=\"simulation.DistributedResolver\">\n \
                <argument value=\"node%d\" /><argument value=\"%d\" /><argument value=\"%d\" /><argument value=\"%d\" /><argument value=\"%d\" />\n \
                <argument value=\"node%d\" /><argument value=\"%d\" />\n \
                </process>\n" % (i, i, nb_cpu, total_cpu_cap, ram, port, i+1, port+1)

                port+=1

                sys.stdout.write(line)

        # link the last agent to the first
        line = "  <process host=\"node%d\" function=\"simulation.DistributedResolver\">\n \
        <argument value=\"node%d\" /><argument value=\"%d\" /><argument value=\"%d\" /><argument value=\"%d\" /><argument value=\"%d\" />\n \
        <argument value=\"node%d\" /><argument value=\"%d\" />\n \
        </process>\n" % (nb_nodes-1, nb_nodes-1, nb_cpu, total_cpu_cap, ram, port, 0, port_orig)

        sys.stdout.write(line)
        sys.stdout.write("</platform>")

else:
        print("Usage: python generate.py scheduling_policy nb_nodes or python generate.py distributed nb_nodes nb_cpu total_cpu_cap ram port > dvms_deploy.xml")
        sys.exit(1)
<file_sep>/src/main/java/scheduling/hierarchical/snooze/Test.java
package scheduling.hierarchical.snooze;

import configuration.SimulatorProperties;
import org.simgrid.msg.*;
import org.simgrid.msg.Process;
import scheduling.hierarchical.snooze.msg.SnoozeMsg;
import scheduling.hierarchical.snooze.msg.TestFailGLMsg;
import scheduling.hierarchical.snooze.msg.TestFailGMMsg;
import simulation.SimulatorManager;

import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by sudholt on 20/07/2014.
 */
public class Test extends Process {
    static String name;
    static Host host;
    static String inbox;
    public boolean testsToBeTerminated = false;

    static Multicast multicast;
    static GroupLeader gl;
    static ConcurrentHashMap<String, GroupManager> gmsCreated = new ConcurrentHashMap<>();
    static ConcurrentHashMap<String, GroupManager> gmsJoined = new ConcurrentHashMap<>();
    static ConcurrentHashMap<String, LocalController> lcsCreated = new ConcurrentHashMap<>();
    static ConcurrentHashMap<String, LCJoined> lcsJoined = new ConcurrentHashMap<>();

    static int noGMJoins = 0;
    static int noLCJoins = 0;

    static String gm = "";
    static SnoozeMsg m = null;

    public Test(Host host, String name) {
        super(host, name);
        this.host = host;
        this.name = name;
        this.inbox = "test";
    }

    @Override
    public void main(String[] strings) throws MsgException {
        try {
//        procAddLCs();
//        procAddGMs();
//        procFailGLs();
//        procFailGMs();
            while (!testsToBeTerminated && !SimulatorManager.isEndOfInjection()) {
                dispInfo();
                sleep(1000*SnoozeProperties.getInfoPeriodicity());
            }
        } catch (HostFailureException e) {
            testsToBeTerminated = true;
            Logger.err("[Test.main] HostFailureException");
        }
    }

    void procAddGMs() throws HostNotFoundException {
        new Process(host, host.getName() + "-addGMs") {
            public void main(String[] args) throws HostFailureException, HostNotFoundException {
                try {
                    int lcNo = SimulatorProperties.getNbOfHostingNodes(); // no. of statically allocated LCs
                    int gmNo = SimulatorProperties.getNbOfServiceNodes(); // no. of statically allocated GMs
//                for (int i = 0; i < SimulatorProperties.getNbOfServiceNodes()/2 && !testsToBeTerminated; i++) {
                    for (int i = 0; i < SimulatorProperties.getNbOfServiceNodes() && !testsToBeTerminated; i++) {
                        sleep(250);
                        String[] gmArgs = new String[]{"node" + (gmNo + lcNo), "dynGroupManager-" + (gmNo + lcNo)};
                        GroupManager gm =
                                new GroupManager(Host.getByName("node" + (gmNo + lcNo)), "dynGroupManager-" + (gmNo + lcNo), gmArgs);
                        gm.start();
                        Logger.debug("[Test.addLCs] Dyn. GM added: " + gmArgs[1]);
                        gmNo++;
                    }
                } catch (HostFailureException e) {
                    testsToBeTerminated = true;
                    Logger.err("[Test.procAddGMs] HostFailureException");
                }
            }
        }.start();
    }

    void procAddLCs() throws HostNotFoundException {
        new Process(host, host.getName() + "-addLCs") {
            public void main(String[] args) throws HostFailureException, HostNotFoundException {
                try {
                    sleep(6000);
                    int lcNo = 0; // no. of statically allocated LCs
                    for (int i = 0; i < SimulatorProperties.getNbOfHostingNodes() && !testsToBeTerminated; i++) {
                        String[] lcArgs = new String[]{"node" + lcNo, "dynLocalController-" + lcNo};
                        LocalController lc =
                                new LocalController(Host.getByName("node" + lcNo), "dynLocalController-" + lcNo, lcArgs);
                        lc.start();
                        Logger.info("[Test.addLCs] Dyn. LC added: " + lcArgs[1]);
                        lcNo++;
                        sleep(2000);
                    }
                } catch (HostFailureException e) {
                    testsToBeTerminated = true;
                    Logger.err("[Test.procAddLCs] HostFailureException");
                }
            }
        }.start();
    }

    void procFailGLs() throws HostNotFoundException {
        new Process(host, host.getName() + "-terminateGMs") {
            public void main(String[] args) throws HostFailureException {
                try {
                    sleep(4000);
                    for (int i = 0; i < SimulatorProperties.getNbOfServiceNodes() / 2 && !testsToBeTerminated; i++) {
                        if (multicast.gmInfo.size() < 3) {
                            Logger.debug("[Test.failGLs] #GMs: " + multicast.gmInfo.size());
                            sleep(3000);
                            continue;
                        }
                        m = new TestFailGLMsg(name, AUX.glInbox(multicast.glHostname), null, null);
                        m.send();
                        Logger.imp("[Test.failGLs] GL failure: " + Test.gl.getHost().getName());
                        sleep(1537);
//                    break;
                    }
                } catch (HostFailureException e) {
                    testsToBeTerminated = true;
                    Logger.err("[Test.procFailGLs] HostFailureException");
                }
            }
        }.start();
    }

    void procFailGMs() throws HostNotFoundException {
        new Process(host, host.getName() + "-terminateGMs") {
            public void main(String[] args) throws HostFailureException {
                try {
                    sleep(5000);
                    for (int i = 0; i < SimulatorProperties.getNbOfServiceNodes() / 2 && !testsToBeTerminated; i++) {
                        if (multicast.gmInfo.size() < 3) {
                            Logger.info("[Test.failGMs] #GMs: " + multicast.gmInfo.size());
                            sleep(1777);
                            continue;
                        }
                        gm = new ArrayList<String>(multicast.gmInfo.keySet()).get(0);
                        m = new TestFailGMMsg(name, AUX.gmInbox(gm), null, null);
                        m.send();
                        Logger.imp("[Test.failGMs] Term. GM: " + gm + ", #GMs: " + multicast.gmInfo.size());
                        sleep(1777);
//                    break;
                    }
                } catch (HostFailureException e) {
                    testsToBeTerminated = true;
                    Logger.err("[Test.procFailGMs] HostFailureException");
                }
            }
        }.start();
    }

    void dispInfo() {
        int i = 0, al = 0, gmal = 0;
        Logger.imp("\n\n[Test.dispInfo] MUL.GL: " + multicast.glHostname +
                ", #MUL.gmInfo: " + multicast.gmInfo.size() +
                ", #MUL.lcInfo: " + multicast.lcInfo.size() + ", #Test.gmsCreated " + Test.gmsCreated.size());
        Logger.imp("    ----");
        for (String gm : multicast.gmInfo.keySet()) {
            int mulLCs = 0, testLCsCreated = 0, testLCsJoined = 0;
            for (String lc : multicast.lcInfo.keySet()) {
                if (multicast.lcInfo.get(lc).gmHost.equals(gm)) {
                    mulLCs++;
                    if (Test.lcsCreated.containsKey(lc)) testLCsCreated++;
                    if (Test.lcsJoined.containsKey(lc)) testLCsJoined += Test.getNoGMsJoinedLC(lc);
                }
            }
            String gmLeader = "";
            int gml = 0;
            for (String gmn : Test.gmsCreated.keySet()) {
                GroupManager gmo = Test.gmsCreated.get(gmn);
                if (gmn.equals(gm)) {
                    gmLeader = gmo.glHostname;
                    gml = gmo.lcInfo.size();
                    gmal += gml;
                }
            }
            Logger.imp("    MUL.GM: " + gm + ", MUL.GM.#LCs: " + mulLCs
                    + ", Test.GM.#LCs join/create: " + testLCsJoined + "/" + testLCsCreated
                    + ", Test.GMLeader: " + gmLeader);
//            Logger.imp("                         GM.#LCs: " + gml + ", Test.GMLeader: " + gmLeader);
            i++;
            al += mulLCs;
        }
        Logger.imp("    ----");
        if (gl != null)
            Logger.imp("    Test.GL: " + gl.host.getName()
                    + ", Test.GL.#GM: " + gl.gmInfo.size() + ", MUL.GM.#LCs: " + al + ", Test.GM.#LCs: " + gmal);
        Logger.imp("    No. GM joins: " + noGMJoins + ", No. LC joins: " + noLCJoins + "\n");
    }

    static class LCJoined {
        LocalController lco;
        ArrayList<String> gms;
    }

    static void removeJoinedLC(String lc, String gm, String m) {
        if (lcsJoined.containsKey(lc)) {
            LCJoined tlj = lcsJoined.get(lc);
            if (tlj.gms.contains(gm)) {
                tlj.gms.remove(gm);
                Logger.debug(m + " removeJoinedLC: LC: " + lc + ", GM: " + gm);
                if (tlj.gms.size() == 0) {
                    lcsJoined.remove(lc);
                    Logger.debug(m + ", removeJoinedLC: Last GM removed LC: " + lc + ", GM: " + gm);
                }
            }
        }
        else Logger.debug(m + ", removeJoinedLC: No LC: " + lc + ", GM: " + gm);
    }

    static void putJoinedLC(String lc, LocalController lco, String gm, String m) {
        if (lcsJoined.containsKey(lc)) {
            LCJoined tlj = lcsJoined.get(lc);
            if (!tlj.gms.contains(gm)) {
                tlj.gms.add(gm);
                Logger.debug(m + " putJoinedLC: GM added LC: " + lc + ", GM: " + gm + ", LCO: " + lco);
            } else Logger.err(m + " putJoinedLC: Double LC: " + lc + ", GM: " + gm + ", LCO: " + lco);
        } else {
            LCJoined tlj = new LCJoined();
            tlj.lco = lco;
            ArrayList<String> al = new ArrayList<>();
            al.add(gm);
            tlj.gms = al;
            lcsJoined.put(lc, tlj);
            Logger.debug(m + " putJoinedLC: New LC: " + lc + ", GM: " + gm + ", LCO: " + lco);
        }
    }

    static int getNoGMsJoinedLC(String lc) {
        if (!lcsJoined.containsKey(lc)) return 0;
        else return lcsJoined.get(lc).gms.size();
    }
}
<file_sep>/src/main/java/scheduling/hierarchical/snooze/LocalController.java
package scheduling.hierarchical.snooze;

/**
 * Created by sudholt on 25/05/2014.
 */

import configuration.XHost;
import org.simgrid.msg.*;
import org.simgrid.msg.Process;
import scheduling.hierarchical.snooze.msg.LCAssMsg;
import scheduling.hierarchical.snooze.msg.LCChargeMsg;
import scheduling.hierarchical.snooze.msg.NewLCMsg;
import scheduling.hierarchical.snooze.msg.SnoozeMsg;
import simulation.SimulatorManager;

public class LocalController extends Process {
    private String name;
    XHost host; //@ Make private
    private boolean thisLCToBeStopped = false;
    private String gmHostname = "";
    private double gmTimestamp;
    private int procCharge = 0;
    private String inbox, joinMBox;
    private String lcCharge; // GM mbox
    private boolean joining = true;

    public LocalController (Host host, String name, String[] args) throws HostNotFoundException {
        super(host, name, args);
    }

    public void init(XHost host, String name)  {
        this.host = host;
        this.name = name;
        this.inbox = AUX.lcInbox(host.getName());
        this.joinMBox = inbox + "-join";
    }

    @Override
    public void main(String[] args) {
        int n=0;

        try {
            // Let LCs wait for GM initialization
//            sleep(3000);
            Test.lcsCreated.remove(this);
            Logger.debug("Start LC " + args[0] + ", " + args[1]);
            init(SimulatorManager.getXHostByName(args[0]), args[1]);
            Test.lcsCreated.put(this.host.getName(), this);
            join();
            procSendLCChargeToHandleDeadGM();
            while (!stopThisLC()) {
                try {
                    SnoozeMsg m = (SnoozeMsg) Task.receive(inbox, AUX.durationToEnd());
                    handle(m);
//                    if (Task.listen(inbox)) handle((SnoozeMsg) Task.receive());
                    gmDead();
                    if (SnoozeProperties.shouldISleep()) sleep(AUX.DefaultComputeInterval);
                } catch (HostFailureException e) {
                    thisLCToBeStopped = true;
                    Logger.exc("[LC.main] HostFailureException");
                    break;
                } catch (TimeoutException e) {
                    gmDead();
                } catch (Exception e) {
                    String cause = e.getClass().getName();
                    Logger.err("[LC.main] PROBLEM? Exception: " + host.getName() + ": " + cause);
                    e.printStackTrace();
                    Logger.err("[LC.main] PROBLEM? Exception, " + host.getName() + ": " + e.getClass().getName());
                }
            }
            thisLCToBeStopped = true;
        } catch (HostFailureException e) {
            Logger.exc("[LC.main] HostFailureException");
            thisLCToBeStopped = true;
        }
        gmHostname = "";
        Logger.debug("[LC.main] LC stopped");
    }

    boolean stopThisLC() { return thisLCToBeStopped || SimulatorManager.isEndOfInjection(); }

    void handle(SnoozeMsg m) throws HostFailureException {
//        Logger.debug("[LC.handle] LCIn: " + m);
        String cs = m.getClass().getSimpleName();
        switch (cs) {
            case "TermGMMsg" : handleTermGM(m); break;
            case "SnoozeMsg" :
                Logger.err("[GM(SnoozeMsg)] Unknown message" + m + " on " + host);
                break;
        }
    }

    /**
     * Stop LC activity and rejoin
     */
    void handleTermGM(SnoozeMsg m) throws HostFailureException {
        // TODO: stop LC activity
        Logger.err("[LC(TermGM)] GM DEAD, LC rejoins: " + m);
        join();
    }


    /**
     * GM dead: rejoin
     */
    void gmDead() throws HostFailureException {
        if (AUX.timeDiff(gmTimestamp) < AUX.HeartbeatTimeout || joining) return;
        Logger.err("[LC.gmDead] GM dead: " + gmHostname + ", " + gmTimestamp);
        gmHostname = "";
        join();
    }

    void join() throws HostFailureException {
        joining = true;
        Logger.info("[LC.join] Entry: " + gmHostname + ", TS: " + gmTimestamp);
        String gl, gm;
        boolean success = false;
        do {
            try {
                gl = getGL();
                if (gl.isEmpty()) continue;
                int i = 0;
                do {
                    gm = getGM(gl);
                    if (!gm.isEmpty()) success = joinGM(gm);
//                    if (gm.isEmpty()) continue;
//                    success = joinGM(gm);
                    i++;
                } while (!success && i < 3);
                if (!success) continue;
                i = 0;
                do {
                    success = joinFinalize(gm);
                    i++;
                } while (!success && i < 3);
                if (!success) continue;
            } catch (HostFailureException e) {
                throw e;
            } catch(Exception e) {
                Logger.err("[LC.join] Exception");
                e.printStackTrace();
                success = false;
            }
        } while (!success && !stopThisLC());
        if (!stopThisLC()) {
            joining = false;
            Test.noLCJoins++;
//        Test.lcsJoined.remove(this.host.getName());
            Test.removeJoinedLC(this.host.getName(), gmHostname, "[LC.join]");  // Should be superfluous
//        Test.lcsJoined.put(this.host.getName(), this);
            Test.putJoinedLC(this.host.getName(), this, gmHostname, "[LC.join]");
            Logger.imp("[LC.join] Finished, GM: " + gmHostname + ", TS: " + gmTimestamp);
        }
    }

    /**
     * Send join request to EP and wait for GroupManager acknowledgement
     */
    String getGL() throws HostFailureException {
        try {
            boolean success = false;
            SnoozeMsg m = null;
            String gl = "";
            // Join GL multicast group
            m = new NewLCMsg(null, AUX.multicast + "-newLC", host.getName(), joinMBox);
            m.send();
//            Logger.debug("[LC.getGL] 1 Request sent: " + m);
            // Wait for GL beat
            int i = 0;
            do {
                m = (SnoozeMsg) Task.receive(inbox, AUX.durationToEnd());
//                m = (SnoozeMsg) Task.receive(inbox, AUX.HeartbeatTimeout);
                i++;
                Logger.info("[LC.getGL] Round " + i + ": " + m);
                gl = (String) m.getOrigin();
                success = m.getClass().getSimpleName().equals("RBeatGLMsg") && !m.getOrigin().isEmpty();
            } while (!success && !stopThisLC());
            return gl;
//            Logger.info("[LC.getGL] 1 Got GL: " + m);
        } catch (TimeoutException e) {
            Logger.exc("[LC.getGL] PROBLEM? Exception " + host.getName() + ": " + e.getClass().getName());
            e.printStackTrace();
            return "";
        } catch (HostFailureException e) {
            throw e;
        } catch (Exception e) {
            Logger.exc("[LC.getGL] PROBLEM? Exception " + host.getName() + ": " + e.getClass().getName());
            e.printStackTrace();
            return "";
        }
    }

    /**
     * Send join request to EP and wait for GroupManager acknowledgement
     */
    String getGM(String gl) throws HostFailureException {
        try {
            // Send GM assignment request
            SnoozeMsg m = new LCAssMsg(host.getName(), AUX.glInbox(gl) + "-lcAssign", host.getName(), joinMBox);
            m.send();
            Logger.info("[LC.getGM] Assignment message sent: " + m);

            // Wait for GM assignment
            m = (SnoozeMsg) Task.receive(joinMBox, 5*AUX.MessageReceptionTimeout);
            if (!m.getClass().getSimpleName().equals("LCAssMsg")) return "";
            String gm = (String) m.getMessage();
            if (gm.isEmpty()) {
                Logger.err("[LC.getGM] Empty GM: " + m);
                return "";
            }
            Logger.imp("[LC.getGM] GM assigned: " + m);
            return gm;
        } catch (TimeoutException e) {
            Logger.exc("[LC.getGM] Exception " + host.getName() + ": " + e.getClass().getName());
            e.printStackTrace();
            return "";
        } catch (HostFailureException e) {
            throw e;
        } catch (Exception e) {
            Logger.exc("[LC.getGM] PROBLEM? Exception " + host.getName() + ": " + e.getClass().getName());
            e.printStackTrace();
            return "";
        }
    }

    /**
     * Send join request to EP and wait for GroupManager acknowledgement
     */
    boolean joinGM(String gm) throws HostFailureException {
        try {
            // GM integration request
            SnoozeMsg m = new NewLCMsg(host.getName(), AUX.gmInbox(gm) + "-newLC", name, joinMBox);
            m.send();
            Logger.info("[LC.joinGM] Integration message sent: " + m);
            m = (SnoozeMsg) Task.receive(joinMBox, 5*AUX.MessageReceptionTimeout);
            if (!m.getClass().getSimpleName().equals("NewLCMsg")) {
                Logger.err("[LC.joinGM] No NewLC msg.: " + m);
                return false;
            }
            Logger.imp("[LC.joinGM] Integrated by GM: " + m);
            return true;
        } catch (TimeoutException e) {
            Logger.exc("[LC.joinGM] Exception " + host.getName() + ": " + e.getClass().getName());
            e.printStackTrace();
            return false;
        } catch (HostFailureException e) {
            throw e;
        } catch (Exception e) {
            Logger.exc("[LC.joinGM] PROBLEM? Exception " + host.getName() + ": " + e.getClass().getName());
            e.printStackTrace();
            return false;
        }
    }


    /**
     * Send join request to EP and wait for GroupManager acknowledgement
     */
    boolean joinFinalize(String gm) throws HostFailureException {
        try {
            // Leave GL multicast, join GM multicast group
            SnoozeMsg m = new NewLCMsg(gm, AUX.multicast + "-newLC", host.getName(), joinMBox);
            m.send();
            Logger.info("[LC.joinFinalize] GL->GM multicast: " + m);
            m = (SnoozeMsg) Task.receive(joinMBox, 5 * AUX.MessageReceptionTimeout);
            if (!m.getClass().getSimpleName().equals("NewLCMsg")) return false;
            gm = (String) m.getMessage();
            if (gm.isEmpty()) {
                Logger.err("[LC.joinFinalize] 4 Empty GM: " + m);
                return false;
            }
            Logger.info("[LC.tryJoin] Ok GL->GM multicast: " + m);

            gmHostname = gm;
            gmTimestamp = Msg.getClock();

            Logger.info("[LC.joinFinalize] Finished, GM: " + gm + ", " + gmTimestamp);
            return true;
        } catch (HostFailureException e) {
            throw e;
        } catch (Exception e) {
            Logger.exc("[LC.joinFinalize] PROBLEM? Exception " + host.getName() + ": " + e.getClass().getName());
            e.printStackTrace();
            return false;
        }
    }

    void handleGMBeats(SnoozeMsg m) {
        String gm = (String) m.getOrigin();
        if (gmHostname.isEmpty()) {
            Logger.err("[LC.handleGMBeats] No GM: " + host.getName());
        }
        if (!gmHostname.equals(gm)) {
            Logger.err("[LC.handleGMBeats] Multiple GMs: " + host.getName() + ", " + gmHostname + ", " + gm);
        } else {
            gmTimestamp = Msg.getClock();
            Logger.info("[LC.handleGMBeats] " + host.getName() + ", "  + gmHostname + ", TS: " + gmTimestamp);
        }
    }

    /**
     * Send LC beats to GM
     */
    void procSendLCChargeToHandleDeadGM() {
        try {
            final XHost h = host;
            new Process(host.getSGHost(), host.getSGHost().getName() + "-lcCharge") {
                public void main(String[] args) {
                    int chargeCounter = 0;
                    while (!stopThisLC()) {
                        chargeCounter++;
                        try {
                            if (chargeCounter%4 == 0) {
                                LCChargeMsg.LCCharge lc = new LCChargeMsg.LCCharge(h.getCPUDemand(), h.getMemDemand(), Msg.getClock());
                                LCChargeMsg m = new LCChargeMsg(lc, AUX.gmInbox(gmHostname), h.getName(), null);
                                m.send();
                                Logger.info("[LC.procSendLCChargeToGM] Charge sent: " + m);
                            }
                            gmDead();
                            sleep(AUX.HeartbeatInterval*1000/4);
                        } catch (HostFailureException e) {
                            Logger.exc("[LC.procSendLCChargeToGM] HostFailureException");
                            thisLCToBeStopped = true;
                            break;
                        } catch (Exception e) { e.printStackTrace(); }
                    }
                }
            }.start();
        } catch (Exception e) { e.printStackTrace(); }
    }

    void totalHostCapacity() {
        HostCapacity hc = new HostCapacity(host.getCPUCapacity(), host.getMemSize());
    }

    void startVM() {

    }

    void shutdownVM() {

    }

    void migrateVM() {

    }

}
<file_sep>/src/main/java/scheduling/hierarchical/snooze/msg/RBeatGMMsg.java
package scheduling.hierarchical.snooze.msg;

import scheduling.hierarchical.snooze.GroupManager;

/**
 * Created by sudholt on 14/07/2014.
 */
public class RBeatGMMsg extends SnoozeMsg {
    /**
     * Relay GL heartbeats to EPs, GMs and LCs
     * @param timestamp Timestamp
     * @param sendBox   Target mbox
     * @param origin    GL host
     * @param replyBox  null
     */
    public RBeatGMMsg(GroupManager gm, String sendBox, String origin, String replyBox) {
        super(gm, sendBox, origin, replyBox);
    }
}
<file_sep>/visu/template/energy_script.jinja2
#!/usr/bin/Rscript

{% set colors = ["#E04836", "#5696BC", "#F39D41", "#8D5924", "#2F5168"] %}
{% set algos_size = algos|count %}
{% set tuple_size = x_axis|count %}
{% set group_by_nodes_count = group_by_nodes|count %}

pdf(width=10, heigh=7)

# Import the date
{% set i = 0 %}
names <- c({% for name in names %}{% if i > 0 %}, {% endif %}"{{ name }}"{% set i = i+1 %}{% endfor %})
data <- read.table("{{source}}", header=T,sep=",")
attach(data)

# Compute the range of the series 
g_range <- range(0{% for algo in algos %},{{ algo }} {% endfor %})

{% set pch_start = 20 %}
{% set lty_start = 3 %}

{% set cex = 1.5 %}
{% set lwd = 1 %}
{% set legend_cex = 1 %}
{% set legend_lwd = 1.5 %}

{% set title_enabled = False %}

# Plot the first serie
{% set count = 0 %}
plot({{algos[0]}}, type="o", col="{{ colors[0] }}", ylim=g_range, pch={{pch_start+count}}, cex={{cex}}, lwd={{lwd}}, lty={{lty_start+count}}, 
   axes=TRUE, ann=FALSE)

# Generate x-axis
{% set count = 0 %}
#axis(1, at=1:{{tuple_size}}, lab=c({% for server_count,vm_count in x_axis %}{% if count > 0 %},{% endif %}"{{server_count}} nodes\n{{vm_count}} vms"{% set count = count +1 %}{% endfor %}))

print(g_range[2])

# Generate x-axis
axis(2)

# Create box around plot
box()

# Graph other series of data
{% set count = 0 %}
{% for algo in algos %}{% if count > 0 %}lines({{ algo }}, type="o", pch={{pch_start+count}}, cex={{cex}}, lwd={{lwd}}, lty={{lty_start+count}}, col="{{ colors[count] }}"){% endif %}{% set count = count +1 %}
{% endfor %}

{% if title_enabled %}
# 		Create a title with a red, bold/italic font
title(main="{{title|capitalize}}", font.main=4)
{% endif %}

# 		Label the x and y axes with dark green text
title(xlab="{{x_label}}", col.lab=rgb(0,0,0))
title(ylab="{{y_label}}", col.lab=rgb(0,0,0))

#abline(h=3600,col="black",lty=2)
# text(1.5, (3600+g_range[2]/40), "3600 s", col = "black")

# 		Create a legend at (1, g_range[2]) that is slightly smaller 
# 		(cex) and uses the same line colors and points used by 
# 		the actual plots 
{% set count = 0 %}
legend(1, g_range[2], names, cex={{legend_cex}}, lwd={{legend_lwd}}, 
   col=c({% for algo in algos %}{% if count > 0 %},{% endif %}"{{ colors[count] }}"{% set count = count +1 %}{% endfor %}), pch={{pch_start}}:{{pch_start + algos|length}}, lty={{lty_start}}:{{lty_start + algos|length}});

<file_sep>/visu/generate_data.py
#!/usr/bin/python
from __future__ import division
from pkg_resources import WorkingSet, DistributionNotFound
import sys

working_set = WorkingSet()

# Printing all installed modules
# print tuple(working_set)

# Detecting if module is installed
dependency_found = True
try:
    dep = working_set.require('Jinja2')
except DistributionNotFound:
    dependency_found = False
    pass

if not dependency_found:
    try:
        # Installing it (anyone knows a better way?)
        from setuptools.command.easy_install import main as install

        install(['Jinja2'])
        print("run again as normal user to process results")
    except DistributionNotFound:
        print("run this script as sudo to install a missing template engine")
        pass
    sys.exit(0)

import csv
import subprocess
import time
import os
import json
import jinja2

################################################################################
# Constant and parameters
################################################################################

# duration = 3600
max_duration = 86400


################################################################################
# Functions of the script
################################################################################
def execute_cmd(args):
    print "%s" % args
    # return "%s" % args
    out, err = subprocess.Popen(args,
                                shell=False,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE).communicate()
    if not err == "":
        print err
    return out


def render_template(template_file_path, vars, output_file_path):
    templateLoader = jinja2.FileSystemLoader(searchpath=".")
    templateEnv = jinja2.Environment(loader=templateLoader)

    TEMPLATE_FILE = template_file_path
    template = templateEnv.get_template(TEMPLATE_FILE)

    templateVars = vars

    outputText = template.render(templateVars)
    with open(output_file_path, "w") as text_file:
        text_file.write(outputText)


################################################################################
# Clean data and scripts folders
################################################################################
execute_cmd(["rm", "-r", "data"])
execute_cmd(["mkdir", "data"])

execute_cmd(["rm", "-r", "scripts"])
execute_cmd(["mkdir", "scripts"])

################################################################################
# Detect algorithms used in experiments
################################################################################
algos = []
for dirname, dirnames, filenames in os.walk('./events'):
    # print path to all subdirectories first.
    for filename in filenames:
        if filename.endswith(".json") and 'true' not in dirname:
            with open("%s/%s" % (dirname, filename), 'r') as f:
                print("loading %s/%s" % (dirname, filename))
                header_line = f.readline()
                print header_line
                header_data = json.loads(header_line)
                data = header_data["data"]
                algo = data["algorithm"]
                if "hierarchical" in algo:
                    algo = "%s_%s" % (algo, data["algorithm_details"]["lcsRatio"])
                if not algo in algos:
                    algos += [algo]
print algos

################################################################################
# Detect (server_count, vm_count) combination used in experiments
################################################################################
nodes_tuples = []
vms_tuples = []
nodes_vms_tuples = []
for dirname, dirnames, filenames in os.walk('./events'):
    # print path to all subdirectories first.
    for filename in filenames:
        if filename.endswith(".json"):
            with open("%s/%s" % (dirname, filename), 'r') as f:
                header_line = f.readline()
                header_data = json.loads(header_line)
                data = header_data["data"]

                compute_node_count = data["server_count"]
                service_node_count = data["service_node_count"]
                node_count = compute_node_count + service_node_count

                if not compute_node_count in nodes_tuples:
                    nodes_tuples += [compute_node_count]
                if not data["vm_count"] in vms_tuples:
                    vms_tuples += [data["vm_count"]]
                    # nodes_vms_tuple = "%s-%s" % (data["server_count"], data["vm_count"])
                    # if not nodes_vms_tuple in nodes_vms_tuples:
                    #     nodes_vms_tuples += [nodes_vms_tuple]

# Order the tuples
nodes_tuples = sorted(nodes_tuples)
vms_tuples = sorted(vms_tuples)
nodes_vms_tuples = [str(tuple2[0]) + "-" + str(tuple2[1]) for tuple2 in zip(nodes_tuples, vms_tuples)]
# nodes_vms_tuples = sorted(nodes_vms_tuples)

print nodes_tuples
print vms_tuples
print nodes_vms_tuples

################################################################################
# Fill data maps with computed metrics
################################################################################
map_simulation_count = {}

map_compute_time = {}
map_compute_time_per_service_node = {}
map_violation_time = {}
map_migration_time = {}
map_total_time = {}

map_reconfigure_failure_count = {}
map_reconfigure_success_count = {}
map_reconfigure_noreconf_count = {}
map_migration_count = {}
map_success_psize = {}

map_avg_psize = {}
map_migration_avg_duration = {}

for dirname, dirnames, filenames in os.walk('./events'):
    # print path to all subdirectories first.
    for filename in filenames:
        if filename.endswith(".json"):
            with open("%s/%s" % (dirname, filename), 'r') as f:
                header_line = f.readline()
                header_data = json.loads(header_line)
                data = header_data["data"]

                algo = data["algorithm"]
                if "hierarchical" in algo:
                    algo = "%s_%s" % (algo, data["algorithm_details"]["lcsRatio"])

                compute_node_count = data["server_count"]
                service_node_count = data["service_node_count"]

                if "distributed" in algo:
                    service_node_count = compute_node_count

                node_count = compute_node_count + service_node_count

                nodes_vms_tuple = "%s-%s" % (algo, compute_node_count)

                compute_time = 0
                violation_time = 0
                migrate_time = 0
                reconfigure_time = 0

                reconfigure_failure_count = 0
                reconfigure_success_count = 0
                reconfigure_noreconf_count = 0
                migration_count = 0
                success_psize = 0

                servers_involved = 0

                for line in f.readlines():
                    try:
                        data = json.loads(line)

                        if float(data["time"]) > max_duration:
                            continue
                        # print(data)

                        if data["event"] == "trace_event" and data["value"] == "violation":
                            violation_time += data["duration"]

                        if data["event"] == "trace_event" and data["value"] == "reconfigure":
                            reconfigure_time += data["duration"]

                        if data["event"] == "trace_event" and data["value"] == "compute":
                            compute_time += data["duration"]

                            if data["data"]["state"] == "NO_RECONFIGURATION_NEEDED":
                                reconfigure_noreconf_count += 1
                            elif data["data"]["state"] == "SUCCESS":
                                reconfigure_success_count += 1
                                servers_involved += data["data"]["psize"]
                                success_psize += data["data"]["psize"]

                            else:
                                reconfigure_failure_count += 1

                        if data["event"] == "trace_event" and data["state_name"] == "SERVICE" and data[
                            "value"] == "migrate":
                            migrate_time += data["duration"]
                            migration_count += 1
                    except:
                        pass

                try:
                    avg_psize = servers_involved / reconfigure_success_count
                except:
                    avg_psize = 0

                try:
                    avg_migration_duration = migrate_time / migration_count
                except:
                    avg_migration_duration = 0

                if not map_simulation_count.has_key(nodes_vms_tuple):
                    map_simulation_count[nodes_vms_tuple] = 0

                map_simulation_count[nodes_vms_tuple] += 1

                map_compute_time[nodes_vms_tuple] = compute_time
                map_compute_time_per_service_node[
                    nodes_vms_tuple] = compute_time / service_node_count if service_node_count > 0 else -1
                map_violation_time[nodes_vms_tuple] = violation_time
                map_migration_time[nodes_vms_tuple] = migrate_time
                map_total_time[nodes_vms_tuple] = reconfigure_time

                map_reconfigure_noreconf_count[nodes_vms_tuple] = reconfigure_noreconf_count
                map_reconfigure_failure_count[nodes_vms_tuple] = reconfigure_failure_count
                map_reconfigure_success_count[nodes_vms_tuple] = reconfigure_success_count
                map_migration_count[nodes_vms_tuple] = migration_count
                map_success_psize[nodes_vms_tuple] = (success_psize / reconfigure_success_count
                                                      if reconfigure_success_count > 0 else -1
                                                      )

                map_avg_psize[nodes_vms_tuple] = avg_psize
                map_migration_avg_duration[nodes_vms_tuple] = avg_migration_duration

################################################################################
# Group statistics by simulation kind
################################################################################

for key in map_simulation_count:
    simulation_count = map_simulation_count[key]

    map_compute_time[key] /= simulation_count
    map_violation_time[key] /= simulation_count
    map_migration_time[key] /= simulation_count
    map_total_time[key] /= simulation_count
    map_reconfigure_failure_count[key] /= simulation_count
    map_reconfigure_success_count[key] /= simulation_count
    map_migration_count[key] /= simulation_count
    map_avg_psize[key] /= simulation_count
    map_migration_avg_duration[key] /= simulation_count

################################################################################
# Generate CSV files from data maps
################################################################################
print map_compute_time
print map_violation_time
print map_migration_time
print map_total_time

print map_reconfigure_failure_count
print map_reconfigure_success_count
print map_migration_count

print map_avg_psize
print map_migration_avg_duration

render_template("template/matrix_data.jinja2",
                {"algos": algos, "server_counts": nodes_tuples, "data": map_compute_time}, "data/compute_time.csv")
render_template("template/matrix_data.jinja2",
                {"algos": algos, "server_counts": nodes_tuples, "data": map_compute_time_per_service_node},
                "data/compute_time_per_service_node.csv")
render_template("template/matrix_data.jinja2",
                {"algos": algos, "server_counts": nodes_tuples, "data": map_violation_time}, "data/violation_time.csv")
render_template("template/matrix_data.jinja2",
                {"algos": algos, "server_counts": nodes_tuples, "data": map_migration_time}, "data/migration_time.csv")
render_template("template/matrix_data.jinja2", {"algos": algos, "server_counts": nodes_tuples, "data": map_total_time},
                "data/total_time.csv")
render_template("template/matrix_data.jinja2",
                {"algos": algos, "server_counts": nodes_tuples, "data": map_reconfigure_failure_count},
                "data/reconfigure_failure_count.csv")
render_template("template/matrix_data.jinja2",
                {"algos": algos, "server_counts": nodes_tuples, "data": map_reconfigure_success_count},
                "data/reconfigure_success_count.csv")
render_template("template/matrix_data.jinja2",
                {"algos": algos, "server_counts": nodes_tuples, "data": map_reconfigure_noreconf_count},
                "data/reconfigure_noreconf_count.csv")
render_template("template/matrix_data.jinja2",
                {"algos": algos, "server_counts": nodes_tuples, "data": map_migration_count},
                "data/migration_count.csv")
render_template("template/matrix_data.jinja2",
                {"algos": algos, "server_counts": nodes_tuples, "data": map_success_psize}, "data/success_psize.csv")
render_template("template/matrix_data.jinja2",
                {"algos": algos, "server_counts": nodes_tuples, "data": map_migration_avg_duration},
                "data/migration_avg_duration.csv")

# Add distributed class algorithmes to the group_by_nodes
group_by_nodes = ["distributed"]
# Add hierarchical class algorithmes to the group_by_nodes
for each in algos:
    if "hierarchical" in each:
        group_by_nodes += [each]

not_group_by_nodes = list(set(algos) - set(group_by_nodes))

print("group_by_nodes -> %s" % (group_by_nodes))
print("not_group_by_nodes -> %s" % (not_group_by_nodes))

render_template("template/matrix_script.jinja2",
                {"source": "data/compute_time.csv", "x_label": "Infrastructure sizes", "y_label": "Time (s)",
                 "algos": algos, "x_axis": zip(nodes_tuples, vms_tuples), "group_by_nodes": group_by_nodes,
                 "not_group_by_nodes": not_group_by_nodes, "title": "cumulated computation time"},
                "scripts/compute_time.r")
render_template("template/matrix_script.jinja2",
                {"source": "data/compute_time_per_service_node.csv", "x_label": "Infrastructure sizes",
                 "y_label": "Time (s)", "algos": algos, "x_axis": zip(nodes_tuples, vms_tuples),
                 "group_by_nodes": group_by_nodes, "not_group_by_nodes": not_group_by_nodes,
                 "title": "computation time per service node"}, "scripts/compute_time_per_service_node.r")
render_template("template/matrix_script.jinja2",
                {"source": "data/violation_time.csv", "x_label": "Infrastructure sizes", "y_label": "Time (s)",
                 "algos": algos, "x_axis": zip(nodes_tuples, vms_tuples), "group_by_nodes": [],
                 "not_group_by_nodes": [], "title": "cumulated violation time"}, "scripts/violation_time.r")
render_template("template/matrix_script.jinja2",
                {"source": "data/migration_time.csv", "x_label": "Infrastructure sizes", "y_label": "Time (s)",
                 "algos": algos, "x_axis": zip(nodes_tuples, vms_tuples), "group_by_nodes": [],
                 "not_group_by_nodes": [], "title": "cumulated migration time"}, "scripts/migration_time.r")
render_template("template/matrix_script.jinja2",
                {"source": "data/total_time.csv", "x_label": "Infrastructure sizes", "y_label": "Time (s)",
                 "algos": algos, "x_axis": zip(nodes_tuples, vms_tuples), "group_by_nodes": group_by_nodes,
                 "not_group_by_nodes": not_group_by_nodes, "title": "cumulated reconfiguration time"},
                "scripts/total_time.r")
render_template("template/matrix_script.jinja2",
                {"source": "data/reconfigure_failure_count.csv", "x_label": "Infrastructure sizes", "y_label": "Count",
                 "algos": algos, "x_axis": zip(nodes_tuples, vms_tuples), "group_by_nodes": [],
                 "not_group_by_nodes": [], "title": "failed reconfiguration count"},
                "scripts/reconfigure_failure_count.r")
render_template("template/matrix_script.jinja2",
                {"source": "data/reconfigure_success_count.csv", "x_label": "Infrastructure sizes", "y_label": "Count",
                 "algos": algos, "x_axis": zip(nodes_tuples, vms_tuples), "group_by_nodes": [],
                 "not_group_by_nodes": [], "title": "successful reconfiguration count"},
                "scripts/reconfigure_success_count.r")
render_template("template/matrix_script.jinja2",
                {"source": "data/reconfigure_noreconf_count.csv", "x_label": "Infrastructure sizes", "y_label": "Count",
                 "algos": algos, "x_axis": zip(nodes_tuples, vms_tuples), "group_by_nodes": [],
                 "not_group_by_nodes": [], "title": "no reconfiguration count"}, "scripts/reconfigure_noreconf_count.r")
render_template("template/matrix_script.jinja2",
                {"source": "data/migration_count.csv", "x_label": "Infrastructure sizes", "y_label": "Count",
                 "algos": algos, "x_axis": zip(nodes_tuples, vms_tuples), "group_by_nodes": [],
                 "not_group_by_nodes": [], "title": "migration count"}, "scripts/migration_count.r")
render_template("template/matrix_script.jinja2",
                {"source": "data/success_psize.csv", "x_label": "Infrastructure sizes", "y_label": "Count",
                 "algos": algos, "x_axis": zip(nodes_tuples, vms_tuples), "group_by_nodes": [],
                 "not_group_by_nodes": [], "title": "average number of nodes involved in a successul computation"},
                "scripts/success_psize.r")
render_template("template/matrix_script.jinja2",
                {"source": "data/migration_avg_duration.csv", "x_label": "Infrastructure sizes", "y_label": "Time (s)",
                 "algos": algos, "x_axis": zip(nodes_tuples, vms_tuples), "group_by_nodes": [],
                 "not_group_by_nodes": [], "title": "average duration of migration"},
                "scripts/migration_avg_duration.r")
<file_sep>/visu/template/repartition_script.jinja2
#!/usr/bin/Rscript

data <- read.table("repartition/data/{{algo}}-{{node_count}}/repartition_{{metric}}.csv", header=T,sep=",")
colnames(data) <- c("type", "value")
attach(data)

dev.new(width=8, height=6)

n <- length(data$value)
plot( 100*(1:n)/n ~ sort(data$value), xlab="{{legend}}", ylab='Cumulated Distribution (percentage)')
lines(100*(1:n)/n ~ sort(data$value))  
title(main="{{algo}} {{node_count}} nodes \n(Cumulated Frequency of {{metric}} distribution)")


<file_sep>/src/main/java/scheduling/distributed/dvms2/TimeoutCheckerProcess.java
package scheduling.distributed.dvms2;

import configuration.XHost;
import org.simgrid.msg.HostFailureException;
import org.simgrid.msg.Process;
import simulation.SimulatorManager;

public class TimeoutCheckerProcess extends Process {

    public TimeoutCheckerActor timeoutActor;

    public TimeoutCheckerProcess(XHost xhost, String name, int port, SGNodeRef ref, DVMSProcess process) {
        super(xhost.getSGHost(), String.format("%s-checkout-checker", name, port));

        this.timeoutActor = new TimeoutCheckerActor(ref, xhost, process);
    }

    public class TimeoutCheckerActor extends SGActor {

        SGNodeRef ref;
        DVMSProcess process;
        XHost xhost;

        public TimeoutCheckerActor(SGNodeRef ref, XHost xhost, DVMSProcess process) {
            super(ref);

            this.ref = ref;
            this.xhost = xhost;
            this.process = process;
        }

        public void doCheckTimeout() throws HostFailureException {

            send(ref, "checkTimeout");
            waitFor(1);
        }

        public void receive(Object message, SGNodeRef sender, SGNodeRef returnCanal) {

        }
    }

    public void main(String args[]) {

        try {
            while (!SimulatorManager.isEndOfInjection()) {

                timeoutActor.doCheckTimeout();

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}


<file_sep>/config/snooze.properties
/**
 * This file is the main configuration file for the Snooze scheduling management (hierarchical)
 *
 **/

/**
 * Main properties
 **/

// The identifier of the algorithm variant
// If empty, the id is calculated from the parameters (host no., service host no., ...)
snooze.alg-variant =

// The periodicity for sending the heartbeat (in seconds)
// Default: 2
snooze.hb-periodicity = 3

// The timeout before considering a daemon dead (GL, GM or LC) (in seconds)
// Default: 5
snooze.hb-timeout = 6

// Periodic scheduling
// Default: true
snooze.scheduling-periodic = false

// The periodicity to invoke the scheduling algorithm (in seconds)
// Default: 30 seconds
snooze.scheduling-periodicity = 120

// The information level : 4:err,exc; 3:imp(ortant), 2:info; 1:debug
// Default: 2
snooze.info-level = 1

// Periodicity of the display of information, statistics etc. (in seconds)
// Default: 5s
// TODO add a property to  enable/disable test
snooze.info-periodicity = 1

// If you want to simulate costs of local computations, please set the following property to true
// Default: false
snooze.simulate-localcomputation = false


// If you want to simulate a specific fault injection.
// Default: false
snooze.faultmode = true
snooze.glcrash-period = 900
snooze.gmcrash-period = 300<file_sep>/src/main/java/scheduling/hierarchical/snooze/ThreadPool.java
package scheduling.hierarchical.snooze;

import org.simgrid.msg.Host;
import org.simgrid.msg.HostNotFoundException;
import org.simgrid.msg.MsgException;
import org.simgrid.msg.Process;
import scheduling.hierarchical.snooze.msg.SnoozeMsg;
import simulation.SimulatorManager;

import java.lang.reflect.Constructor;

/**
 * Created by sudholt on 31/07/2014.
 */
public class ThreadPool {
    private final Process[] workers;
    private final int numThreads;
    private String runClass;

    ThreadPool(Object owner, String runClass, int numThreads) {
        this.numThreads = numThreads;
        workers = new Process[numThreads];

        int i = 0;
        for (Process w: workers) {
            i++;
            w = new Worker(Host.currentHost(), "PoolProcess-" + i, owner, runClass);
            try {
                w.start();
                Logger.debug("[ThreadPool] Worker created: " + i + ", " + Host.currentHost()
                        + ", " + owner.getClass().getSimpleName() + ", " + runClass);
            } catch (Exception e) {
                Logger.exc("[ThreadPool] HostNoFound");
//                e.printStackTrace();
            }
        }
    }

    private class Worker extends Process {
        Host host;
        String name;
        SnoozeMsg m;
        String mbox;
        Object owner;
        String runClassName;

        Worker(Host host, String name, Object owner, String runClass) {
            super(host, name);
            this.host = host;
            this.name = name;
            this.owner = owner;
            this.runClassName = runClass;
        }

        @Override
        public void main(String[] strings) throws MsgException {
            while (!SimulatorManager.isEndOfInjection()) {
                try {
                    Class runClass = Class.forName(runClassName);
                    Constructor<?> constructor = runClass.getDeclaredConstructors()[0];
                    constructor.setAccessible(true);
                    Runnable r = (Runnable) constructor.newInstance(owner);
                    Logger.debug("[ThreadPool.Worker.main] : " + r);
                    r.run();
                } catch (Exception e) {
                    e.printStackTrace();
                }
               // TODO it would be better to have a GL notification to inform available GMS instead of an active loop
            }
        }
    }

}<file_sep>/visu/generate_energy.py
#!/usr/bin/python
from __future__ import division, print_function
from pkg_resources import WorkingSet , DistributionNotFound
import sys
import re
import pprint
pp = pprint.PrettyPrinter(indent=4).pprint

working_set = WorkingSet()

# Detecting if module is installed
dependency_found = True
try:
	dep = working_set.require('Jinja2')
except DistributionNotFound:
	dependency_found  = False

if not dependency_found:
	try:
		# Installing it (anyone knows a better way?)
		from setuptools.command.easy_install import main as install
		install(['Jinja2'])
		print("run again as normal user to process results")
	except DistributionNotFound:
		print("run this script as sudo to install a missing template engine")

	sys.exit(0)

import csv
import subprocess
import time
import os
import json
import jinja2

################################################################################
# Constant and parameters
################################################################################

max_duration = 86400


################################################################################
# Functions of the script
################################################################################
def execute_cmd(args):
	print("Running '%s'" % " ".join(args))
	out, err = subprocess.Popen(args,
				   shell=False,
				   stdout=subprocess.PIPE,
				   stderr=subprocess.PIPE).communicate()
	if not err == "":
		print(err)
	return out

def render_template(template_file_path, vars, output_file_path):
	templateLoader = jinja2.FileSystemLoader( searchpath="." )
	templateEnv = jinja2.Environment( loader=templateLoader )

	TEMPLATE_FILE = template_file_path
	template = templateEnv.get_template( TEMPLATE_FILE )

	templateVars = vars

	outputText = template.render( templateVars )
	with open(output_file_path, "w") as text_file:
		text_file.write(outputText)
		

################################################################################
# Clean data and scripts folders
################################################################################
execute_cmd(["rm", "-rf", "energy"])
execute_cmd(["mkdir", "energy"])

execute_cmd(["rm", "-rf", "energy/scripts"])
execute_cmd(["mkdir", "energy/scripts"])

execute_cmd(["mkdir", "-p", "data"])

################################################################################
# Fill data maps with computed metrics
################################################################################
algos = []

for dir in os.listdir('./events'):
	algos.append(dir)
print('Algos: ', end='')
pp(algos)

nodes_tuples = []
vms_tuples   = []
map_energy				  = {}
map_energy_per_second  = {}
map_energy_per_service_node = {}

for dirname, dirnames, filenames in os.walk('./events'):
	# print(path to all subdirectories first.)
	for filename in filenames:
		if filename.endswith(".json"):
			with open("%s/%s" % (dirname, filename), 'r') as f:
				print("Reading " + os.path.join(dirname, filename))
				header_line = f.readline()
				header_data = json.loads(header_line)
				data = header_data["data"]
				
				algo = os.path.basename(dirname)
				compute_node_count = data["server_count"]
				nodes_vms_tuple = "%s-%s" % (algo, compute_node_count)

				if not compute_node_count in nodes_tuples:
					nodes_tuples += [compute_node_count]
				if not data['vm_count'] in vms_tuples:
					vms_tuples += [data['vm_count']]
				
				energy = {}

				l = 1
				for line in f.readlines():
					try:
						data = json.loads(line)

						if float(data["time"]) > max_duration:
							continue

						event_time = int(float(data["time"]))

						if data["event"] == "trace_event" and data["value"] == "ENERGY":
							if not energy.has_key(data["origin"]):
								energy[data["origin"]] = 0

							energy[data["origin"]] += data["data"]["value"]

							if not map_energy_per_second.has_key(event_time):
								map_energy_per_second[event_time] = {}
								for a in algos:
									map_energy_per_second[event_time][a] = 0

							map_energy_per_second[event_time][algo] += data["data"]["value"]

						l += 1
					except Exception as ex:
						print(ex)
						print(str(l) + ' ' + line)

				map_energy[nodes_vms_tuple]						  = energy
				#map_avg_energy_per_service_node[nodes_vms_tuple]	 = reduce(lambda x, y: x + y, map_energy[nodes_vms_tuple]) / len(map_energy)

################################################################################
# Generate CSV files from data maps
################################################################################
#pp(map_energy_per_second)

# Make the column names comply with R, also make pretty names
regex = re.compile(r'(\w+)\-(\w+)')
r_algos = map(lambda n: regex.sub(r'\1\2', n), algos)
names = map(lambda n: regex.sub(r'\1 (\2)', n), algos)

render_template("template/energy_data.jinja2", {"algos": r_algos, "data": map_energy_per_second}, "data/energy.csv")

group_by_nodes = []
not_group_by_nodes = []
render_template("template/energy_script.jinja2",
		{
			"source": "data/energy.csv",
			"x_label": "Time",
			"y_label": "Joules",
			"algos": r_algos,
			"names": names,
			"x_axis": zip(nodes_tuples, vms_tuples),
			"group_by_nodes": group_by_nodes,
			"not_group_by_nodes": not_group_by_nodes, 
			"title": "cumulated computation time"
		},
		"scripts/energy.r")


<file_sep>/visu/template/cloud_script.jinja2
#!/usr/bin/Rscript

algo1_matrix_data_smp_det_time <- read.table("clouds/data/{{algo1}}-{{node_count}}/violations_smp_det.csv", header=T,sep=",")
colnames(algo1_matrix_data_smp_det_time) <- c("algo1_smp_det_time", "algo1_smp_det_duration") 
attach(algo1_matrix_data_smp_det_time)

algo1_matrix_data_smp_hid_time <- read.table("clouds/data/{{algo1}}-{{node_count}}/violations_smp_hid.csv", header=T,sep=",")
colnames(algo1_matrix_data_smp_hid_time) <- c("algo1_smp_hid_time", "algo1_smp_hid_duration") 
attach(algo1_matrix_data_smp_hid_time)

algo1_matrix_data_out_det_time <- read.table("clouds/data/{{algo1}}-{{node_count}}/violations_out_det.csv", header=T,sep=",")
colnames(algo1_matrix_data_out_det_time) <- c("algo1_out_det_time", "algo1_out_det_duration") 
attach(algo1_matrix_data_out_det_time)

algo1_matrix_data_out_hid_time <- read.table("clouds/data/{{algo1}}-{{node_count}}/violations_out_hid.csv", header=T,sep=",")
colnames(algo1_matrix_data_out_hid_time) <- c("algo1_out_hid_time", "algo1_out_hid_duration") 
attach(algo1_matrix_data_out_hid_time)



algo2_matrix_data_smp_det_time <- read.table("clouds/data/{{algo2}}-{{node_count}}/violations_smp_det.csv", header=T,sep=",")
colnames(algo2_matrix_data_smp_det_time) <- c("algo2_smp_det_time", "algo2_smp_det_duration") 
attach(algo2_matrix_data_smp_det_time)

algo2_matrix_data_smp_hid_time <- read.table("clouds/data/{{algo2}}-{{node_count}}/violations_smp_hid.csv", header=T,sep=",")
colnames(algo2_matrix_data_smp_hid_time) <- c("algo2_smp_hid_time", "algo2_smp_hid_duration") 
attach(algo2_matrix_data_smp_hid_time)

algo2_matrix_data_out_det_time <- read.table("clouds/data/{{algo2}}-{{node_count}}/violations_out_det.csv", header=T,sep=",")
colnames(algo2_matrix_data_out_det_time) <- c("algo2_out_det_time", "algo2_out_det_duration") 
attach(algo2_matrix_data_out_det_time)

algo2_matrix_data_out_hid_time <- read.table("clouds/data/{{algo2}}-{{node_count}}/violations_out_hid.csv", header=T,sep=",")
colnames(algo2_matrix_data_out_hid_time) <- c("algo2_out_hid_time", "algo2_out_hid_duration") 
attach(algo2_matrix_data_out_hid_time)



dev.new(width=8, height=6)

g_range <- range(algo1_smp_det_duration, algo1_smp_hid_duration, algo1_out_det_duration, algo1_out_hid_duration, algo2_smp_det_duration, algo2_smp_hid_duration, algo2_out_det_duration, algo2_out_hid_duration)
plot(    algo1_smp_det_time, algo1_smp_det_duration,  pch=7 ,  col=rgb(255, 153, 51 , 200,maxColorValue=255), ylim=g_range*1.35, 
    ,xlim=c(0, {{duration}}), xlab="Time (s)", ylab="Duration of the violation (s)")
#title(main="Duration of each violation")
points(  algo1_smp_hid_time, algo1_smp_hid_duration,  pch=0 ,  col=rgb(255, 153, 51 , 200,maxColorValue=255))
points(  algo1_out_det_time, algo1_out_det_duration,  pch=13,  col=rgb(255, 178, 102, 200,maxColorValue=255))
points(  algo1_out_hid_time, algo1_out_hid_duration,  pch=1 ,  col=rgb(255, 178, 102, 200,maxColorValue=255))

points(  algo2_smp_det_time, algo2_smp_det_duration,  pch=7 ,  col=rgb(0  , 76 , 153, 200,maxColorValue=255))
points(  algo2_smp_hid_time, algo2_smp_hid_duration,  pch=0 ,  col=rgb(0  , 76 , 153, 200,maxColorValue=255))
points(  algo2_out_det_time, algo2_out_det_duration,  pch=13,  col=rgb(0  , 128, 255, 200,maxColorValue=255))
points(  algo2_out_hid_time, algo2_out_hid_duration,  pch=1 ,  col=rgb(0  , 128, 255, 200,maxColorValue=255))

legend("topleft", c(
        "{{algo1 | capitalize}} violation detected",
        "{{algo1 | capitalize}} violation hidden",        
        "{{algo1 | capitalize}} violation out detected",
        "{{algo1 | capitalize}} violation out hidden",
        "{{algo2 | capitalize}} violation detected",
        "{{algo2 | capitalize}} violation hidden",        
        "{{algo2 | capitalize}} violation out detected",
        "{{algo2 | capitalize}} violation out hidden"
    ), ncol=2,
   col=c(
      rgb(255, 153, 51 , 255,maxColorValue=255),
      rgb(255, 153, 51 , 255,maxColorValue=255),
      rgb(255, 178, 102, 255,maxColorValue=255),
      rgb(255, 178, 102, 255,maxColorValue=255),
      rgb(0  , 76 , 153, 255,maxColorValue=255),
      rgb(0  , 76 , 153, 255,maxColorValue=255),
      rgb(0  , 128, 255, 255,maxColorValue=255),
      rgb(0  , 128, 255, 255,maxColorValue=255)
  ), pch=c(7, 0, 13, 1, 7, 0, 13, 1))


<file_sep>/src/main/java/test/TestB.java
package test;

import org.simgrid.msg.*;
import org.simgrid.msg.Process;

import java.util.Random;

public class TestB extends Process {
    private static final int ITERATIONS = 50;

    private Random rand;

    public TestB(Host host, String name, String[] args) throws HostNotFoundException {
        super(host, name, args);
        rand = new Random();
    }

    @Override
    public void main(String[] strings) throws MsgException {
        for(int i = 0; i < ITERATIONS; i++) {
            Task t = new Task("task-" + i, getHost().getSpeed() * rand.nextInt(500), 0);
            System.out.println("A: about to execute");
            t.execute();
            System.out.println(String.format("B: about to go to sleep (%d)", i));
            waitFor(500);
            System.out.println("B: woke up");
        }

        System.out.println("B: last sleep");
        waitFor(800);
        System.out.println("B: I'm dying...");
    }
}
<file_sep>/src/main/java/scheduling/hierarchical/snooze/msg/GLElecStopGMMsg.java
package scheduling.hierarchical.snooze.msg;

/**
 * Created by sudholt on 20/07/2014.
 */
public class GLElecStopGMMsg extends SnoozeMsg {
    public GLElecStopGMMsg(String name, String sendBox, String origin, String replyBox) {
        super(name, sendBox, origin, replyBox);
    }
}
<file_sep>/src/main/java/configuration/XVM.java
/**
 *  Copyright 2012-2013-2014. The SimGrid Team. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the license (GNU LGPL) which comes with this package.
 *
 * This class is an extension of the usual VM of the Simgrid MSG abstraction
 * Note that the extension is done by aggregation instead of inheritance. This enables to create/destroy the sg VM while
 * manipulating the same XVM at the java level.
 *
 * @author: <EMAIL>
 */

package configuration;

import org.simgrid.msg.HostFailureException;
import org.simgrid.msg.HostNotFoundException;
import org.simgrid.msg.Msg;
import org.simgrid.msg.VM;

public class XVM {

    /**
     * The MSG VM to extend (extension by aggregation)
     */
    private VM vm;
    /**
     * The dirty page intensity of the VM (currently determined by the class of the VM, see the configureHostsAndVMs method).
     * Expressed as a percentage of the netBW (i.e. an integer between 0 and 100)
     * @see simulation.SimulatorManager
     */
    private int dpIntensity;
    /**
     *  The bandwidth network capability of the VM (expressed as MBytes).
     */
    private int netBW;
    /**
     * The ramsize of the VM
     */
    private int ramsize;
    /**
     * The current load of the VM (i.e. how the CPU is loaded).
     * Please note that for the moment, one VM can have only have one vcpu.
     * Hence, this value represents the current load of the vcpu (i.e. between 0 and 100%)
     */
    private double currentLoadDemand;

    /**
     * The number of times the load has been changed during the simulation.
     * This metric is relevant to check whether one particular VM is more affected than the others
     */
    private int NbOfLoadChanges;

    /**
     * The number of times the VM has been migrated during the simulation.
     * This metric is relevant to check whether one particular VM is more affected than the others
     */
    private int NbOfMigrations;

    /**
     * The daemon that runs inside the VM in order to simulate the load.
     */
    private Daemon daemon;
    /**
     * the XHost (i.e the physical machine) of the VM.
     * Similarly to the VM abstraction, the MSG Host abstraction has been extended in order to save/manipulate
     * additional states in an easier way.
     */
    private XHost host;

    /**
     * Temporary fix due to a simgrid issue
     * See https://gforge.inria.fr/tracker/index.php?func=detail&aid=17636&group_id=12&atid=165
     */
    private boolean isMigrating; //Temporary fix to prevent migrating the same VM twice

    private boolean isSuspended;

    /**
     * Construcor
     * @param host the XHost (i.e. the PM where the VM is currently running)
     * @param name the name of the vm (as it is listed by virsh list for instance)
     * @param nbCores the nbCores of the VM, please note that right now the injector is able to correctly manage only
     *                one core VM.
     * @param ramsize the size of the RAM (rigid parameter, once it has been assigned this value should not evolve.
     * @param netBW the bandwidth of the NIC (expressed in MBytes per second, for instance for a 1Gb/s ethernet NIC, you
     *              should mention 125 MBytes.
     * @param diskPath the path to the disk image (not used for the moment)
     * @param diskSize the size of the disk image (not used for the moment)
     * @param migNetBW the network bandwidth available for performing the migration (i.e. rigid value, this is the
     *                 maximum value that the migration can expect). In the first version of KVM, the bandwidth for the
     *                 migration was limited to 32MBytes. Although now, kvm uses the whole bandwidth that can be offered
     *                 by the Host NIC, users can define a dedicated value for one VM y using the (virsh migrate_set_speed
     *                 command.
     * @param dpIntensity the dirty page intensity, i.e. the refresh rate of the memory as described in the cloudcom
     *                    2013 paper (Adding a Live Migration Model into SimGrid: One More Step Toward the Simulation of
     *                    Infrastructure-as-a-Service Concerns)
     *                    The parameter is expressed has a percentage of the network bandwidth.
     *
     */
     public XVM(XHost host, String name,
            int nbCores, int ramsize, int netBW, String diskPath, int diskSize, int migNetBW, int dpIntensity){
        // TODO, why should we reduce the migNetBW ? (i.e. interest of multiplying the value by 0.9)
        this.vm = new VM (host.getSGHost(), name, ramsize, netBW, dpIntensity);
        //this.vm = new VM (host.getSGHost(), name, nbCores, ramsize, netBW, diskPath, diskSize, (int)(migNetBW*0.9), dpIntensity);
        this.currentLoadDemand = 0;
        this.netBW = netBW ;
        this. dpIntensity = dpIntensity ;
        this.ramsize= ramsize;
        this.daemon = new Daemon(this.vm, 100);
        this.host = host;
        this.NbOfLoadChanges = 0;
         this.NbOfMigrations = 0;
        this.isMigrating = false;
         isSuspended = false;
   }

    /* Delegation method from MSG VM */

    /**
     * @return the name of the VM
     */
    public String getName() {
        return this.vm.getName();
    }

    /**
     * @return the number of core of the VM
     */
    public double getCoreNumber() {
        return this.vm.getCoreNumber();
    }
    /**
     * Change the load of the VM, please remind that the load of the VM is set to 0 at its beginning.
     * TODO, check whether it makes sense to set the load to a minimal load.
     * @param expectedLoad expressed as a percentage (i.e. between 0 and 100)
     */
    public void setLoad(double expectedLoad){
        if (expectedLoad >0) {
            this.vm.setBound(this.vm.getSpeed()*expectedLoad/100);
            daemon.resume();
        }
        else if (NbOfLoadChanges > 0){
            daemon.suspend();
        }
        currentLoadDemand = expectedLoad ;
        NbOfLoadChanges++;
    }

    // TODO c'est crade
    public double getLoad(){
        return this.currentLoadDemand;
    }

    /**
     * @return the daemon process (i.e MSG Process) in charge of simulating the load of the VM
     */
    public Daemon getDaemon(){
        return this.daemon;
    }

    /**
     * @return the number of times the load has been changed since the begining of the simulation
     */
    public int getNbOfLoadChanges() {
        return NbOfLoadChanges;
    }

    /**
     * @return the number of times the VM has been migrated since the begining of the simulation
     */
    public int getNbOfMigrations() {
        return NbOfMigrations;
    }


    /**
     *  Override start method in order to start the daemon at the same time that should run inside the VM.
     */
    public void start(){
        this.vm.start();
        try {
            daemon.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
        this.setLoad(currentLoadDemand);
    }

    public void shutdown() {
        this.vm.shutdown();

    }

    public boolean isRunning() {
        return this.vm.isRunning() == 1;
    }

    /**
     * Migrate a VM from one XHost to another one.
     * @param host the host where to migrate the VM
     */
    public void migrate(XHost host) throws HostFailureException, DoubleMigrationException {
        if (!this.isMigrating) {
            this.isMigrating = true;
            //Msg.info("Start migration of VM " + this.getName() + " to " + host.getName());
            //Msg.info("    currentLoadDemand:" + this.currentLoadDemand + "/ramSize:" + this.ramsize + "/dpIntensity:" + this.dpIntensity + "/remaining:" + this.daemon.getRemaining());
            try {
                this.vm.migrate(host.getSGHost());
                this.NbOfMigrations++;
                this.host = host;
                this.setLoad(this.currentLoadDemand);   //TODO temporary fixed (setBound is not correctly propagated to the new node at the surf level)
                //The dummy cpu action is not bounded.
                Msg.info("End of migration of VM " + this.getName() + " to node " + host.getName());
            } catch (Exception e){
                e.printStackTrace();
                Msg.info("Something strange occurs during the migration");
                Msg.info("TODO Adrien, migrate should return 0 or -1, -2, ... according to whether the migration succeeded or not.");
                throw new HostFailureException();
                // TODO Adrien, migrate should return 0 or -1, -2, ... according to whether the migration succeeded or not.
                // This value can be then use at highler level to check whether the reconfiguration plan has been aborted or not.
            }
        } else {
            Msg.info("You are trying to migrate " + vm.getName() + " twice... it is impossible ! Byebye");
            //throw new DoubleMigrationException();
            System.exit(12);
        }
        this.isMigrating = false;

    }

    /**
     * TODO Adrien - Error management & documentation
     * @return 0 if success, 1 if should be postponed, -1 if failure, -2 if already suspended
     */
    public int suspend() {
        // Todo check if 0 means false & if CPU load should be 0 when vm is suspended
        if (this.isMigrating()) {
            Msg.info("VM " + vm.getName() + " is migrating");
            return 1;
        }
        else {
            Msg.info("VM " + vm.getName() + " is not migrating");
            if (this.vm.isSuspended() == 0) {
                try {
               //     Msg.info("Start suspension of VM " + this.getName() + " on " + this.host.getName());
                    //Msg.info("    currentLoadDemand:" + this.currentLoadDemand + "/ramSize:" + this.ramsize + "/dpIntensity:" + this.dpIntensity + "/remaining:" + this.daemon.getRemaining());
                    this.vm.suspend();
                    // VM is suspended - we suspend the daemon simulating CPU demand
                    //Msg.info("End of suspension of VM " + this.getName() + " on " + this.host.getName());
                    isSuspended = true;
                    return 0;
                } catch (Exception e) {
                    e.printStackTrace();
                    Msg.info("An error occurred during the suspension");
                    // todo throw exc ?
                    return -1;
                }
            } else {
                Msg.info("You are trying to suspend "+ this.getName() +" that is an already suspended VM.");
                System.exit(-1);
                return -2;
            }
        }
    }

    /**
     * TODO Adrien - improve implementation & documentation
     * @return 0 if success, -1 if failure, 1 if already running
     */
    public int resume() {
        if (isSuspended) {
            try {
                //Msg.info("Start resuming VM " + this.getName() + " on " + this.host.getName());
                this.vm.resume();
                // VM is resumed - we resume the daemon simulating CPU demand
                this.daemon.resume();
                //Msg.info("    currentLoadDemand:" + this.currentLoadDemand + "/ramSize:" + this.ramsize + "/dpIntensity:" + this.dpIntensity + "/remaining:" + this.daemon.getRemaining());
                //Msg.info("End of resuming of VM " + this.getName() + " on " + this.host.getName());
                isSuspended = false;
                return 0;
            } catch (Exception e) {
                e.printStackTrace();
                Msg.info("An error occurred during resuming");
                // todo throw exc ?
                return -1;
            }
        } else {
            Msg.info("You are trying to resume an already running VM " + this.getName());
            return 1;
        }
    }


    /**
     * @return the size of the RAM in MBytes
     */
    public int getMemSize(){
        return this.ramsize;
    }


    /**
     * @return the size of the RAM in MBytes
     */
    public boolean isMigrating(){
        return isMigrating;
    }


    /**
     * @return the current load of the VM
     */
    public double getCPUDemand() {
        return this.currentLoadDemand;
    }

    /**
     * @return the current location of the VM (i.e. its XHost)
     */
    public XHost getLocation() {
        return this.host;
    }

    /**
     * @return the load of the network
     */
    public long getNetBW() {
        return this.netBW;
    }

    public String toString() {
        return String.format("XVM [name=%s, currentLoad=%.2f, dpIntensity=%d, isMigrating=%b, isRunning=%b]",
                getName(),
                currentLoadDemand,
                dpIntensity,
                isMigrating,
                isRunning());
    }
}

<file_sep>/visu/generate_clouds.py
#!/usr/bin/python
from __future__ import division
from pkg_resources import WorkingSet , DistributionNotFound
working_set = WorkingSet()

import itertools

# Printing all installed modules
#print tuple(working_set)

# Detecting if module is installed
dependency_found = True
try:
    dep = working_set.require('Jinja2')
except DistributionNotFound:
    dependency_found  = False
    pass

if not dependency_found:
    try:
        # Installing it (anyone knows a better way?)
        from setuptools.command.easy_install import main as install
        install(['Jinja2'])
        print("run again as normal user to process results")
    except DistributionNotFound:
        print("run this script as sudo to install a missing template engine")
        pass
    sys.exit(0)


import csv
import subprocess
import time
import os
import json
import jinja2
import traceback

################################################################################
# Constant and parameters
################################################################################

max_duration = 86400

################################################################################
# Functions of the script
################################################################################
def execute_cmd(args):
	print "%s" % args
	# return "%s" % args
	out, err = subprocess.Popen(args,
                   shell=False,
                   stdout=subprocess.PIPE,
                   stderr=subprocess.PIPE).communicate()
	if not err == "":
		print err
	return out

def render_template(template_file_path, vars, output_file_path):
    templateLoader = jinja2.FileSystemLoader( searchpath="." )
    templateEnv = jinja2.Environment( loader=templateLoader )

    TEMPLATE_FILE = template_file_path
    template = templateEnv.get_template( TEMPLATE_FILE )

    templateVars = vars

    outputText = template.render( templateVars )
    with open(output_file_path, "w") as text_file:
        text_file.write(outputText)
        

################################################################################
# Clean data and scripts folders
################################################################################
execute_cmd(["rm", "-r", "clouds"])
execute_cmd(["mkdir", "clouds"])

################################################################################
# Detect algorithms used in experiments
################################################################################
algos = []
for dirname, dirnames, filenames in os.walk('./events'):
    # print path to all subdirectories first.
    for filename in filenames:
        if filename.endswith(".json"):
            with open("%s/%s" % (dirname, filename), 'r') as f:
                header_line = f.readline()
                header_data = json.loads(header_line)
                data = header_data["data"]
                algo = data["algorithm"]
                if not algo in algos:
                    algos += [algo]
print algos

################################################################################
# Detect (server_count, vm_count) combination used in experiments
################################################################################
nodes_tuples     = []
vms_tuples       = []
nodes_vms_tuples = []
for dirname, dirnames, filenames in os.walk('./events'):
    # print path to all subdirectories first.
    for filename in filenames:
        if filename.endswith(".json"):
            with open("%s/%s" % (dirname, filename), 'r') as f:
                header_line = f.readline()
                header_data = json.loads(header_line)
                data = header_data["data"]

                compute_node_count = data["server_count"]
                service_node_count = data["service_node_count"]
                node_count = compute_node_count + service_node_count

                if not compute_node_count in nodes_tuples:
                    nodes_tuples += [compute_node_count]
                if not data["vm_count"] in vms_tuples:
                    vms_tuples += [data["vm_count"]]
                # nodes_vms_tuple = "%s-%s" % (data["server_count"], data["vm_count"])
                # if not nodes_vms_tuple in nodes_vms_tuples:
                #     nodes_vms_tuples += [nodes_vms_tuple]

# Order the tuples
nodes_tuples = sorted(nodes_tuples)
vms_tuples = sorted(vms_tuples)
nodes_vms_tuples = [str(tuple2[0])+"-"+str(tuple2[1]) for tuple2 in zip(nodes_tuples, vms_tuples)]
# nodes_vms_tuples = sorted(nodes_vms_tuples)

print nodes_tuples
print vms_tuples
print nodes_vms_tuples

################################################################################
# Fill data maps with computed metrics
################################################################################

def export_csv_data(algo, node_count, violations_smp_detected, violations_smp_hidden, violations_out_detected, violations_out_hidden):

    folder_name = "clouds/data/%s-%d" % (algo, node_count)

    execute_cmd(["mkdir", "-p", folder_name])

    render_template("template/cloud_data.jinja2", {"algo": algo, "node_count": node_count, "violations": violations_smp_detected, "labels": ["smp_det_time", "smp_det_duration", "node", "type"]}, "%s/violations_smp_det.csv" % (folder_name))
    render_template("template/cloud_data.jinja2", {"algo": algo, "node_count": node_count, "violations": violations_smp_hidden,   "labels": ["smp_hid_time", "smp_hid_duration", "node", "type"]}, "%s/violations_smp_hid.csv" % (folder_name))
    render_template("template/cloud_data.jinja2", {"algo": algo, "node_count": node_count, "violations": violations_out_detected, "labels": ["out_det_time", "out_det_duration", "node", "type"]}, "%s/violations_out_det.csv" % (folder_name))
    render_template("template/cloud_data.jinja2", {"algo": algo, "node_count": node_count, "violations": violations_out_hidden,   "labels": ["out_hid_time", "out_hid_duration", "node", "type"]}, "%s/violations_out_hid.csv" % (folder_name))

map_algos_size = {}


# variable that is used to detect "violation-out", "violation-normal" and "violation-sched":
# it will store the last line about "violations-out" or "violation-det", to detect if the next
# "violation" has been already processed!
last_line = None

max_plot_time = 0

for dirname, dirnames, filenames in os.walk('./events'):
    # print path to all subdirectories first.
    for filename in filenames:
        if filename.endswith(".json"):
            with open("%s/%s" % (dirname, filename), 'r') as f:
                header_line = f.readline()
                header_data = json.loads(header_line)
                data = header_data["data"]
                algo = data["algorithm"]

                compute_node_count = data["server_count"]
                service_node_count = data["service_node_count"]
                node_count = compute_node_count + service_node_count
                
                nodes_vms_tuple = "%s-%s" % (data["algorithm"], compute_node_count)
                
                if not map_algos_size.has_key(compute_node_count):
                    map_algos_size[compute_node_count] = []

                map_algos_size[compute_node_count] += [algo]

                _violations_det_per_node = {}
                _violations_out_per_node = {}
                _violations_smp_per_node = {}

                for line in f.readlines():
                    try:
                        data = json.loads(line)

                        if float(data["time"]) > max_duration - 50:
                            continue
                        if float(data["time"]) > max_plot_time:
                            max_plot_time = float(data["time"])

                        if data["event"] == "trace_event" and data["value"] == "violation-det":
                            current_violation_det = (float(data["time"]), float(data["duration"]), data["origin"], "det")
                            if not _violations_det_per_node.has_key(data["origin"]):
                                _violations_det_per_node[data["origin"]] = []
                            _violations_det_per_node[data["origin"]] += [current_violation_det]

                        if data["event"] == "trace_event" and data["value"] == "violation-out":
                            current_violation_out = (float(data["time"]), float(data["duration"]), data["origin"], "out")
                            if not _violations_out_per_node.has_key(data["origin"]):
                                _violations_out_per_node[data["origin"]] = []
                            _violations_out_per_node[data["origin"]] += [current_violation_out]

                        if data["event"] == "trace_event" and data["value"] == "violation":
                            current_violation_smp = (float(data["time"]), float(data["duration"]), data["origin"], "smp")
                            if not _violations_smp_per_node.has_key(data["origin"]):
                                _violations_smp_per_node[data["origin"]] = []
                            _violations_smp_per_node[data["origin"]] += [current_violation_smp]

                    except Exception as e:
                        # print traceback.format_exc()
                        pass
                
                f.seek(0)

                nodes = set(_violations_smp_per_node.keys() + _violations_out_per_node.keys())

                violations_smp_detected = []
                violations_smp_hidden   = []
                violations_out_detected = []
                violations_out_hidden   = []

                for node in nodes:
                    try:

                        current_violation_det = _violations_det_per_node[node] if _violations_det_per_node.has_key(node) else []
                        current_violation_out = _violations_out_per_node[node] if _violations_out_per_node.has_key(node) else []
                        current_violation_smp = _violations_smp_per_node[node] if _violations_smp_per_node.has_key(node) else []

                        product = itertools.product(current_violation_smp, current_violation_det)
                        product_filtered = [element for element in product if abs(element[0][0] + element[0][1] - element[1][0] - element[1][1]) < 0.01]

                        violations_smp_per_node_detected = set([element[0] for element in product_filtered])
                        violations_smp_per_node_hidden   = set([element    for element in current_violation_smp if element not in violations_smp_per_node_detected])

                        if len(violations_smp_per_node_detected) + len(violations_smp_per_node_hidden) != len(current_violation_smp):
                            print("%s + %s = %s" % (violations_smp_per_node_detected, violations_smp_per_node_hidden, current_violation_smp))

                        product = itertools.product(current_violation_out, current_violation_det)
                        product_filtered = [element for element in product if abs(element[0][0] + element[0][1] - element[1][0] - element[1][1]) < 0.01]

                        violations_out_per_node_detected = set([element[0] for element in product_filtered])
                        violations_out_per_node_hidden   = set([element    for element in current_violation_out if element not in violations_out_per_node_detected])
                        if len(violations_out_per_node_detected) + len(violations_out_per_node_hidden) != len(current_violation_out):
                            print("%s + %s = %s" % (violations_out_per_node_detected, violations_out_per_node_hidden, current_violation_out))

                        

                        violations_smp_detected += violations_smp_per_node_detected
                        violations_smp_hidden   += violations_smp_per_node_hidden
                        violations_out_detected += violations_out_per_node_detected
                        violations_out_hidden   += violations_out_per_node_hidden
                        
                    except:
                        pass

                violation_total_time = 0
                for violation in violations_smp_detected:
                    violation_total_time += violation[1]
                for violation in violations_smp_hidden:
                    violation_total_time += violation[1]
                for violation in violations_out_detected:
                    violation_total_time += violation[1]
                for violation in violations_out_hidden:
                    violation_total_time += violation[1]

                print("%s@%d => %d" % (algo, compute_node_count, violation_total_time))

                export_csv_data(algo, compute_node_count, violations_smp_detected, violations_smp_hidden, violations_out_detected, violations_out_hidden)




################################################################################
# Find simulation matching and prepare R scripts
################################################################################

def export_clouds_data(algo1, algo2, node_count):
    print("%s and %s with %s" % (algo1, algo2, node_count))

    folder_name = "clouds/scripts/%d-%s-%s" % (node_count, algo1, algo2)

    execute_cmd(["mkdir", "-p", folder_name])

    render_template("template/cloud_script.jinja2", {"algo1": algo1, "algo2": algo2, "node_count": node_count, "duration": max_plot_time},   "%s/compare.r" % (folder_name))

    pass

for key in map_algos_size:
    algos = map_algos_size[key]
    node_count = key

    if len(algos) < 1:
        continue
    elif len(algos) == 1:
        algos += [algos[0]]

    for element in itertools.combinations(algos, min(2, len(algos))):
        export_clouds_data(element[0], element[1], node_count)

################################################################################
# Clean results folder
################################################################################
execute_cmd(["rm", "-r", "clouds/results"])
execute_cmd(["mkdir", "-p", "clouds/results"])

################################################################################
# Generate clouds figures
################################################################################


for key in map_algos_size:
    algos = map_algos_size[key]
    node_count = key

    for element in itertools.combinations(algos, min(2, len(algos))):

        script_folder_name = "clouds/scripts/%d-%s-%s" % (node_count, element[0], element[1])
        out_file_path = "clouds/results/%d-%s-%s.pdf" % (node_count, element[0], element[1])

        execute_cmd(["/usr/bin/env", "Rscript", "%s/compare.r" % (script_folder_name)])

        execute_cmd(["mv", "Rplots.pdf", out_file_path])

################################################################################
# Prepare R scripts for one simulation
################################################################################

def export_clouds_single_data(algo, node_count):
    print("%s with %s" % (algo, node_count))

    folder_name = "clouds/scripts/%d-%s" % (node_count, algo)

    execute_cmd(["mkdir", "-p", folder_name])

    render_template("template/cloud_single_script.jinja2", {"algo": algo, "node_count": node_count, "duration": max_plot_time},   "%s/compare.r" % (folder_name))

    pass

for key in map_algos_size:
    algos = map_algos_size[key]
    node_count = key

    for algo in algos:
        export_clouds_single_data(algo, node_count)

################################################################################
# Generate clouds figures
################################################################################


for key in map_algos_size:
    algos = map_algos_size[key]
    node_count = key

    for algo in algos:

        script_folder_name = "clouds/scripts/%d-%s" % (node_count, algo)
        out_file_path = "clouds/results/%d-%s.pdf" % (node_count, algo)

        execute_cmd(["/usr/bin/env", "Rscript", "%s/compare.r" % (script_folder_name)])

        execute_cmd(["mv", "Rplots.pdf", out_file_path])

<file_sep>/src/main/java/migration/Migrator.java
package migration;

import configuration.XHost;
import org.simgrid.msg.*;
import org.simgrid.msg.Process;

import configuration.XVM;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Random;

public class Migrator extends Process {
    public static boolean isEnd = false;

    public Migrator(Host host, String name, String[] args) {
        super(host, name, args);
    }

    @Override
    public void main(String[] args) throws MsgException {
        int load = 90;
        int dpIntensity = 90;

        // Prepare the hosts
        Host host1 = null;
        Host host2 = null;
        Host host3 = null;
        Host host4 = null;
        Host host5 = null;
        Host host6 = null;
        Host host7 = null;
        Host host8 = null;
        try {
            host1 = Host.getByName("node0");
            host2 = Host.getByName("node1");
            host3 = Host.getByName("node2");
            host4 = Host.getByName("node3");
            host5 = Host.getByName("node4");
            host6 = Host.getByName("node5");
            host7 = Host.getByName("node6");
            host8 = Host.getByName("node7");
        } catch (HostNotFoundException e) {
            Msg.critical(e.getMessage());
            e.printStackTrace();
            System.exit(1);
        }

        // Start a VM
        XVM[] xvms = new XVM[78];
        for(int i = 0 ; i < xvms.length; i++) {
            Host host = Host.getByName("node" + (i%4));
            XHost xhost = new XHost(host, 32*1024, 8, 800, 1250, null);
            xvms[i] = new XVM(
                    xhost,          // destination
                    "vm-" + i,         // name
                    1,              // # of VCPU
                    1 * 1024,       // RAM
                    125,           // BW
                    null,           // disk path
                    -1,             // disk size
                    125,           // migration BW
                    dpIntensity);   // dirty page rate

            xvms[i].start();
            xvms[i].setLoad(load);
            Msg.info(xvms[i].getName() + " started on host " + host.getName());
        }



        // Migrate the VM
        double host1Before = host1.getConsumedEnergy();
        double host2Before = host2.getConsumedEnergy();
        double start = Msg.getClock();
        int i = 0;
        for(XVM vm: xvms) {
            if(i < xvms.length)
                asyncMigrate(vm, host5);
            else if (i < xvms.length * 2 / 4)
                asyncMigrate(vm, host6);
            else if (i < xvms.length * 3/ 4)
                asyncMigrate(vm, host7);
            else
                asyncMigrate(vm, host8);
            i++;
        }
        double duration = Msg.getClock() - start;
        double host1After = host1.getConsumedEnergy();
        double host2After = host2.getConsumedEnergy();
        waitFor(10);
        isEnd = true;
        host1.off();
        host2.off();
        host5.off();
        waitFor(1000);

        double watt1 = (host1After - host1Before) / duration;
        double watt2 = (host2After - host2Before) / duration;
        Msg.info(String.format("End of migration\nConsumed energy:\nHost 1: %.2f\nHost 2: %.2f", watt1, watt2));

        try {
            File out = new File("migration_energy.dat");
            boolean empty = !out.exists();
            FileWriter writer = new FileWriter(out, true);

            if(empty)
                writer.write("# Load\tdpIntensity\ttime\thost 1\thost 2\n");

            Msg.info(String.format("%f %f %f", duration, host1Before, host1After));
            writer.write(String.format("%d\t%d\t\t%.2f\t%.2f\t%.2f\n", load, dpIntensity, duration, watt1, watt2));

            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        exit();
    }

    public static boolean isEnd() {
        return isEnd;
    }

    int nbThreads = 0;

    private void asyncMigrate(XVM vm, Host destHost) {
        try {
            String[] args = new String[2];

            args[0] = vm.getName();
            args[1] = destHost.getName();
            Random rand = new Random();
            Msg.info("Nbre Thread Inc: "+ (++nbThreads));
            new Process(Host.currentHost(),"Migrate-"+rand.nextDouble(),args) {
                public void main(String[] args) throws HostFailureException {
                    Host destHost = null;
                    VM vm = null;
                    try {
                        vm = VM.getVMByName(args[0]);
                        destHost = Host.getByName(args[1]);
                    } catch (Exception e) {
                        e.printStackTrace();
                        System.err.println("You are trying to migrate from/to a non existing node");
                    }
                    if(destHost != null){
                        vm.migrate(destHost);
                        //waitFor(10.0);
                    }
                    Msg.info("End of migration of VM " + args[0] + " to " + args[1]);
                    Msg.info("Nbre Thread Dec: "+ (--nbThreads));

                }
            }.start();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
<file_sep>/src/main/java/scheduling/hierarchical/snooze/AUX.java
package scheduling.hierarchical.snooze;

import configuration.SimulatorProperties;
import org.simgrid.msg.Host;
import org.simgrid.msg.Msg;

/**
 * Created by sudholt on 06/07/2014.
 */
public class AUX {
    static final String epInbox = "epInbox";                  // EP mbox

    static final String multicast = "multicast";              // GL/GM multicast mbox
    static Host multicastHost = null;

    static final String glElection = "glElection";            // HeartbeatGroup mbox

    static final long DefaultComputeInterval = 1;

    static final long HeartbeatInterval = SnoozeProperties.getHeartBeatPeriodicity();
    static final long HeartbeatTimeout = SnoozeProperties.getHeartBeatTimeout();

    static final double DeadTimeout = 600;
//    static final long DeadTimeout = SnoozeProperties.getHeartBeatPeriodicity()/3;
    static final double MessageReceptionTimeout = 0.2;

    static final int glLCPoolSize = Math.max(SimulatorProperties.getNbOfHostingNodes()/10, 1);
    static final int glGMPoolSize = Math.max((SimulatorProperties.getNbOfServiceNodes()-1)/10, 1);
    static final int gmLCPoolSize =
            Math.max(SimulatorProperties.getNbOfHostingNodes()/(SimulatorProperties.getNbOfServiceNodes()-1)/10, 1);

//    static final long PoolingTimeout = SimulatorProperties.getDuration(); // Timeout for worker tasks

    // constants for variants of Snooze alg.
    static final boolean GLElectionForEachNewGM = false;
    static final boolean GLElectionStopGM = true;
    public static final GroupLeader.AssignmentAlg assignmentAlg = GroupLeader.AssignmentAlg.BESTFIT;
//    public static final GroupLeader.AssignmentAlg assignmentAlg = GroupLeader.AssignmentAlg.ROUNDROBIN;

    static String glInbox(String glHost) { return glHost + "-glInbox"; }
    static String gmInbox(String gmHost) { return gmHost + "-gmInbox"; }
    static String lcInbox(String lcHost) { return lcHost + "-lcInbox"; }

    static double timeDiff(double oldTime) {
        return Msg.getClock()-oldTime;
    }

    static double durationToEnd() { return SimulatorProperties.getDuration() - Msg.getClock() + 0.01; }
}
<file_sep>/src/main/java/scheduling/distributed/dvms2/DVMSProcess.java
package scheduling.distributed.dvms2;

import org.simgrid.msg.*;
import org.simgrid.msg.Process;
import scheduling.distributed.dvms2.dvms.dvms2.DvmsActor;
import scheduling.distributed.dvms2.dvms.dvms3.LocalityBasedScheduler;
import simulation.SimulatorManager;

import java.net.UnknownHostException;

//Represents a server running on a worker node
//Currently, this server can only process on request at a time -> less concurrent access to the node object
public class DVMSProcess extends Process {

    private SGActor dvms;

    Long id;
    String name;

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Constructor
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public DVMSProcess(Host host, String name, String hostname, int port, SGNodeRef entropyActorRef, SGNodeRef snoozerActorRef) throws UnknownHostException  {
        super(host, String.format("%s", hostname, port));

        this.name = String.format("%s", hostname, port);
        this.id = nameToId(hostname);


        if(DvmsProperties.isLocalityBasedScheduler()) {
            this.dvms = new LocalityBasedScheduler(new SGNodeRef(String.format("%s", hostname, port), id), this, entropyActorRef, snoozerActorRef);
        } else {
            this.dvms = new DvmsActor(new SGNodeRef(String.format("%s", hostname, port), id), this, entropyActorRef, snoozerActorRef);
        }
    }

    public SGNodeRef self() {

        return this.dvms.self();
    }

    public static Long nameToId(String name) {

        Long result = -1L;
        try {
            result = Long.parseLong(name.substring(4, name.length()));
        } catch(Exception e) {
            e.printStackTrace();
        }

        return result;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Other methods
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////


    String mBox = "";

    @Override
    public void main(String[] args) throws MsgException {

        mBox = this.name;

        while(!SimulatorManager.isEndOfInjection()){

            try{

                MsgForSG req=(MsgForSG) Task.receive(mBox);
                Long reqId = nameToId(req.getSender().getHost().getName());

                dvms.receive(req.getMessage(), new SGNodeRef(req.getOrigin(), reqId), new SGNodeRef(req.getReplyBox(), -1L));
            } catch (Exception e) {
                Msg.info(String.format("Failure on %s", mBox));
                e.printStackTrace();
            }
        }

        Msg.info("End of server");
    }
}

<file_sep>/src/main/java/scheduling/hierarchical/snooze/msg/GMElecMsg.java
package scheduling.hierarchical.snooze.msg;

/**
 * Created by sudholt on 09/07/2014.
 */

public class GMElecMsg extends SnoozeMsg {
    public GMElecMsg(String name, String sendBox, String origin, String replyBox) {
        super(name, sendBox, origin, replyBox);
    }
}
<file_sep>/run_example.sh
#! /bin/bash

PID_FILE=/tmp/vmplaces.pid

source xprc

function do_abort() {
	echo Killing java process with PID `cat $PID_FILE`
	kill -9 `cat $PID_FILE`
	rm -f $PID_FILE
	exit 2
}

trap do_abort SIGINT

error=0

function run() {
	echo '----------------------------------------'
	echo "Running $algo $implem with $n_nodes compute and $n_service service nodes turning off hosts: $turn_off, load.mean=$mean, load.std=$std"
	echo "Command: java $VM_OPTIONS $SIM_ARGS simulation.Main $PROGRAM_ARGUMENTS"
	echo "Command: PROGRAM_ARGUMENTS $PROGRAM_ARGUMENTS"
	echo '----------------------------------------'
	java $VM_OPTIONS simulation.Main $PROGRAM_ARGUMENTS &
	pid=$!
	echo $pid > $PID_FILE
	wait $pid
	ret=$?

	echo java returned $ret

	if [ $ret -ne 0 ] && [ $ret -ne 134 ]
	then
		error=1
		exit $ret
	fi

	mkdir -p visu/events/$name
	cp events.json visu/events/$name/
}

#######################################
#                Main                 #
#######################################

# Number of hosting nodes
nodes='64'
abort=0

rm -rf logs/ffd

{
	run $nodes example scheduling.simple.ExampleReconfigurationPlanner false
} 2>&1 | tee run_all.log


if [ ! $error ]
	then
		visu/energy_plot.py run_all.log energy.dat
	fi
<file_sep>/src/main/java/scheduling/hierarchical/snooze/msg/LCChargeMsg.java
package scheduling.hierarchical.snooze.msg;

/**
 * Created by sudholt on 04/07/2014.
 */
public class LCChargeMsg extends SnoozeMsg {
    public LCChargeMsg(LCCharge lc, String sendBox, String origin, String replyBox) {
        super(lc, sendBox, origin, replyBox);
    }

    public static class LCCharge {
        private double procCharge;
        private int memUsed;
        private double timestamp;

        public LCCharge(double proc, int mem, double ts) {
            this.setProcCharge(proc); this.setMemUsed(mem); this.setTimestamp(ts);
        }

        public double getProcCharge() {
            return procCharge;
        }

        public void setProcCharge(double procCharge) {
            this.procCharge = procCharge;
        }

        public int getMemUsed() {
            return memUsed;
        }

        public void setMemUsed(int memUsed) {
            this.memUsed = memUsed;
        }

        public double getTimestamp() {
            return timestamp;
        }

        public void setTimestamp(double timestamp) {
            this.timestamp = timestamp;
        }
    }
}
<file_sep>/src/main/java/scheduling/SchedulerBuilder.java
package scheduling;

import configuration.SimulatorProperties;
import configuration.XHost;
import org.simgrid.msg.Msg;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;

/**
 * @author <NAME>
 * Singleton used to build the scheduler given in simulator.properties.
 */
public enum SchedulerBuilder {

    /**
     * Builder instance.
     */
    INSTANCE;

    /**
     * Scheduler class to instantiate.
     */
    private Class<?> schedulerClass = null;

    /**
     * Gets the scheduler class to instantiate later.
     */
    SchedulerBuilder() {
        try {
            schedulerClass = Class.forName(SimulatorProperties.getImplementation());
        } catch (ClassNotFoundException e) {
            Msg.critical("Scheduler class not found. Check the value simulator.implementation in the simulator properties file.");
            System.err.println(e);
            System.exit(-1);
        }
    }

    /**
     * Gets the builder instance.
     * @return instance
     */
    public static SchedulerBuilder getInstance() {
        return INSTANCE;
    }

    /**
     * Instantiates the scheduler.
     * @param xHosts xHosts
     * @return instantiated scheduler
     */
    public Scheduler build(Collection<XHost> xHosts) {
        Constructor<?> schedulerConstructor;
        try {
            schedulerConstructor = schedulerClass.getConstructor(Collection.class);
            return (Scheduler) schedulerConstructor.newInstance(xHosts);
        } catch (Exception e) {
            handleExceptions(e);
        } 

        return null;
    }

    /**
     * Instantiates the scheduler.
     * @param xHosts xHosts
     * @param id id
     * @return instantiated scheduler
     */
    public Scheduler build(Collection<XHost> xHosts, Integer id) {
        Constructor<?> schedulerConstructor;
        try {
            schedulerClass = Class.forName(SimulatorProperties.getImplementation());
            schedulerConstructor = schedulerClass.getConstructor(Collection.class, Integer.class);
            return (Scheduler) schedulerConstructor.newInstance(xHosts, id);
        } catch (Exception e) {
            handleExceptions(e);
        }
        return null;
    }

    /**
     * Handles builder methods exceptions. This will stop the program.
     * @param e thrown exception
     */
    private void handleExceptions(Exception e) {
        System.err.println(e);
        if (e instanceof NoSuchMethodException) {
            Msg.critical("Scheduler constructor not found. This should never happen!!");
        } else if (e instanceof InstantiationException) {
            Msg.critical("Scheduler instantiation issue");
        } else if (e instanceof IllegalAccessException) {
            Msg.critical("Scheduler constructor could not be accessed");
        } else if (e instanceof InvocationTargetException) {
            Msg.critical("Invocation target exception while instantiating the scheduler");
        } else {
            Msg.critical("Unhandled exception");
        }
        System.exit(-1);
    }
    
}
<file_sep>/visu/generate_detailed_graphs.py
#!/usr/bin/python
from __future__ import division
from pkg_resources import WorkingSet , DistributionNotFound
working_set = WorkingSet()

from numpy import array
import itertools

# Printing all installed modules
#print tuple(working_set)

# Detecting if module is installed
dependency_found = True
try:
    dep = working_set.require('Jinja2')
except DistributionNotFound:
    dependency_found  = False
    pass

if not dependency_found:
    try:
        # Installing it (anyone knows a better way?)
        from setuptools.command.easy_install import main as install
        install(['Jinja2'])
        print("run again as normal user to process results")
    except DistributionNotFound:
        print("run this script as sudo to install a missing template engine")
        pass
    sys.exit(0)


import csv
import subprocess
import time
import os
import json
import jinja2
import traceback

################################################################################
# Constant and parameters
################################################################################

duration = 3600

################################################################################
# Functions of the script
################################################################################
def execute_cmd(args):
	print "%s" % args
	# return "%s" % args
	out, err = subprocess.Popen(args,
                   shell=False,
                   stdout=subprocess.PIPE,
                   stderr=subprocess.PIPE).communicate()
	if not err == "":
		print err
	return out

def render_template(template_file_path, vars, output_file_path):
    templateLoader = jinja2.FileSystemLoader( searchpath="." )
    templateEnv = jinja2.Environment( loader=templateLoader )

    TEMPLATE_FILE = template_file_path
    template = templateEnv.get_template( TEMPLATE_FILE )

    templateVars = vars

    outputText = template.render( templateVars )
    with open(output_file_path, "w") as text_file:
        text_file.write(outputText)
        

################################################################################
# Clean data and scripts folders
################################################################################
execute_cmd(["rm", "-r", "detailed"])
execute_cmd(["mkdir", "detailed"])

################################################################################
# Detect algorithms used in experiments
################################################################################
algos = []
for dirname, dirnames, filenames in os.walk('./events'):
    # print path to all subdirectories first.
    for filename in filenames:
        if filename.endswith(".json"):
            with open("%s/%s" % (dirname, filename), 'r') as f:
                header_line = f.readline()
                header_data = json.loads(header_line)
                data = header_data["data"]
                algo = data["algorithm"]
                if not algo in algos:
                    algos += [algo]
# print algos

################################################################################
# Detect (server_count, vm_count) combination used in experiments
################################################################################
nodes_tuples     = []
vms_tuples       = []
nodes_vms_tuples = []
for dirname, dirnames, filenames in os.walk('./events'):
    # print path to all subdirectories first.
    for filename in filenames:
        if filename.endswith(".json"):
            with open("%s/%s" % (dirname, filename), 'r') as f:
                header_line = f.readline()
                header_data = json.loads(header_line)
                data = header_data["data"]

                compute_node_count = data["server_count"]
                service_node_count = data["service_node_count"]
                node_count = compute_node_count + service_node_count

                if not compute_node_count in nodes_tuples:
                    nodes_tuples += [compute_node_count]
                if not data["vm_count"] in vms_tuples:
                    vms_tuples += [data["vm_count"]]
                # nodes_vms_tuple = "%s-%s" % (data["server_count"], data["vm_count"])
                # if not nodes_vms_tuple in nodes_vms_tuples:
                #     nodes_vms_tuples += [nodes_vms_tuple]

# Order the tuples
nodes_tuples = sorted(nodes_tuples)
vms_tuples = sorted(vms_tuples)
nodes_vms_tuples = [str(tuple2[0])+"-"+str(tuple2[1]) for tuple2 in zip(nodes_tuples, vms_tuples)]
# nodes_vms_tuples = sorted(nodes_vms_tuples)

# print nodes_tuples
# print vms_tuples
# print nodes_vms_tuples

################################################################################
# Fill data maps with computed metrics
################################################################################

def export_csv_data(algo, node_count, computes, migrations, migrations_count, violations, reconfigurations):

    folder_name = "detailed/data/%s-%d" % (algo, node_count)

    execute_cmd(["mkdir", "-p", folder_name])

    render_template("template/cloud_data.jinja2", {"algo": algo, "node_count": node_count, "violations": computes,         "labels": ["type", "value"]}, "%s/detailed_computations.csv" % (folder_name))
    render_template("template/cloud_data.jinja2", {"algo": algo, "node_count": node_count, "violations": migrations_count, "labels": ["type", "value"]}, "%s/detailed_migrations_count.csv" % (folder_name))
    render_template("template/cloud_data.jinja2", {"algo": algo, "node_count": node_count, "violations": migrations,       "labels": ["type", "value"]}, "%s/detailed_migrations.csv" % (folder_name))
    render_template("template/cloud_data.jinja2", {"algo": algo, "node_count": node_count, "violations": violations_count, "labels": ["type", "value"]}, "%s/detailed_violations_count.csv" % (folder_name))
    render_template("template/cloud_data.jinja2", {"algo": algo, "node_count": node_count, "violations": violations,       "labels": ["type", "value"]}, "%s/detailed_violations.csv" % (folder_name))
    render_template("template/cloud_data.jinja2", {"algo": algo, "node_count": node_count, "violations": reconfigurations, "labels": ["type", "value"]}, "%s/detailed_reconfigurations.csv" % (folder_name))

map_algos_size = {}

metrics = ["migrations_count", "migrations", "computations", "violations_count", "violations", "reconfigurations"]

# variable that is used to detect "violation-out", "violation-normal" and "violation-sched":
# it will store the last line about "violations-out" or "violation-det", to detect if the next
# "violation" has been already processed!
last_line = None

algos_map = {}
for algo in algos:
    algos_map[algo] = {}
metrics_map = {}
for metric in metrics:
    metrics_map[metric] = {}

for dirname, dirnames, filenames in os.walk('./events'):
    # print path to all subdirectories first.
    for filename in filenames:
        if filename.endswith(".json"):
            with open("%s/%s" % (dirname, filename), 'r') as f:
                header_line = f.readline()
                header_data = json.loads(header_line)
                data = header_data["data"]
                algo = data["algorithm"]

                compute_node_count = data["server_count"]
                service_node_count = data["service_node_count"]
                node_count = compute_node_count + service_node_count
                
                nodes_vms_tuple = "%s-%s" % (data["algorithm"], compute_node_count)
                
                if not map_algos_size.has_key(compute_node_count):
                    map_algos_size[compute_node_count] = []

                map_algos_size[compute_node_count] += [algo]

                computes = []
                migrations_count = 0
                migrations = []
                violations_count = 0
                violations = []
                reconfigurations = []

                for line in f.readlines():
                    try:
                        data = json.loads(line)

                        if float(data["time"]) > duration:
                            continue

                        if data["event"] == "trace_event" and data["value"] == "migrate":
                            migration_duration = data["duration"]
                            migrations += [migration_duration]
                            migrations_count += 1

                        if data["event"] == "trace_event" and data["value"] == "compute":
                            compute_duration = data["duration"]
                            compute_result = data["data"]["state"]
                            computes += [compute_duration]

                        if data["event"] == "trace_event" and data["value"] == "violation":
                            violation_duration = data["duration"]
                            violations += [violation_duration]
                            violations_count += 1

                        if data["event"] == "trace_event" and data["value"] == "reconfigure":
                            reconfiguration_duration = data["duration"]
                            reconfigurations += [reconfiguration_duration]

                    except Exception as e:
                        # print traceback.format_exc()
                        pass

                algos_map[algo][compute_node_count] = {
                    "migrations_count": [migrations_count],
                    "migrations": migrations,
                    "reconfigurations": reconfigurations,
                    "computations": computes,
                    "violations_count": [violations_count],
                    "violations": violations
                }

                for metric in metrics:
                    if not metrics_map[metric].has_key(compute_node_count):
                        metrics_map[metric][compute_node_count] = {}

                metrics_map["migrations_count"][compute_node_count][algo] = [migrations_count]
                metrics_map["migrations"][compute_node_count][algo] = migrations
                metrics_map["computations"][compute_node_count][algo] = computes
                metrics_map["violations_count"][compute_node_count][algo] = [violations_count]
                metrics_map["violations"][compute_node_count][algo] = violations
                metrics_map["reconfigurations"][compute_node_count][algo] = reconfigurations
    
                f.seek(0)

                # export_csv_data(algo, compute_node_count, computes, migrations, violations, reconfigurations)

################################################################################
# Clean results folder
################################################################################
execute_cmd(["rm", "-r", "detailed/results"])
execute_cmd(["mkdir", "-p", "detailed/results"])

################################################################################
# Generate mean and std for each metric and algorith
################################################################################

node_numbers = nodes_tuples

legends = {
    "migrations_count": "migrations count", 
    "migrations": "migration time (s)", 
    "computations": "computation time (s)",
    "violations_count": "violations count", 
    "violations": "violation time (s)",
    "reconfigurations": "reconfigurations time (s)"
}

metrics_data = {}
for metric in metrics:
    metrics_data[metric] = {}
    for node_number in node_numbers:
        metrics_data[metric][node_number] = {}
        for algo in algos:
            metrics_data[metric][node_number][algo] = [0.0, 0.0]

for metric in metrics:
    for algo in algos:
        for node_number in node_numbers:
            nums = array(metrics_map[metric][node_number][algo])
            std = nums.std()
            mean = nums.mean()
            metrics_data[metric][node_number][algo] = ["%6s"  % "{0:0.2f}".format(mean), "%6s"  % "{0:0.2f}".format(std)]

algos_data = {}
for algo in algos:
    algos_data[algo] = {}
    for node_number in node_numbers:
        algos_data[algo][node_number] = {}
        for metric in metrics:
            algos_data[algo][node_number][metric] = [0.0, 0.0]

for algo in algos:
    for node_number in node_numbers:
        for metric in metrics:
            nums = array(algos_map[algo][node_number][metric])
            std = nums.std()
            mean = nums.mean()
            algos_data[algo][node_number][metric] = ["%6s"  % "{0:0.2f}".format(mean), "%6s"  % "{0:0.2f}".format(std)]

# print(metrics_data)
# print(algos_data)

################################################################################
# Prepare R scripts for each simulation
################################################################################

def export_detailed_single_metric(metrics_data, algos, node_numbers, metric, legend):
    print("%s with %s" % (metric, node_count))
    folder_name = "detailed/latex/%s" % (metric)
    execute_cmd(["mkdir", "-p", folder_name])
    render_template("template/detailed_metric_script.jinja2", {"algos": algos, "node_numbers": sorted(node_numbers), "x_axis": zip(nodes_tuples, vms_tuples), "data": metrics_data, "metric": metric, "algos": algos, "legend": legend},   "%s/detailed_%s.r" % (folder_name, metric))

def export_detailed_single_algo(algos_data, metrics, node_numbers, algo, legend):
    print("%s with %s" % (algo, node_count))
    folder_name = "detailed/latex/%s" % (algo)
    execute_cmd(["mkdir", "-p", folder_name])
    render_template("template/detailed_algo_script.jinja2", {"algo": algo, "node_numbers": sorted(node_numbers), "x_axis": zip(nodes_tuples, vms_tuples), "data": algos_data, "metrics": metrics, "metrics": metrics, "legend": legend},   "%s/detailed_%s.r" % (folder_name, algo))

legend = "TOTO"

for metric in metrics:
    export_detailed_single_metric(metrics_data, algos, node_numbers, metric, legend)

for algo in algos:
    export_detailed_single_algo(algos_data, metrics, node_numbers, algo, legend)

<file_sep>/src/main/java/scheduling/hierarchical/snooze/msg/TestFailGMMsg.java
package scheduling.hierarchical.snooze.msg;

/**
 * Created by sudholt on 20/07/2014.
 */
public class TestFailGMMsg extends SnoozeMsg {
    public TestFailGMMsg(String name, String sendBox, String origin, String replyBox) {
        super(name, sendBox, origin, replyBox);
    }
}
<file_sep>/src/main/java/migration/XVM.java
/* Copyright (c) 2014. The SimGrid Team.
 * All rights reserved.                                                     */

/* This program is free software; you can redistribute it and/or modify it
 * under the terms of the license (GNU LGPL) which comes with this package. */

package migration;

import org.simgrid.msg.Msg;
import org.simgrid.msg.VM;
import org.simgrid.msg.Host;
import org.simgrid.msg.HostNotFoundException;
import org.simgrid.msg.HostFailureException;

public class XVM extends VM {
  private int dpIntensity;
  private int netBW;
  private int ramsize;
  private int currentLoad;

  private Daemon daemon;

  public XVM(Host host, String name,
    int nbCores, int ramsize, int netBW, String diskPath, int diskSize, int migNetBW, int dpIntensity){
    super(host, name, ramsize, netBW, dpIntensity);
    this.currentLoad = 0;
    this.netBW = netBW ;
    this. dpIntensity = dpIntensity ;
    this.ramsize= ramsize;
    this.daemon = new Daemon(this, 100);
  }

  public void setLoad(int load){  
    if (load >0) {
      this.setBound(this.getSpeed()*load/100);
      //    this.getDaemon().setLoad(load);
      daemon.resume();
    } else{
      daemon.suspend();
    }
    currentLoad = load ;
  }

  public void start(){
    super.start();
    try {
      daemon.start();
    } catch (Exception e) {
      e.printStackTrace();
    }
    this.setLoad(0);
  }

  public Daemon getDaemon(){
    return this.daemon;
  }

  public int getLoad(){
    System.out.println("Remaining comp:" + this.daemon.getRemaining());
    return this.currentLoad;
  }

  public void migrate(Host host) throws HostFailureException {
    Msg.info("Start migration of VM " + this.getName() + " to " + host.getName());
    Msg.info("    currentLoad:" + this.currentLoad + "/ramSize:" + this.ramsize + "/dpIntensity:" + this.dpIntensity 
        + "/remaining:" + String.format(java.util.Locale.US, "%.2E",this.daemon.getRemaining()));
    try{
      super.migrate(host);
    } catch (Exception e){
      Msg.info("Something wrong during the live migration of VM "+this.getName());
      throw new HostFailureException(); 
    }
    this.setLoad(this.currentLoad); //Fixed the fact that setBound is not propagated to the new node.
    Msg.info("End of migration of VM " + this.getName() + " to node " + host.getName());
  }
}
<file_sep>/src/main/java/scheduling/hierarchical/snooze/Multicast.java
package scheduling.hierarchical.snooze;

import org.simgrid.msg.*;
import org.simgrid.msg.Process;
import scheduling.hierarchical.snooze.msg.*;
import simulation.SimulatorManager;

import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by sudholt on 13/07/2014.
 */
public class Multicast extends Process {
    private String name;
    private Host host;
    private String inbox;
    String glHostname;  //@ Make private
    private double glTimestamp;
    private boolean glDead = false;
    private double lastPromotionOrElection;
    private boolean electingOrPromoting = false;
    private ThreadPool newLCPool;
    private ThreadPool newGMPool;
    ConcurrentHashMap<String, GMInfo> gmInfo = new ConcurrentHashMap<>();  //@ Make private
    ConcurrentHashMap<String, LCInfo> lcInfo = new ConcurrentHashMap<>();  //@ Make private

    public Multicast(Host host, String name) {
        super(host, name);
        this.host = host;
        this.name = name;
        this.inbox = AUX.multicast;
        this.glHostname = "";
        AUX.multicastHost = host;
    }

    @Override
    public void main(String[] strings) {
        int n = 1;

        Test.multicast = this;

        newLCPool = new ThreadPool(this, RunNewLC.class.getName(), AUX.glLCPoolSize);
        newLCPool = new ThreadPool(this, RunNewGM.class.getName(), AUX.glGMPoolSize);
        Logger.debug("[MUL.main] noLCWorkers: " + AUX.glLCPoolSize);

        procRelayGLBeats();
        procRelayGMBeats();
        while (!SimulatorManager.isEndOfInjection()) {
            try {
                SnoozeMsg m = (SnoozeMsg) Task.receive(inbox, AUX.durationToEnd());
                handle(m);
                glDead();
                gmDead();
                if(SnoozeProperties.shouldISleep()) sleep(AUX.DefaultComputeInterval);
            } catch (HostFailureException e) {
                Logger.exc("[MUL.main] HostFailureException");
            } catch (TimeoutException e) {
                glDead();
                gmDead();
            } catch (Exception e) {
                String cause = e.getClass().getName();
                Logger.err("[MUL.main] PROBLEM? Exception: " + host.getName() + ": " + cause);
                e.printStackTrace();
            }
        }
    }

    /**
     * Receive and relay GL heartbeats
     * @param m
     */
    public void handle(SnoozeMsg m) {
     //   Logger.debug("New message :" + m);
        String cs = m.getClass().getSimpleName();
        switch (cs) {
            case "GLElecMsg": handleGLElec(m); break;
//            case "NewGMMsg" : handleNewGM(m);  break;
            case "TermGMMsg": handleTermGM(m); break;
            case "SnoozeMsg":
                Logger.err("[MUL(SnoozeMsg)] Unknown message" + m);
                break;
        }
    }

    void handleGLElec(SnoozeMsg m) {
//        Logger.debug("[MUL(GLElecMsg)] " + m);

        if (AUX.timeDiff(lastPromotionOrElection) > AUX.HeartbeatTimeout || lastPromotionOrElection == 0
                || AUX.GLElectionForEachNewGM) {
           // No recent leaderElection
            leaderElection();
        } else {
            // Leader recently elected
            Logger.info("[MUL(GLElecMsg)] GL election on-going or recent: " + m);
        }
    }

    void handleTermGM(SnoozeMsg m) {
        ArrayList<String> orphanLCs = new ArrayList<String>();

        String gm = (String) m.getMessage();
        Logger.debug("[MUL(TermGM)] GM, gmInfo: " + gm + ", " + gmInfo.get(gm));
        gmInfo.remove(gm);
//        for (String lc: lcInfo.keySet()) {
//            if (lcInfo.get(lc).equals(gm)) orphanLCs.add(lc);
//        }
    }

    /**
     * GL dead
     */
    void glDead() {
        if (!glDead) return;
        Logger.err("[MUL.glDead] GL dead, trigger leader election: " + glHostname);
        leaderElection();
    }

    /**
     * GM dead
     */
    void gmDead() {
        ArrayList<String> deadGMs = new ArrayList<String>();
        ArrayList<String> orphanLCs = new ArrayList<String>();

        for (String gm: gmInfo.keySet()) {
            GMInfo gi = gmInfo.get(gm);
            if (gi == null || AUX.timeDiff(gmInfo.get(gm).timestamp) <= AUX.HeartbeatTimeout
                    || gi.joining) {
//                Logger.err("[MUL.gmDead] GM: " + gm + " TS: " + gi.timestamp);
                continue;
            }
            deadGMs.add(gm);

            // Identify LCs of dead GMs
            for (String lc: lcInfo.keySet()) {
                if (lcInfo.get(lc).gmHost.equals(gm)) orphanLCs.add(lc);
            }
        }

        // Remove dead GMs and associated LCs
        for (String gm: deadGMs) {
            Logger.imp("[MUL.gmDead] GM removed: " + gm + ", " + gmInfo.get(gm).timestamp);
            gmInfo.remove(gm);
//            leaderElection();
        }
        for (String lc: orphanLCs) {
            lcInfo.remove(lc);
            Logger.imp("[MUL.gmDead] LC removed: " + lc);
        }
    }

    boolean gmPromotion(String gm) {
        SnoozeMsg m;
        String elecMBox = AUX.gmInbox(gm) + "-MulticastElection";
        boolean success = false;
        // Send GL creation request to GM
        m = new GMElecMsg(null, AUX.gmInbox(gm), null, elecMBox);
        m.send();
//                Logger.info("[MUL.leaderElection] GM notified: " + m);

        boolean msgReceived = false;
        try {
            m = (SnoozeMsg) Task.receive(elecMBox, AUX.MessageReceptionTimeout);
//                    Logger.debug("[MUL.leaderElection] Msg.received for GM: " + gm + ", " + m);
        } catch (Exception e) {
            e.printStackTrace();
        }
        success =
                m.getClass().getSimpleName().equals("GLElecStopGMMsg") && gm.equals((String) m.getMessage());
//                Logger.info("[MUL.leaderElection] GM->GL: " + m);
        if (success) {
            String newLeader = (String) m.getMessage();
            if (!glHostname.isEmpty() && !newLeader.equals(glHostname)) {
                m = new TermGLMsg(name, AUX.glInbox(glHostname), host.getName(), null);
                Logger.debug("[MUL.leaderElection] GL termination message: " + m);
                m.send();
            }
            glHostname = newLeader;
            glTimestamp = Msg.getClock();
            glDead = false;
            m = new GLElecStopGMMsg(name, AUX.gmInbox(gm), null, null);
            m.send();
            Logger.imp("[MUL.leaderElection] New leader elected: " + m);
        } else Logger.err("[MUL.leaderElection] GM promotion failed: " + gm);

        return success;
    }


    /**
     * Election of a new GL: promote a GM if possible, create new GL instance
     */
    void leaderElection() {
        if (gmInfo.isEmpty()) {
            // Ex-nihilo GL creation
            GroupLeader gl = new GroupLeader(Host.currentHost(), "groupLeader");
            try {
                gl.start();
            } catch (Exception e) {
                e.printStackTrace();
            }
            Test.gl = gl;
            // Deployment on the Multicast node! Where should it be deployed?
            glHostname = gl.getHost().getName();  // optimization
            glTimestamp = Msg.getClock();
            glDead = false;
            Logger.err("[MUL.leaderElection] New leader ex-nihilo on: " + glHostname);
        } else {
            SnoozeMsg m = null;

            // Leader election: select GM, send promotion message
            ArrayList<String> gms = new ArrayList<String>(gmInfo.keySet());
            int i = 0;
            boolean success = false;
            String oldGL = "";
            String gm = "";
            do {
                Logger.debug("[MUL.leaderElection] Round: " + i);
                gm = gms.get(i % gms.size());
                success = gmPromotion(gm);
                i++;
            } while (i<10 && !success);
            if (!success) {
                Logger.err("MUL(GLElec)] Leader election failed 10 times");
                return;
            } else lastPromotionOrElection = Msg.getClock();
            Logger.imp("[MUL.leaderElection] Finished: " + glHostname + ", " + m);
        }
    }

    /**
     * Relay GL beats to EP, GMs and joining LCs
     */
    void relayGLBeats(SnoozeMsg m) {
        // Get timestamp
        String gl = (String) m.getOrigin();
        if ((glHostname == "" || glDead) && !gl.isEmpty()) {
            glHostname = gl;
            glDead = false;
            Logger.err("[MUL.relayGLBeats] GL initialized: " + glHostname);
        }
        if (glHostname != gl) {
            Logger.err("[MUL.relayGLBeats] Multiple GLs: " + glHostname + ", " + gl);
            return;
        }
        glTimestamp = (double) m.getMessage();

        // Relay GL beat to EP, GMs and LCs
        int i = 0;
        if (!glHostname.isEmpty()) {
            new RBeatGLMsg(glTimestamp, AUX.epInbox, glHostname, null).send();
            Logger.info("[MUL.relayGLbeat] Beat relayed to: " + AUX.epInbox);
            for (String gm : gmInfo.keySet()) {
                m = new RBeatGLMsg(glTimestamp, AUX.gmInbox(gm)+"-glBeats", glHostname, null);
//                m.send();
                try {
                    GroupManager g = Test.gmsCreated.get(gm);
                    g.glBeats(m);
                } catch (NullPointerException e) {
                    Logger.exc("[MUL.relayGLBeats] NullPointer, GM: " + gm);
                    gmInfo.remove(gm);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                Logger.info("[MUL.relayGLbeats] Beat relayed to GM: " + m);
            }
            for (String lc : lcInfo.keySet()) {
                LCInfo lv = lcInfo.get(lc);
                if (lv.joining) {
                    m = new RBeatGLMsg(glTimestamp, AUX.lcInbox(lv.lcHost), glHostname, null);
                    m.send();
                    i++;
//                    Logger.debug("[MUL.relayGLBeats] To LC: " + m);
                }
            }
        } else Logger.err("[MUL] No GL");
        Logger.imp("[MUL.relayGLBeats] GL beat received/relayed: " + glHostname + ", " + glTimestamp
                + ", #GMs: " + gmInfo.size() + ", # join. LCs: " + i);
    }

    /**
     * Relay GM beats to LCs
     */
    void relayGMBeats(GroupManager g, double ts) {
        String gm = g.host.getName();
        RBeatGMMsg m = new RBeatGMMsg(g, AUX.glInbox(glHostname)+"-gmPeriodic", gm, null);
//        m.send();
//        Test.gl.handleGMInfo(m);
        Logger.imp("[MUL.relayGMBeats] " + m);

        // Send to LCs
        int i = 0;
        for (String lc: g.lcInfo.keySet()) {
            LCInfo lci = lcInfo.get(lc);
            if (lci != null) {
                String gmLc = lci.gmHost;
//            Logger.debug("[MUL.relayGMBeats] LC: " + lc + ", GM: " + gm);
                if (gm.equals(gmLc)) {
                    GMInfo gmi = gmInfo.get(gm);
                    m = new RBeatGMMsg(g, AUX.lcInbox(lc) + "-gmBeats", gm, null);
                    LocalController lco = null;
                    try {
                        lco = Test.lcsJoined.get(lc).lco;
                        lco.handleGMBeats(m);
                    } catch (NullPointerException e) {
                        Logger.exc("[MUL.relayGMBeats] NullPointer, LC: " + lc + ", " + m);
                        lcInfo.remove(lc);
                    }
                    i++;
                    Logger.info("[MUL.relayGMBeats] To LC: " + lc + ", "+ lco + ", " + m);
                }
            }
        }
        Logger.imp("[MUL.relayGMBeats] GL beat received/relayed: " + gm + ", " + Msg.getClock()
                + ", #LCs: " + i);
    }

    public class RunNewGM implements Runnable {
        public RunNewGM() {};

        @Override
        public void run() {
            try {
                SnoozeMsg m;
                m = (SnoozeMsg) Task.receive(inbox + "-newGM", AUX.durationToEnd());
//                m = (SnoozeMsg) Task.receive(inbox + "-newGM", AUX.PoolingTimeout);
                Logger.info("[MUL.RunNewGM] " + m);
                String gm = ((GroupManager) m.getMessage()).host.getName();
                gmInfo.put(gm, new GMInfo(AUX.gmInbox(gm), Msg.getClock(), true));
                Logger.imp("[MUL(RunNewGM)] GM added: " + gm + ", " + m + ", " + lastPromotionOrElection);
                if (!glHostname.isEmpty() && (lastPromotionOrElection == 0.0
                        || AUX.timeDiff(lastPromotionOrElection) <= AUX.HeartbeatTimeout)) {
                    m = new RBeatGLMsg(glTimestamp, AUX.gmInbox(gm) + "-glBeats", glHostname, null);
                    m.send();
                    Logger.imp("[MUL(RunNewGM)] No promotion: " + m);
                    return;
                }
                boolean success = false;
                if (!electingOrPromoting) {
                    electingOrPromoting = true;
                    success = gmPromotion(gm);
                }
                if (!success) Logger.err("[MUL(RunNewGM)] GM Promotion FAILED: " + gm);
                else {
                    lastPromotionOrElection = Msg.getClock();
                    Logger.imp("[MUL(RunNewGM)] GM Promotion succeeded: " + gm);
                }
            } catch (TimeoutException e) {
                Logger.exc("[MUL.RunNewGM] PROBLEM? Timeout Exception");
            } catch (HostFailureException e) {
                Logger.err("[MUL.RunNewGM] HostFailure Exception should never happen!: " + host.getName());
            } catch (Exception e) {
                Logger.exc("[MUL.RunNewGM] Exception");
                e.printStackTrace();
            }
        }
    }

    public class RunNewLC implements Runnable {
        public RunNewLC() {};

        @Override
        public void run() {
            NewLCMsg m;
            try {
                m = (NewLCMsg) Task.receive(inbox + "-newLC", AUX.durationToEnd());
//                m = (NewLCMsg) Task.receive(inbox + "-newLC", AUX.PoolingTimeout);
                Logger.info("[MUL.RunNewLC] " + m);
                if (m.getMessage() == null) {
                    // Add LC
                    lcInfo.put(m.getOrigin(), new LCInfo(m.getOrigin(), "", Msg.getClock(), true));
                    Logger.info("[MUL.RunNewLC] LC temp. joined: " + m);
                } else {
                    // End LC join phase
                    String lc = m.getOrigin();
                    String gm = (String) m.getMessage();
                    lcInfo.put(lc, new LCInfo(lc, gm, Msg.getClock(), false));
                    m = new NewLCMsg(gm, m.getReplyBox(), null, null);
                    m.send();
                    Logger.imp("[MUL.RunNewLC] LC integrated: " + m);
                }
            } catch (TimeoutException e) {
                Logger.exc("[MUL.RunNewLC] PROBLEM? Timeout Exception");
            } catch (HostFailureException e) {
                Logger.err("[MUL.RunNewLC] HostFailure Exception should never happen!: " + host.getName());
            } catch (Exception e) {
                Logger.exc("[MUL.RunNewLC] Exception");
                e.printStackTrace();
            }
        }
    }

    /**
     * Relays GL beats
     */
    void procRelayGLBeats() {
        try {
            new Process(host, host.getName() + "-relayGLBeats") {
                public void main(String[] args) {
                    while (!SimulatorManager.isEndOfInjection()) {
                        try {
                            gmDead();
                            // Get incoming message from GL
                            SnoozeMsg m = (SnoozeMsg) Task.receive(inbox + "-relayGLBeats", AUX.durationToEnd());
                            Logger.info("[MUL.procRelayGLBeats] " + m);
                            relayGLBeats(m);
                            if(SnoozeProperties.shouldISleep())
                                sleep(AUX.DefaultComputeInterval);
                        } catch (HostFailureException e) {
                            Logger.err("[MUL.main] HostFailure Exc. should never happen!: " + host.getName());
                            break;
                        } catch (Exception e) {
                            Logger.exc("[MUL.procNewLC] Exception");
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
        } catch (Exception e) { e.printStackTrace(); }
    }

    /**
     * Relays GM beats
     */
    void procRelayGMBeats() {
        try {
            new Process(host, host.getName() + "-relayGMBeats") {
                public void main(String[] args) {
                    while (!SimulatorManager.isEndOfInjection()) {
                        try {
                            glDead();
                            SnoozeMsg m = (SnoozeMsg) Task.receive(inbox + "-relayGMBeats", AUX.durationToEnd());
                            Logger.info("[MUL.procRelayGMBeats] " + m);
                            String gm = m.getOrigin();
                            double ts = (double) Msg.getClock();
                            if (gmInfo.containsKey(gm)) {
                                GMInfo gi = gmInfo.get(gm);
                                gmInfo.put(gm, new GMInfo(gi.replyBox, ts, gi.joining));
                            }
                            else Logger.err("[MUL.procRelayGMBeats] Unknown GM: " + m);
                            relayGMBeats(((GroupManager) m.getMessage()), ts);
                            if(SnoozeProperties.shouldISleep())
                                sleep(AUX.DefaultComputeInterval);
                        } catch (HostFailureException e) {
                            Logger.err("[MUL.procRelayGMBeats] HostFailure Exc. should never happen!: " + host.getName());
                        } catch (Exception e) {
                            Logger.exc("[MUL.procRelayGMBeats] Exception");
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
        } catch (Exception e) { e.printStackTrace(); }
    }


    class GMInfo {
        String replyBox;
        double timestamp;
        boolean joining;

        GMInfo(String rb, double ts, boolean joining) {
            this.replyBox = rb; this.timestamp = ts; this.joining = joining;
        }
    }

    class LCInfo {
        String lcHost;
        String gmHost;
        double timestamp;
        boolean joining;

        LCInfo(String lc, String gm, double ts, boolean joining) {
            this.lcHost = lc; this.gmHost = gm; this.timestamp = ts; this.joining = joining;
        }
    }
}
<file_sep>/src/main/java/scheduling/hierarchical/snooze/msg/NewGMMsg.java
package scheduling.hierarchical.snooze.msg;

import scheduling.hierarchical.snooze.GroupManager;

/**
 * Created by sudholt on 29/06/2014.
 */
public class NewGMMsg extends SnoozeMsg {
    public NewGMMsg(GroupManager gm, String sendBox, String origin, String replyBox) {
        super(gm, sendBox, origin, replyBox);
    }
}
<file_sep>/src/main/java/scheduling/distributed/dvms2/TimeoutSnoozerProcess.java
package scheduling.distributed.dvms2;

import org.simgrid.msg.*;
import org.simgrid.msg.Process;
import scheduling.distributed.dvms2.dvms.timeout.TimeoutSnoozerActor;
import simulation.SimulatorManager;

import java.net.UnknownHostException;

/**
 * Created by jonathan on 24/11/14.
 */
public class TimeoutSnoozerProcess extends Process {

    private SGActor timeoutSnoozerActor;
    private String name;
    private long id;

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Constructor
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public TimeoutSnoozerProcess(Host host, String name, String hostname, int port) throws UnknownHostException {
        super(host, String.format("%s-timeoutsnoozer", hostname, port));
        this.name = String.format("%s-timeoutsnoozer", hostname, port);
        this.id = nameToId(hostname);
        this.timeoutSnoozerActor = new TimeoutSnoozerActor(new SGNodeRef(this.name, id),  host);
    }

    public SGNodeRef self() {
        return this.timeoutSnoozerActor.self();
    }

    public static Long nameToId(String name) {

        Long result = -1L;
        try {
            result = Long.parseLong(name.substring(4, name.length()));
        } catch(Exception e) {
            e.printStackTrace();
        }

        return result;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Other methods
    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////


    String mBox = "";

    @Override
    public void main(String[] args) throws MsgException {

        mBox = this.name;

        while(!SimulatorManager.isEndOfInjection()){

            try{

                MsgForSG req=(MsgForSG) Task.receive(mBox);
                Long reqId = nameToId(req.getSender().getHost().getName());

                timeoutSnoozerActor.receive(req.getMessage(), new SGNodeRef(req.getOrigin(), reqId), new SGNodeRef(req.getReplyBox(), -1L));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        Msg.info("End of server");
    }
}
<file_sep>/Dockerfile
FROM ubuntu:20.04
MAINTAINER Badock

ARG DEBIAN_FRONTEND=noninteractive

# Enable the APT via HTTP
RUN apt update
RUN apt install -y apt-transport-https

# Download dependencies
# RUN echo "deb https://dl.bintray.com/sbt/debian /" | tee -a /etc/apt/sources.list.d/sbt.list
# RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2EE0EA64E40A89B84B2DF73499E82A75642AC823
RUN apt update
RUN apt install -y simgrid wget

# Install openjdk
RUN apt install -y openjdk-8-jdk

# # Install scala
# RUN apt install -y scala

# Install sbt
#RUN curl -L -o sbt.deb http://dl.bintray.com/sbt/debian/sbt-0.13.15.deb
RUN wget http://dl.bintray.com/sbt/debian/sbt-0.13.15.deb --no-check-certificate -O sbt.deb
RUN dpkg -i sbt.deb
RUN apt update
RUN apt install -y sbt

# Clone projects
#   VMPlaceS
RUN apt install -y git
RUN git clone -b master https://github.com/BeyondTheClouds/VMPlaceS.git

# Change the working directory
WORKDIR /VMPlaceS

# Download the jar provided by the Simgrid project
RUN wget http://gforge.inria.fr/frs/download.php/file/37149/simgrid-3_17.jar --no-check-certificate -O lib/simgrid.jar

# Compile the project and create a "fatjar"
RUN sbt clean
RUN sbt update
RUN sbt assembly

# Run the example
RUN java -Xmx4G -d64 -cp target/simulation.jar simulation.SimpleMain --algo=example --duration 1800 --nb_hosts=10 --nb_vms=93 --load_mean=60.0 2>&1 | grep "MSG_main finished; Terminating the simulation..."
<file_sep>/ALGORITHMS.md
# How to change the placement algorithm to test

_This feature is disponible for centralized algorithms only._

Two centralized algorithms are already implemented:

- BtrPlace
- Entropy

You can find them in the `scheduling.centralized` java package. 

If you want to test another one, start at step 1. Otherwise, go directly to step 2.

## 1- Implement the algorithm

### 1.1- Create the architecture

Create a package named after the algorithm you are to implement in the `centralized` package.

### 1.2- Write the code

Create a class named after the algorithm you are to implement in the package newly created. It must extends the `AbstractScheduler`, which implements the `Scheduler` interface.

## 2- Choose the algorithm to run

Open the `config/simulator.properties` file and find the `simulator.implementation` property. Write the fully qualified name of the class implementing the algorithm you want to test.<file_sep>/visu/template/load_script.jinja2
#!/usr/bin/Rscript

data <- read.table("loads/data/{{algo}}-{{node_count}}/load.csv", header=T,sep=",")
attach(data)

data2 <- setNames(aggregate(load ~ round(time), data, mean, na.rm=TRUE), c("time", "load"))
detach(data)
attach(data2)

# Second graph
# 		Calculate violation times for dvms and entropy

g_range <- range(0, 101)

plot(load ~ time, type="o", col="blue", ylim=g_range,
   axes=FALSE, ann=FALSE, pch="")

# 		Make x axis using experiments names
axis(1, c(0, 1000, 2000, 3000, 3600))
axis(2, c(0, 20, 40, 60, 80, 100), c("0%", "20%", "40%", "60%", "80%", "100%"))
# 		Make y axis with horizontal labels that display ticks at 
# 		every 4 marks. 4*0:g_range[2] is equivalent to c(0,4,8,12).
#load_node0_50.csv

# 		Create box around plot
box()

# 		Graph entropy with red dashed line and square points

abline(h=70,col="black",lty=2)
text(1.1, (70+g_range[2]/40), "    70%", col = "black")

# 		Create a title with a red, bold/italic font
title(main="Load of the cluster\nConsolidation rate= 10VMs/PM, Average VM load = 70%", col.main="red", font.main=4)

# 		Label the x and y axes with dark green text
title(xlab="Time (s)", col.lab=rgb(0,0.5,0))
title(ylab="Load (%)", col.lab=rgb(0,0.5,0))

# 		Create a legend at (1, g_range[2]) that is slightly smaller 
# 		(cex) and uses the same line colors and points used by 
# 		the actual plots 
legend(1, g_range[2], c("load"), cex=0.8, 
   col=c("blue"), pch="", lty=1:2);<file_sep>/visu/generate_hidden_violation.py
#!/usr/bin/python
from __future__ import division
from pkg_resources import WorkingSet , DistributionNotFound
working_set = WorkingSet()

import itertools

# Printing all installed modules
#print tuple(working_set)

# Detecting if module is installed
dependency_found = True
try:
    dep = working_set.require('Jinja2')
except DistributionNotFound:
    dependency_found  = False
    pass

if not dependency_found:
    try:
        # Installing it (anyone knows a better way?)
        from setuptools.command.easy_install import main as install
        install(['Jinja2'])
        print("run again as normal user to process results")
    except DistributionNotFound:
        print("run this script as sudo to install a missing template engine")
        pass
    sys.exit(0)


import csv
import subprocess
import time
import os
import json
import jinja2
import traceback

################################################################################
# Constant and parameters
################################################################################

duration = 3600

################################################################################
# Functions of the script
################################################################################
def execute_cmd(args):
    print "%s" % args
    # return "%s" % args
    out, err = subprocess.Popen(args,
                   shell=False,
                   stdout=subprocess.PIPE,
                   stderr=subprocess.PIPE).communicate()
    if not err == "":
        print err
    return out

def render_template(template_file_path, vars, output_file_path):
    templateLoader = jinja2.FileSystemLoader( searchpath="." )
    templateEnv = jinja2.Environment( loader=templateLoader )

    TEMPLATE_FILE = template_file_path
    template = templateEnv.get_template( TEMPLATE_FILE )

    templateVars = vars

    outputText = template.render( templateVars )
    with open(output_file_path, "w") as text_file:
        text_file.write(outputText)
        

################################################################################
# Clean data and scripts folders
################################################################################
execute_cmd(["rm", "-r", "clouds"])
execute_cmd(["mkdir", "clouds"])

################################################################################
# Detect algorithms used in experiments
################################################################################
algos = []
for dirname, dirnames, filenames in os.walk('./events'):
    # print path to all subdirectories first.
    for filename in filenames:
        if filename.endswith(".json"):
            with open("%s/%s" % (dirname, filename), 'r') as f:
                header_line = f.readline()
                header_data = json.loads(header_line)
                data = header_data["data"]
                algo = data["algorithm"]
                if not algo in algos:
                    algos += [algo]
print algos

################################################################################
# Detect (server_count, vm_count) combination used in experiments
################################################################################
nodes_tuples     = []
vms_tuples       = []
nodes_vms_tuples = []
for dirname, dirnames, filenames in os.walk('./events'):
    # print path to all subdirectories first.
    for filename in filenames:
        if filename.endswith(".json"):
            with open("%s/%s" % (dirname, filename), 'r') as f:
                header_line = f.readline()
                header_data = json.loads(header_line)
                data = header_data["data"]

                compute_node_count = data["server_count"]
                service_node_count = data["service_node_count"]
                node_count = compute_node_count + service_node_count

                if not compute_node_count in nodes_tuples:
                    nodes_tuples += [compute_node_count]
                if not data["vm_count"] in vms_tuples:
                    vms_tuples += [data["vm_count"]]
                # nodes_vms_tuple = "%s-%s" % (data["server_count"], data["vm_count"])
                # if not nodes_vms_tuple in nodes_vms_tuples:
                #     nodes_vms_tuples += [nodes_vms_tuple]

# Order the tuples
nodes_tuples = sorted(nodes_tuples)
vms_tuples = sorted(vms_tuples)
nodes_vms_tuples = [str(tuple2[0])+"-"+str(tuple2[1]) for tuple2 in zip(nodes_tuples, vms_tuples)]
# nodes_vms_tuples = sorted(nodes_vms_tuples)

print nodes_tuples
print vms_tuples
print nodes_vms_tuples

################################################################################
# Fill data maps with computed metrics
################################################################################

def export_csv_data(algo, node_count, violations_smp_detected, violations_smp_hidden, violations_out_detected, violations_out_hidden):

    folder_name = "clouds/data/%s-%d" % (algo, node_count)

    execute_cmd(["mkdir", "-p", folder_name])

    render_template("template/cloud_data.jinja2", {"algo": algo, "node_count": node_count, "violations": violations_smp_detected, "labels": ["smp_det_time", "smp_det_duration", "node", "type"]}, "%s/violations_smp_det.csv" % (folder_name))
    render_template("template/cloud_data.jinja2", {"algo": algo, "node_count": node_count, "violations": violations_smp_hidden,   "labels": ["smp_hid_time", "smp_hid_duration", "node", "type"]}, "%s/violations_smp_hid.csv" % (folder_name))
    render_template("template/cloud_data.jinja2", {"algo": algo, "node_count": node_count, "violations": violations_out_detected, "labels": ["out_det_time", "out_det_duration", "node", "type"]}, "%s/violations_out_det.csv" % (folder_name))
    render_template("template/cloud_data.jinja2", {"algo": algo, "node_count": node_count, "violations": violations_out_hidden,   "labels": ["out_hid_time", "out_hid_duration", "node", "type"]}, "%s/violations_out_hid.csv" % (folder_name))

map_algos_size = {}

map_hidden_violation_count   = {}
map_detected_violation_count = {}
map_detected_violation_ratio = {}


# variable that is used to detect "violation-out", "violation-normal" and "violation-sched":
# it will store the last line about "violations-out" or "violation-det", to detect if the next
# "violation" has been already processed!
last_line = None

for dirname, dirnames, filenames in os.walk('./events'):
    # print path to all subdirectories first.
    for filename in filenames:
        if filename.endswith(".json"):
            with open("%s/%s" % (dirname, filename), 'r') as f:
                header_line = f.readline()
                header_data = json.loads(header_line)
                data = header_data["data"]
                algo = data["algorithm"]

                compute_node_count = data["server_count"]
                service_node_count = data["service_node_count"]
                node_count = compute_node_count + service_node_count
                
                nodes_vms_tuple = "%s-%s" % (data["algorithm"], compute_node_count)
                
                if not map_algos_size.has_key(compute_node_count):
                    map_algos_size[compute_node_count] = []

                map_algos_size[compute_node_count] += [algo]

                _violations_det_per_node = {}
                _violations_out_per_node = {}
                _violations_smp_per_node = {}

                for line in f.readlines():
                    try:
                        data = json.loads(line)

                        if float(data["time"]) > duration:
                            continue

                        if data["event"] == "trace_event" and data["value"] == "violation-det":
                            current_violation_det = (float(data["time"]), float(data["duration"]), data["origin"], "det")
                            if not _violations_det_per_node.has_key(data["origin"]):
                                _violations_det_per_node[data["origin"]] = []
                            _violations_det_per_node[data["origin"]] += [current_violation_det]

                        if data["event"] == "trace_event" and data["value"] == "violation-out":
                            current_violation_out = (float(data["time"]), float(data["duration"]), data["origin"], "out")
                            if not _violations_out_per_node.has_key(data["origin"]):
                                _violations_out_per_node[data["origin"]] = []
                            _violations_out_per_node[data["origin"]] += [current_violation_out]

                        if data["event"] == "trace_event" and data["value"] == "violation":
                            current_violation_smp = (float(data["time"]), float(data["duration"]), data["origin"], "smp")
                            if not _violations_smp_per_node.has_key(data["origin"]):
                                _violations_smp_per_node[data["origin"]] = []
                            _violations_smp_per_node[data["origin"]] += [current_violation_smp]

                    except Exception as e:
                        # print traceback.format_exc()
                        pass
                
                f.seek(0)

                nodes = set(_violations_smp_per_node.keys() + _violations_out_per_node.keys())

                violations_smp_detected = []
                violations_smp_hidden   = []
                violations_out_detected = []
                violations_out_hidden   = []

                for node in nodes:
                    try:

                        current_violation_det = _violations_det_per_node[node] if _violations_det_per_node.has_key(node) else []
                        current_violation_out = _violations_out_per_node[node] if _violations_out_per_node.has_key(node) else []
                        current_violation_smp = _violations_smp_per_node[node] if _violations_smp_per_node.has_key(node) else []

                        product = itertools.product(current_violation_smp, current_violation_det)
                        product_filtered = [element for element in product if abs(element[0][0] + element[0][1] - element[1][0] - element[1][1]) < 0.01]

                        violations_smp_per_node_detected = set([element[0] for element in product_filtered])
                        violations_smp_per_node_hidden   = set([element    for element in current_violation_smp if element not in violations_smp_per_node_detected])

                        if len(violations_smp_per_node_detected) + len(violations_smp_per_node_hidden) != len(current_violation_smp):
                            print("%s + %s = %s" % (violations_smp_per_node_detected, violations_smp_per_node_hidden, current_violation_smp))

                        product = itertools.product(current_violation_out, current_violation_det)
                        product_filtered = [element for element in product if abs(element[0][0] + element[0][1] - element[1][0] - element[1][1]) < 0.01]

                        violations_out_per_node_detected = set([element[0] for element in product_filtered])
                        violations_out_per_node_hidden   = set([element    for element in current_violation_out if element not in violations_out_per_node_detected])
                        if len(violations_out_per_node_detected) + len(violations_out_per_node_hidden) != len(current_violation_out):
                            print("%s + %s = %s" % (violations_out_per_node_detected, violations_out_per_node_hidden, current_violation_out))

                        

                        violations_smp_detected += violations_smp_per_node_detected
                        violations_smp_hidden   += violations_smp_per_node_hidden
                        violations_out_detected += violations_out_per_node_detected
                        violations_out_hidden   += violations_out_per_node_hidden
                        
                    except:
                        pass

                hidden_violation_count   = len(violations_smp_hidden) + len(violations_out_hidden)
                detected_violation_count = len(violations_smp_detected) + len(violations_out_detected)

                map_hidden_violation_count[nodes_vms_tuple]     = hidden_violation_count  
                map_detected_violation_count[nodes_vms_tuple]   = detected_violation_count

                map_detected_violation_ratio[nodes_vms_tuple] = detected_violation_count / (detected_violation_count + hidden_violation_count)

                # print("%s@%d => %d" % (algo, compute_node_count, violation_total_time))

                # export_csv_data(algo, compute_node_count, violations_smp_detected, violations_smp_hidden, violations_out_detected, violations_out_hidden)


################################################################################
# Generate CSV files from data maps
################################################################################
print map_hidden_violation_count
print map_detected_violation_count
print map_detected_violation_ratio

render_template("template/matrix_data.jinja2", {"algos": algos, "server_counts": nodes_tuples, "data": map_hidden_violation_count  },             "data/hidden_violation_count.csv")
render_template("template/matrix_data.jinja2", {"algos": algos, "server_counts": nodes_tuples, "data": map_detected_violation_count  },           "data/detected_violation_count.csv")
render_template("template/matrix_data.jinja2", {"algos": algos, "server_counts": nodes_tuples, "data": map_detected_violation_ratio  },           "data/detected_violation_ratio.csv")

group_by_nodes     = ["distributed", "hierarchical"]
not_group_by_nodes = list(set(algos) - set(group_by_nodes))

print("group_by_nodes -> %s" %(group_by_nodes))
print("not_group_by_nodes -> %s" %(not_group_by_nodes))

render_template("template/matrix_script.jinja2", {"source": "data/hidden_violation_count.csv",   "x_label": "Configuration", "y_label": "count",          "algos": algos, "x_axis": zip(nodes_tuples, vms_tuples), "group_by_nodes": [], "not_group_by_nodes": [],  "title": "hidden_violation_count"},   "scripts/hidden_violation_count.r")
render_template("template/matrix_script.jinja2", {"source": "data/detected_violation_count.csv", "x_label": "Configuration", "y_label": "count",          "algos": algos, "x_axis": zip(nodes_tuples, vms_tuples), "group_by_nodes": [], "not_group_by_nodes": [],  "title": "detected_violation_count"}, "scripts/detected_violation_count.r")
render_template("template/matrix_script.jinja2", {"source": "data/detected_violation_ratio.csv", "x_label": "Configuration", "y_label": "percentage",     "algos": algos, "x_axis": zip(nodes_tuples, vms_tuples), "group_by_nodes": [], "not_group_by_nodes": [],  "title": "detected_violation_ratio"}, "scripts/detected_violation_ratio.r")
<file_sep>/visu/generate_loads.py
#!/usr/bin/python
from __future__ import division
from pkg_resources import WorkingSet , DistributionNotFound
working_set = WorkingSet()

import itertools

# Printing all installed modules
#print tuple(working_set)

# Detecting if module is installed
dependency_found = True
try:
    dep = working_set.require('Jinja2')
except DistributionNotFound:
    dependency_found  = False
    pass

if not dependency_found:
    try:
        # Installing it (anyone knows a better way?)
        from setuptools.command.easy_install import main as install
        install(['Jinja2'])
        print("run again as normal user to process results")
    except DistributionNotFound:
        print("run this script as sudo to install a missing template engine")
        pass
    sys.exit(0)


import csv
import subprocess
import time
import os
import json
import jinja2

################################################################################
# Constant and parameters
################################################################################

duration = 3600

################################################################################
# Functions of the script
################################################################################
def execute_cmd(args):
	print "%s" % args
	# return "%s" % args
	out, err = subprocess.Popen(args,
                   shell=False,
                   stdout=subprocess.PIPE,
                   stderr=subprocess.PIPE).communicate()
	if not err == "":
		print err
	return out

def render_template(template_file_path, vars, output_file_path):
    templateLoader = jinja2.FileSystemLoader( searchpath="." )
    templateEnv = jinja2.Environment( loader=templateLoader )

    TEMPLATE_FILE = template_file_path
    template = templateEnv.get_template( TEMPLATE_FILE )

    templateVars = vars

    outputText = template.render( templateVars )
    with open(output_file_path, "w") as text_file:
        text_file.write(outputText)
        

################################################################################
# Clean data and scripts folders
################################################################################
execute_cmd(["rm", "-r", "loads"])
execute_cmd(["mkdir", "loads"])

################################################################################
# Detect algorithms used in experiments
################################################################################
algos = []
for dirname, dirnames, filenames in os.walk('./events'):
    # print path to all subdirectories first.
    for filename in filenames:
        if filename.endswith(".json"):
            with open("%s/%s" % (dirname, filename), 'r') as f:
                header_line = f.readline()
                header_data = json.loads(header_line)
                data = header_data["data"]
                algo = data["algorithm"]
                if not algo in algos:
                    algos += [algo]
print algos

################################################################################
# Detect (server_count, vm_count) combination used in experiments
################################################################################
nodes_tuples     = []
vms_tuples       = []
nodes_vms_tuples = []
for dirname, dirnames, filenames in os.walk('./events'):
    # print path to all subdirectories first.
    for filename in filenames:
        if filename.endswith(".json"):
            with open("%s/%s" % (dirname, filename), 'r') as f:
                header_line = f.readline()
                header_data = json.loads(header_line)
                data = header_data["data"]
                
                compute_node_count = data["server_count"]
                service_node_count = data["service_node_count"]
                node_count = compute_node_count + service_node_count

                if not compute_node_count in nodes_tuples:
                    nodes_tuples += [compute_node_count]
                if not data["vm_count"] in vms_tuples:
                    vms_tuples += [data["vm_count"]]
                # nodes_vms_tuple = "%s-%s" % (data["server_count"], data["vm_count"])
                # if not nodes_vms_tuple in nodes_vms_tuples:
                #     nodes_vms_tuples += [nodes_vms_tuple]

# Order the tuples
nodes_tuples = sorted(nodes_tuples)
vms_tuples = sorted(vms_tuples)
nodes_vms_tuples = [str(tuple2[0])+"-"+str(tuple2[1]) for tuple2 in zip(nodes_tuples, vms_tuples)]
# nodes_vms_tuples = sorted(nodes_vms_tuples)

print nodes_tuples
print vms_tuples
print nodes_vms_tuples

################################################################################
# Fill data maps with computed metrics
################################################################################

def export_csv_data(algo, node_count, loads):

    folder_name = "loads/data/%s-%d" % (algo, node_count)

    execute_cmd(["mkdir", "-p", folder_name])

    render_template("template/load_data.jinja2", {"algo": algo, "loads": loads, "labels": ["time", "load"]},   "%s/load.csv" % (folder_name))

simulations = []

for dirname, dirnames, filenames in os.walk('./events'):
    # print path to all subdirectories first.
    for filename in filenames:
        if filename.endswith(".json"):
            with open("%s/%s" % (dirname, filename), 'r') as f:
                header_line = f.readline()
                header_data = json.loads(header_line)
                data = header_data["data"]
                algo = data["algorithm"]

                compute_node_count = data["server_count"]
                service_node_count = data["service_node_count"]
                node_count = compute_node_count + service_node_count

                nodes_vms_tuple = "%s-%s" % (data["algorithm"], compute_node_count)
                
                service_node_name = "node%d" % (node_count)

                simulations += [(algo, compute_node_count)]

                loads = []

                for line in f.readlines():
                    try:
                        data = json.loads(line)

                        if float(data["time"]) > 1801:
                            continue
                        # print(data)

                        if data["event"] == "trace_event" and data["state_name"] == "VARIABLE" and data["value"] == "LOAD" and data["origin"] == service_node_name:
                            loads += [(data["time"], data["data"]["value"])]

                    except:
                        pass

                export_csv_data(algo, compute_node_count, loads)



################################################################################
# Find simulation matching and prepare R scripts
################################################################################

def export_loads_data(algo, node_count):

    folder_name = "loads/scripts/%d-%s" % (node_count, algo)

    execute_cmd(["mkdir", "-p", folder_name])

    render_template("template/load_script.jinja2", {"algo": algo, "node_count": node_count},   "%s/compare.r" % (folder_name))

    pass

for simulation in simulations:
    algo = simulation[0]
    node_count = simulation[1]

    export_loads_data(algo, node_count)

################################################################################
# Clean results folder
################################################################################
execute_cmd(["rm", "-r", "loads/results"])
execute_cmd(["mkdir", "-p", "loads/results"])

################################################################################
# Generate loads figures
################################################################################

for simulation in simulations:
    algo = simulation[0]
    node_count = simulation[1]

    export_loads_data(algo, node_count)

    script_folder_name = "loads/scripts/%d-%s" % (node_count, algo)
    out_file_path = "loads/results/%d-%s.pdf" % (node_count, algo)

    execute_cmd(["/usr/bin/env", "Rscript", "%s/compare.r" % (script_folder_name)])

    execute_cmd(["mv", "Rplots.pdf", out_file_path])

<file_sep>/visu/generate_repartition.py
#!/usr/bin/python
from __future__ import division
from pkg_resources import WorkingSet , DistributionNotFound
working_set = WorkingSet()

import itertools

# Printing all installed modules
#print tuple(working_set)

# Detecting if module is installed
dependency_found = True
try:
    dep = working_set.require('Jinja2')
except DistributionNotFound:
    dependency_found  = False
    pass

if not dependency_found:
    try:
        # Installing it (anyone knows a better way?)
        from setuptools.command.easy_install import main as install
        install(['Jinja2'])
        print("run again as normal user to process results")
    except DistributionNotFound:
        print("run this script as sudo to install a missing template engine")
        pass
    sys.exit(0)


import csv
import subprocess
import time
import os
import json
import jinja2
import traceback

################################################################################
# Constant and parameters
################################################################################

duration = 3600

################################################################################
# Functions of the script
################################################################################
def execute_cmd(args):
	print "%s" % args
	# return "%s" % args
	out, err = subprocess.Popen(args,
                   shell=False,
                   stdout=subprocess.PIPE,
                   stderr=subprocess.PIPE).communicate()
	if not err == "":
		print err
	return out

def render_template(template_file_path, vars, output_file_path):
    templateLoader = jinja2.FileSystemLoader( searchpath="." )
    templateEnv = jinja2.Environment( loader=templateLoader )

    TEMPLATE_FILE = template_file_path
    template = templateEnv.get_template( TEMPLATE_FILE )

    templateVars = vars

    outputText = template.render( templateVars )
    with open(output_file_path, "w") as text_file:
        text_file.write(outputText)
        

################################################################################
# Clean data and scripts folders
################################################################################
execute_cmd(["rm", "-r", "repartition"])
execute_cmd(["mkdir", "repartition"])

################################################################################
# Detect algorithms used in experiments
################################################################################
algos = []
for dirname, dirnames, filenames in os.walk('./events'):
    # print path to all subdirectories first.
    for filename in filenames:
        if filename.endswith(".json"):
            with open("%s/%s" % (dirname, filename), 'r') as f:
                header_line = f.readline()
                header_data = json.loads(header_line)
                data = header_data["data"]
                algo = data["algorithm"]
                if not algo in algos:
                    algos += [algo]
print algos

################################################################################
# Detect (server_count, vm_count) combination used in experiments
################################################################################
nodes_tuples     = []
vms_tuples       = []
nodes_vms_tuples = []
for dirname, dirnames, filenames in os.walk('./events'):
    # print path to all subdirectories first.
    for filename in filenames:
        if filename.endswith(".json"):
            with open("%s/%s" % (dirname, filename), 'r') as f:
                header_line = f.readline()
                header_data = json.loads(header_line)
                data = header_data["data"]

                compute_node_count = data["server_count"]
                service_node_count = data["service_node_count"]
                node_count = compute_node_count + service_node_count

                if not compute_node_count in nodes_tuples:
                    nodes_tuples += [compute_node_count]
                if not data["vm_count"] in vms_tuples:
                    vms_tuples += [data["vm_count"]]
                # nodes_vms_tuple = "%s-%s" % (data["server_count"], data["vm_count"])
                # if not nodes_vms_tuple in nodes_vms_tuples:
                #     nodes_vms_tuples += [nodes_vms_tuple]

# Order the tuples
nodes_tuples = sorted(nodes_tuples)
vms_tuples = sorted(vms_tuples)
nodes_vms_tuples = [str(tuple2[0])+"-"+str(tuple2[1]) for tuple2 in zip(nodes_tuples, vms_tuples)]
# nodes_vms_tuples = sorted(nodes_vms_tuples)

print nodes_tuples
print vms_tuples
print nodes_vms_tuples

################################################################################
# Fill data maps with computed metrics
################################################################################

def export_csv_data(algo, node_count, computes, migrations):

    folder_name = "repartition/data/%s-%d" % (algo, node_count)

    execute_cmd(["mkdir", "-p", folder_name])

    render_template("template/cloud_data.jinja2", {"algo": algo, "node_count": node_count, "violations": computes,   "labels": ["type", "value"]}, "%s/repartition_computations.csv" % (folder_name))
    render_template("template/cloud_data.jinja2", {"algo": algo, "node_count": node_count, "violations": migrations, "labels": ["type", "value"]}, "%s/repartition_migrations.csv" % (folder_name))

map_algos_size = {}


# variable that is used to detect "violation-out", "violation-normal" and "violation-sched":
# it will store the last line about "violations-out" or "violation-det", to detect if the next
# "violation" has been already processed!
last_line = None

for dirname, dirnames, filenames in os.walk('./events'):
    # print path to all subdirectories first.
    for filename in filenames:
        if filename.endswith(".json"):
            with open("%s/%s" % (dirname, filename), 'r') as f:
                header_line = f.readline()
                header_data = json.loads(header_line)
                data = header_data["data"]
                algo = data["algorithm"]

                compute_node_count = data["server_count"]
                service_node_count = data["service_node_count"]
                node_count = compute_node_count + service_node_count
                
                nodes_vms_tuple = "%s-%s" % (data["algorithm"], compute_node_count)
                
                if not map_algos_size.has_key(compute_node_count):
                    map_algos_size[compute_node_count] = []

                map_algos_size[compute_node_count] += [algo]

                computes = []
                migrations = []

                for line in f.readlines():
                    try:
                        data = json.loads(line)

                        if float(data["time"]) > duration:
                            continue

                        if data["event"] == "trace_event" and data["value"] == "migrate":
                            migration_time = data["duration"]
                            migrations += [["MIGRATION", migration_time]]

                        if data["event"] == "trace_event" and data["value"] == "compute":
                            compute_time = data["duration"]
                            compute_result = data["data"]["state"]
                            computes += [[compute_result, compute_time]]

                    except Exception as e:
                        # print traceback.format_exc()
                        pass
                
                f.seek(0)

                export_csv_data(algo, compute_node_count, computes, migrations)

################################################################################
# Clean results folder
################################################################################
execute_cmd(["rm", "-r", "repartition/results"])
execute_cmd(["mkdir", "-p", "repartition/results"])

################################################################################
# Prepare R scripts for each simulation
################################################################################

metrics = ["migrations", "computations"]
legends = {
    "migrations": "migration time (s)", 
    "computations": "computation time (s)"
}

def export_repartition_single_data(algo, node_count, metric, legend):
    print("%s with %s" % (algo, node_count))

    folder_name = "repartition/scripts/%d-%s" % (node_count, algo)

    execute_cmd(["mkdir", "-p", folder_name])

    render_template("template/repartition_script.jinja2", {"algo": algo, "node_count": node_count, "metric": metric, "legend": legend},   "%s/compare_%s.r" % (folder_name, metric))

    pass

for key in map_algos_size:
    algos = map_algos_size[key]
    node_count = key

    for algo in algos:
        for metric in metrics:
            export_repartition_single_data(algo, node_count, metric, legends[metric])

################################################################################
# Generate repartition figures
################################################################################


for key in map_algos_size:
    algos = map_algos_size[key]
    node_count = key

    for algo in algos:
        for metric in metrics:
            script_folder_name = "repartition/scripts/%d-%s" % (node_count, algo)
            out_file_path = "repartition/results/%s-%s-%d.pdf" % (metric, algo, node_count)

            execute_cmd(["/usr/bin/env", "Rscript", "%s/compare_%s.r" % (script_folder_name, metric)])

            execute_cmd(["mv", "Rplots.pdf", out_file_path])

<file_sep>/src/main/java/scheduling/hierarchical/snooze/msg/LCAssMsg.java
package scheduling.hierarchical.snooze.msg;

/**
 * Created by sudholt on 13/07/2014.
 */
public class LCAssMsg extends SnoozeMsg {
    public LCAssMsg(String name, String sendBox, String origin, String replyBox) {
        super(name, sendBox, origin, replyBox);
    }
}
<file_sep>/src/main/java/scheduling/Scheduler.java
package scheduling;

import configuration.XHost;

import java.util.Collection;

/**
 * Contract that must be followed by the implemented schedulers.
 */
public interface Scheduler {

    ComputingResult computeReconfigurationPlan();
    SchedulerResult checkAndReconfigure(Collection<XHost> hostsToCheck);

    /**
     * Result of the reconfiguration plan computation.
     */
    class ComputingResult {

        public enum State {

            NO_RECONFIGURATION_NEEDED("NO_RECONFIGURATION_NEEDED"),
            PLACEMENT_FAILED("PLACEMENT_FAILED"),
            RECONFIGURATION_FAILED("RECONFIGURATION_FAILED"),
            SUCCESS("SUCCESS");

            private String name;

            State(String name){
                this.name = name;
            }

            public String toString(){
                return name;
            }

        }

        public State state;

        /**
         * Number of migrations in the computed plan
         */
        public int nbMigrations;

        /**
         * Duration of the computing process
         */
        public long duration;

        /**
         * 	The cost of the reconfiguration plan.
         */
        protected int planCost;

        public ComputingResult(State state, long duration, int nbMigrations, int planCost) {
            this.state = state;
            this.duration = duration;
            this.nbMigrations = nbMigrations;
            this.planCost = planCost;
        }

        public ComputingResult(State state, long duration) {
            this(state, duration, 0, 0);
        }

        public ComputingResult() { this(State.SUCCESS, 0, 0, 0); }

    }


    /**
     * Result of the reconfiguration.
     */
    class SchedulerResult {

        /**
         * Result of the Scheduling process.
         */
        public enum State {

            SUCCESS("SUCCESS"),
            RECONFIGURATION_PLAN_ABORTED("RECONFIGURATION_PLAN_ABORTED"),
            NO_VIABLE_CONFIGURATION("NO_VIABLE_CONFIGURATION"),
            NO_RECONFIGURATION_NEEDED("NO_RECONFIGURATION_NEEDED");

            private String name;

            State(String name){
                this.name = name;
            }

            public String toString(){
                return name;
            }

        }

        /**
         * Result of the reconfiguration.
         */
        public State state;

        /**
         * Duration in ms of the reconfiguration.
         */
        public long duration;

    }

}
<file_sep>/visu/template/cloud_single_script.jinja2
#!/usr/bin/Rscript

algo1_matrix_data_smp_det_time <- read.table("clouds/data/{{algo}}-{{node_count}}/violations_smp_det.csv", header=T,sep=",")
colnames(algo1_matrix_data_smp_det_time) <- c("algo1_smp_det_time", "algo1_smp_det_duration") 
attach(algo1_matrix_data_smp_det_time)

algo1_matrix_data_smp_hid_time <- read.table("clouds/data/{{algo}}-{{node_count}}/violations_smp_hid.csv", header=T,sep=",")
colnames(algo1_matrix_data_smp_hid_time) <- c("algo1_smp_hid_time", "algo1_smp_hid_duration") 
attach(algo1_matrix_data_smp_hid_time)

algo1_matrix_data_out_det_time <- read.table("clouds/data/{{algo}}-{{node_count}}/violations_out_det.csv", header=T,sep=",")
colnames(algo1_matrix_data_out_det_time) <- c("algo1_out_det_time", "algo1_out_det_duration") 
attach(algo1_matrix_data_out_det_time)

algo1_matrix_data_out_hid_time <- read.table("clouds/data/{{algo}}-{{node_count}}/violations_out_hid.csv", header=T,sep=",")
colnames(algo1_matrix_data_out_hid_time) <- c("algo1_out_hid_time", "algo1_out_hid_duration") 
attach(algo1_matrix_data_out_hid_time)

dev.new(width=8, height=6)

g_range <- range(algo1_smp_det_duration, algo1_smp_hid_duration, algo1_out_det_duration, algo1_out_hid_duration)
plot(    algo1_smp_det_time, algo1_smp_det_duration,  pch=7 ,  col=rgb(255, 128, 0  , 200,maxColorValue=255), ylim=g_range*1.20, 
    ,xlim=c(0, {{duration}}), xlab="Time (s)", ylab="Duration of the violation (s)")
#title(main="Duration of each violation")
points(  algo1_smp_hid_time, algo1_smp_hid_duration,  pch=0 ,  col=rgb(255, 128, 0  , 200,maxColorValue=255))
points(  algo1_out_det_time, algo1_out_det_duration,  pch=13,  col=rgb(0  , 102, 204, 200,maxColorValue=255))
points(  algo1_out_hid_time, algo1_out_hid_duration,  pch=1 ,  col=rgb(0  , 102, 204, 200,maxColorValue=255))

legend("topleft", c(
        "{{algo | capitalize}} violation detected",
        "{{algo | capitalize}} violation hidden",        
        "{{algo | capitalize}} violation out detected",
        "{{algo | capitalize}} violation out hidden"
    ), ncol=2,
   col=c(
   		rgb(255, 128, 0  , 200,maxColorValue=255),
   		rgb(255, 128, 0  , 200,maxColorValue=255),
		  rgb(0  , 102, 204, 200,maxColorValue=255),
      rgb(0  , 102, 204, 200,maxColorValue=255)
	), pch=c(7, 0, 13, 1))


<file_sep>/run_all.sh
#! /bin/bash

PID_FILE=/tmp/vmplaces.pid

source xprc

function do_abort() {
	echo Killing java process with PID `cat $PID_FILE`
	kill -9 `cat $PID_FILE`
	rm -f $PID_FILE
	exit 2
}

trap do_abort SIGINT

error=0

# run <nb nodes> <algo> <implem>
# Ex: run 128 centralized scheduling.centralized.entropy2.Entropy2RP
function run() {
	n_nodes=$1
	algo=$2
	implem=$3
	turn_off=$4

	if [ "$3" != "none" ]
	then
		implem="-Dsimulator.implementation=$implem"

		# Yes, this is ugly
		name=`echo ${implem} | rev | cut -d "." -f1 | rev`
		name="${algo}-${name}-${n_nodes}-${turn_off}"
	else
		implem=''
		name="${algo}-${n_nodes}-${turn_off}"
	fi

	n_service='1'
	case "$algo" in
		"centralized")
			n_service=1
			;;
		"hierarchical")
			n_service=$(($n_nodes / 32 + 1))
			;;
		"distributed")
			n_service=0
			;;
	esac

	n_vms=$(($n_nodes * 10))
	mean=60
	std=20

	SIM_ARGS="-Dsimulator.algorithm=$algo $implem"
	SIM_ARGS="$SIM_ARGS -Dhostingnodes.number=$n_nodes"
	SIM_ARGS="$SIM_ARGS -Dservicenodes.number=$n_service"
	SIM_ARGS="$SIM_ARGS -Dvm.number=$n_vms"
	SIM_ARGS="$SIM_ARGS -Dhostingnodes.cpunumber=8"
	SIM_ARGS="$SIM_ARGS -Dhostingnodes.memorytotal=32768"
	SIM_ARGS="$SIM_ARGS -Dhosts.turn_off=$turn_off"
	SIM_ARGS="$SIM_ARGS -Dload.mean=$mean"
	SIM_ARGS="$SIM_ARGS -Dload.std=$std"

	echo '----------------------------------------'
	echo "Running $algo $implem with $n_nodes compute and $n_service service nodes turning off hosts: $turn_off, load.mean=$mean, load.std=$std"
	echo "Command: java $VM_OPTIONS $SIM_ARGS simulation.Main $PROGRAM_ARGUMENTS"
	echo "Command: VM_OPTIONS $VM_OPTIONS"
	echo "Command: SIM_ARGS $SIM_ARGS"
	echo "Command: PROGRAM_ARGUMENTS $PROGRAM_ARGUMENTS"
	echo '----------------------------------------'
	java $VM_OPTIONS $SIM_ARGS simulation.Main $PROGRAM_ARGUMENTS &
	pid=$!
	echo $pid > $PID_FILE
	wait $pid
	ret=$?

	echo java returned $ret

	if [ $ret -ne 0 ] && [ $ret -ne 134 ]
	then
		error=1
		exit $ret
	fi

	mkdir -p visu/events/$name
	cp events.json visu/events/$name/
}

#######################################
#                Main                 #
#######################################

# Number of hosting nodes
nodes='64'
abort=0

rm -rf logs/ffd

{
	for n in $nodes; do
		run $n centralized scheduling.centralized.entropy2.Entropy2RP false
		run $n centralized scheduling.centralized.ffd.LazyFirstFitDecreased false
		run $n centralized scheduling.centralized.ffd.OptimisticFirstFitDecreased false

		run $n centralized scheduling.centralized.entropy2.Entropy2RP true
		run $n centralized scheduling.centralized.ffd.LazyFirstFitDecreased true
		run $n centralized scheduling.centralized.ffd.OptimisticFirstFitDecreased true

		#run $n hierarchical false

		#run $n distributed false
	done
} 2>&1 | tee run_all.log


if [ ! $error ]
	then
		visu/energy_plot.py run_all.log energy.dat
	fi
<file_sep>/src/main/java/scheduling/hierarchical/snooze/Logger.java
package scheduling.hierarchical.snooze;

import org.simgrid.msg.Msg;

/**
 * Created by sudholt on 29/06/2014.
 */
public class Logger {

    public static void err(String s) {
        if (SnoozeProperties.getInfoLevel() <= 4) Msg.info("ERRSNOO: " + s);
    }

    public static void exc(String s) {
        if (SnoozeProperties.getInfoLevel() <= 4) Msg.info("EXCSNOO: " + s);
    }

    public static void imp(String s) {
        if (SnoozeProperties.getInfoLevel() <= 3) Msg.info("IMPSNOO: " + s);
    }

    public static void info(String s) {
        if (SnoozeProperties.getInfoLevel() <= 2) Msg.info("INFSNOO: " + s);
    }

    public static void debug(String s) {
        if (SnoozeProperties.getInfoLevel() == 1) Msg.info("DEBSNOO: " + s);
    }
    public static void log(Exception e) {
        Msg.info("EXCSNOO: ");
        e.printStackTrace(System.err);
    }
}<file_sep>/visu/energy_plot.py
#! /usr/bin/env python

from __future__ import print_function

import os, sys, re, json, math
import traceback
import operator
import pprint
pp = pprint.PrettyPrinter(indent=4).pprint

import numpy as np

import matplotlib.pyplot as plt
import matplotlib.patches as patches
import matplotlib.path as path
import matplotlib.animation as animation
import matplotlib.ticker as ticker
import locale
locale.setlocale(locale.LC_ALL, 'en_US')

def eprint(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)

# Determines the order of the bars in the plots
ORDER = ['Entropy', 'Lazy FFD', 'Optimistic FFD']
#ORDER = ['Lazy FFD', 'Optimistic FFD']

# Check arguments
if len(sys.argv) != 3:
    eprint('Usage: ./energy_plot.py <log file> <energy file>')
    sys.exit(1)

# Some functions
def to_bool(string):
    if string in ['true', 'True']:
        return True
    
    if string in ['false', 'False']:
        return False

    eprint("%s is not a boolean" % string)
    sys.exit(3)

def correct_name(name):
    names = {
        'LazyFirstFitDecreased': 'Lazy FFD',
        'OptimisticFirstFitDecreased': 'Optimistic FFD',
        'Entropy2RP': 'Entropy'}

    return names[name]

# time_on['Entropy']['node56'] = 17546.57
time_on = {}
last_on = None
def new_experiment(alg):
    global last_on
    time_on[alg] = {}
    last_on = {}

def end_experiment(time, alg):
    for node in last_on.keys():
        if last_on[node] is not None:
            node_off(node, time, alg)

def node_on(name, time, alg):
    if name in last_on and last_on[name] is not None:
        eprint("Node %s was already on since %.2f" % (name, time))
        sys.exit(1)
    
    last_on[name] = time

def node_off(name, time, alg):
    if last_on[name] is None:
        eprint("None %s was not on" % name)
        sys.exit(1)

    if name not in time_on[alg]:
        time_on[alg][name] = 0
    
    time_on[alg][name] += time - last_on[name]
    last_on[name] = None

########################################
# Get the number of turned off hosts
# and of migrations
########################################
n_turn_off = {}
n_migrations = {}
algos = []
n_on = {}
scheduler_ticks = {}

# load and standard deviation must be the same
# for all the experiments in the log file
load = None
std = None
simulation_time = None
n_hosts = None

with open(sys.argv[1], 'r') as f:
    turn_off = None

    curr = None

    # Compile 3 patterns and read the logs
    start_pattern = re.compile(r'Running (\w+)(\s-D[\w\.]+\=([\w\.]+))? with (\d+) compute and (\d+) service nodes turning off hosts: (\w+), load.mean=(\d+), load.std=(\d+)')
    end_pattern = re.compile(r'\[.*\s(\d+\.\d+)\] \[.*\] End of Injection')
    off_pattern = re.compile(r'\[(.*\s)?(\d+\.\d+)\] \[.*\] Turn off (node\d+)')
    on_pattern = re.compile(r'\[(.* )?(\d+\.\d+)\] \[.*\] Turn on (node\d+)')
    migration_pattern = re.compile(r'End of migration of VM vm-\d+ from node\d+ to node\d+')

    scheduler_pattern = re.compile(r'\[(.*)\s(\d+\.\d+)\] \[.*\] Launching scheduler \(id = \d+\) - start to compute')

    for line in f:
        # This is a new experiment
        m = re.search(start_pattern, line)
        if m:
            turn_off = to_bool(m.group(6))
            n_hosts = int(m.group(4))
            
            if n_hosts not in n_turn_off:
                n_turn_off[n_hosts] = {True: {}, False: {}}
               
            if n_hosts not in n_migrations:
                n_migrations[n_hosts] = {True: {}, False: {}}
               
            if n_hosts not in scheduler_ticks:
                scheduler_ticks[n_hosts] = {True: {}, False: {}}
               
            if n_hosts not in n_on:
                n_on[n_hosts] = {}

            algo = correct_name(m.group(3).split('.')[-1])
            if algo not in algos:
                algos.append(algo)
                scheduler_ticks[n_hosts][turn_off][algo] = []

            if turn_off:
                n_on[n_hosts][algo] = {}
                n_on[n_hosts][algo][0.0] = 0

            n_turn_off[n_hosts][turn_off][algo] = 0
            n_migrations[n_hosts][turn_off][algo] = 0

            curr = turn_off

            load = int(m.group(7))
            std = int(m.group(8))

            new_experiment(algo)


            continue

        # An experiment is over
        m = re.search(end_pattern, line)
        if m:
            time = float(m.group(1))
            end_experiment(time, algo)
            simulation_time = int(time)
            continue
        
        # The scheduler is running
        m = re.search(scheduler_pattern, line)
        if m:
            if algo not in scheduler_ticks[n_hosts][turn_off]:
                scheduler_ticks[n_hosts][turn_off][algo] = []
            scheduler_ticks[n_hosts][turn_off][algo].append(float(m.group(2)))
            continue

        # A node has been turned off
        m = re.search(off_pattern, line)
        if m:
            n_turn_off[n_hosts][curr][algo] += 1

            if turn_off:
                n_on[n_hosts][algo][float(m.group(2))] = n_on[n_hosts][algo][n_on[n_hosts][algo].keys()[-1]] - 1

            node_off(m.group(3), float(m.group(2)), algo)
            continue

        # A node has been turned on
        m = re.search(on_pattern, line)
        if m:
            if turn_off:
                n_on[n_hosts][algo][float(m.group(2))] = n_on[n_hosts][algo][n_on[n_hosts][algo].keys()[-1]] + 1

            node_on(m.group(3), float(m.group(2)), algo)
            continue

        # A VM has been migrated
        m = re.search(migration_pattern, line)
        if m:
            n_migrations[n_hosts][curr][algo] += 1

########################################
# Count the number of on VMs
########################################
n_vms = {}

dir_pattern = re.compile(r'(\w+)-([\w\d]+)-(\d+)-(true|false)')
events = os.path.join('visu', 'events')

# list dir in 'visu/events'
for item in os.listdir(events):
    m = re.search(dir_pattern, item)

    if m is None:
        continue

    # look for dirs like 'centralized-algo-64'
    if m.group(1) == 'centralized':
        algo = correct_name(m.group(2))
        turn_off = to_bool(m.group(4))
        n_hosts = int(m.group(3))
        
        if n_hosts not in n_vms:
            n_vms[n_hosts] = { True: {}, False: {} }

        event_file = os.path.join(events, item, 'events.json')
        print('Reading ' + event_file)

        with open(event_file, 'r') as f:
            n_vms[n_hosts][turn_off][algo] = {}

            # each line in this file is a JSON document
            for line in f:
                try:
                    event = json.loads(line)

                    if event['value'] == "NB_VM":
                        time = float(event['time'])
                        value = int(event['data']['value'])
                        n_vms[n_hosts][turn_off][algo][time] = value
                except:
                    t, value, tb = sys.exc_info()
                    print(str(t) + " " + str(value))
                    print(line)
                    traceback.print_tb(tb)
                    sys.exit(1)

                if event['value'] != 'NB_VNS_ON':
                    continue

                n_vms[n_hosts][turn_off][algo][float(event['time'])] = int(event['data']['value'])

migration_ordered = []
########################################
# Get the energy metrics
########################################
energy = {}

with open(sys.argv[2], 'r') as f:
    p = re.compile(r'(\d+) \w+ (\w+) (\w+) ([\d\.]+)')
    for line in f:
        m = re.match(p, line)
        n_hosts = int(m.group(1))
        implem = correct_name(m.group(2))
        turn_off = to_bool(m.group(3))
        joules = float(m.group(4))
        
        if n_hosts not in energy:
            energy[n_hosts] = { True: {}, False: {} }

        energy[n_hosts][turn_off][implem] = joules / simulation_time / 1000

########################################
# Make the bar plot
########################################
ind = np.arange(len(algos)) # the x locations for the groups
width = 0.35

ordered_energy = {}
off_ordered = {}
migration_ordered = {}

for n_hosts in energy.keys():
    if n_hosts not in ordered_energy:
        ordered_energy[n_hosts] = { True: [], False: [] }
        
    for alg in ORDER:
        if alg not in energy[n_hosts][True]:
            continue
    
        ordered_energy[n_hosts][True].append(energy[n_hosts][True][alg])
        ordered_energy[n_hosts][False].append(energy[n_hosts][False][alg])

    print("ordered_energy %d:" % n_hosts)
    pp(ordered_energy[n_hosts])

    fig, ax1 = plt.subplots()

    color1 = '#888888'
    color2 = '#FFFFFF'
    linewidth = 1
    rects1 = ax1.bar(ind, ordered_energy[n_hosts][False], width, color=color1, linewidth=linewidth)
    rects2 = ax1.bar(ind + width, ordered_energy[n_hosts][True], width, color=color2, linewidth=linewidth)

    ax1.set_ylabel('Energy (Megawatts)')
    ax1.set_xticks(ind + width)
    lim = ax1.get_ylim()
    ax1.set_ylim(lim[0], lim[1])

    ax1.set_xticklabels(ORDER)

    ########################################
    # Make the line plots
    ########################################
    # Make sure the values here are in the same order as the energy values
    off_ordered[n_hosts] = []
    migration_ordered[n_hosts] = []
    for alg in ORDER:
        if alg not in n_turn_off[n_hosts][True]:
            continue
        
        off_ordered[n_hosts].append(n_turn_off[n_hosts][True][alg])
        migration_ordered[n_hosts].append(n_migrations[n_hosts][True][alg])

    print("off_ordered[%d]:" % n_hosts)
    pp(off_ordered[n_hosts])
    
    print("migration_ordered[%d]:" % n_hosts)
    print(migration_ordered[n_hosts])

    ax2 = ax1.twinx()
    migration_plot, = ax2.plot(ind + width, migration_ordered[n_hosts], 'k--^', linewidth=linewidth)

    lim = ax2.get_ylim()
    ax2.set_ylim(lim[0], lim[1])
    ax2.set_yticks(range(0, int(math.ceil(max(migration_ordered[n_hosts]))), 500))

    for i,j in zip(ind + width, migration_ordered[n_hosts]):
        ax2.annotate(str(j), xy=(i,j + .5), va='bottom', weight='bold', size='large')

    lgd = ax1.legend((rects1[0], rects2[0], migration_plot),
            ('Not turning off hosts', 'Turning off hosts', 'No. VM migrations'),
            loc='lower right')

    def find_filename(format):
        i = 0
        path = format % i
        while os.path.isfile(path):
            i += 1
            path = format % i
        
        return path

    save_path = find_filename('energy_%d_%d_%d_%%d.pdf' % (n_hosts, load, std))
    plt.savefig(save_path, transparent=True, bbox_extra_artists=(lgd,), bbox_inches='tight')
    print('Saved plot as ' + save_path)
    if os.system('which imgcat > /dev/null 2>&1') == 0:
        os.system('imgcat ' + save_path)


########################################
# Make n_on plot
########################################
ordered_n_on = {}
plots = {}

styles = ['k-o', 'k-^', 'k-v', 'k-*']

for n_hosts in n_on:
    fig, ax1 = plt.subplots()

    if n_hosts not in ordered_n_on:
        ordered_n_on[n_hosts] = {}

    if n_hosts not in plots:
        plots[n_hosts] = {}

    i = 0
    for alg in ORDER:
        if alg not in n_on[n_hosts]:
            continue
        
        ordered_n_on[n_hosts][alg] = sorted(n_on[n_hosts][alg].items())
        plots[n_hosts][alg], = ax1.plot(map(lambda t: t[0], ordered_n_on[n_hosts][alg]),
                map(lambda t: t[1], ordered_n_on[n_hosts][alg]), styles[i], linewidth=linewidth, ms=8)
        i += 1
     
    print("ordered_n_on[%d]" % n_hosts)
    pp(ordered_n_on[n_hosts])

    lgd = ax1.legend(plots[n_hosts].values(),
            n_on[n_hosts].keys(),
            loc='upper right')

    ax1.set_xlim(0, simulation_time)
    ax1.set_ylim(20, n_hosts)

    save_path = find_filename('n_on_%d_%d_%d_%%d.pdf' % (n_hosts, load, std))
    plt.savefig(save_path, transparent=True, bbox_extra_artists=(lgd,), bbox_inches='tight')
    print('Saved plot as ' + save_path)
    if os.system('which imgcat > /dev/null 2>&1') == 0:
        os.system('imgcat ' + save_path)

########################################
# Make vm_on plot
########################################
n_vms_ordered = {}

linewidth = 1

for n_hosts in n_vms:
    fig, ax1 = plt.subplots()

    if n_hosts not in n_vms_ordered:
        n_vms_ordered[n_hosts] = {}

    i = 0
    colors = ['g', 'b', 'm', 'y']
    for alg in ORDER:
        if alg not in n_vms[n_hosts][True]:
            continue
        
        n_vms_ordered[n_hosts][alg] = sorted(n_vms[n_hosts][True][alg].items())
        plots[n_hosts][alg], = ax1.plot(map(lambda t: t[0], n_vms_ordered[n_hosts][alg]),
                map(lambda t: t[1], n_vms_ordered[n_hosts][alg]), colors[i] + '.-', linewidth=linewidth, ms=8)
        
        #for tick in scheduler_ticks[n_hosts][True][alg]:
        #   ax1.plot((tick, tick), (450, 512), colors[i] + '-')

        i += 1

    ax1.set_xlim(0, simulation_time)

    lgd = ax1.legend(plots[n_hosts].values(),
            n_on[n_hosts].keys(),
            loc='lower right')

    save_path = find_filename('vms_on_%d_%d_%d_%%d.pdf' % (n_hosts, load, std))
    plt.savefig(save_path, transparent=True, bbox_extra_artists=(lgd,), bbox_inches='tight')
    print('Saved plot as ' + save_path)
    if os.system('which imgcat > /dev/null 2>&1') == 0:
        os.system('imgcat ' + save_path)

<file_sep>/visu/README.md
# Visualisation tools

This folder contains a set of tools that helps to generate beautiful diagrams, in order to compare differents scheduling algorithms. Several metrics are reported by the SimgridInjector, scripts contained in this folder generates files from the reported metrics.

## Requirements
* Python
* R language
* easy_install
* Jinja (template engine for python)

## Installation

When ***generate_data.py*** is run, it will try to find *Jinja* by leveraging the *easy_install* library. To install easy_install, run the following:

```
$ apt-get install python-setuptools # Debian
$ brew install easy_install # MacOS
```

Then,


```
$ sudo ./generate_data.py
```

## Generate the diagrams

When a simulation is performed, an ***events.json*** file is generated, containing information about the experiments and the events that occured.

Just put this file in a folder (with the simulation name) inside the ***events*** folder, as illustrated in the following screenshot:

![image](https://raw.githubusercontent.com/BeyondTheClouds/VMPlaceS/master/docs/assets/img/screenshot_events.png)

Once it is done, just run the following command:

```
./generate_data.py ; ./generate_figures.py
```

The diagrams will auto-magically appear in the results folder!
<file_sep>/src/main/java/injector/InjectorEvent.java
package injector;

/**
 * Created with IntelliJ IDEA.
 * User: alebre
 * Date: 08/10/13
 * Time: 10:03
 * To change this template use File | Settings | File Templates.
 */
public interface InjectorEvent {

    long getId();
    double getTime();
    void play();

}
<file_sep>/config/centralizedResolver.properties
/**
 * This file is the main configuration file for the centralized scheduling management
 *
 **/

/**
 * Main properties
 **/

// The periodicity to invoke the scheduling algorithm (in seconds)
// Default: 30 seconds
centralizedresolver.scheduling-periodicity = 30




<file_sep>/config/dvms.properties
is_locality_based_scheduler = false

minimum_partition_size = 4<file_sep>/src/main/java/scheduling/centralized/ffd/LazyFirstFitDecreased.java
package scheduling.centralized.ffd;

import configuration.SimulatorProperties;
import configuration.XHost;
import configuration.XVM;
import simulation.SimulatorManager;

import java.util.*;

public class LazyFirstFitDecreased extends FirstFitDecreased {

    public LazyFirstFitDecreased(Collection<XHost> hosts) {
        this(hosts, new Random(SimulatorProperties.getSeed()).nextInt());
    }

    public LazyFirstFitDecreased(Collection<XHost> hosts, Integer id) {
        super(hosts, id);
    }

    @Override
    protected void manageOverloadedHost(List<XHost> overloadedHosts, ComputingResult result) {
        // The VMs are sorted by decreasing size of CPU and RAM capacity
        TreeSet<XVM> toSchedule = new TreeSet<>(new XVMComparator(true, useLoad));
        Map<XVM, XHost> sources = new HashMap<>();

        for(XHost host: SimulatorManager.getSGHostingHosts()) {
            predictedCPUDemand.put(host, host.getCPUDemand());
            predictedMemDemand.put(host, host.getMemDemand());
        }

        // Remove enough VMs so the overloaded hosts are no longer overloaded
        for(XHost host : overloadedHosts) {
            Iterator<XVM> vms = host.getRunnings().iterator();

            while((host.getCPUCapacity() < predictedCPUDemand.get(host) ||
                    host.getMemSize() < host.getMemDemand()) && vms.hasNext()) {
                XVM vm = vms.next();
                toSchedule.add(vm);
                sources.put(vm, host);
                predictedCPUDemand.put(host, predictedCPUDemand.get(host) - vm.getCPUDemand());
                predictedMemDemand.put(host, predictedMemDemand.get(host) - vm.getMemSize());
            }
        }

        for(XVM vm: toSchedule) {
            XHost dest = null;

            // Try find a new host for the VMs (saneHosts is not sorted)
            for(XHost host: SimulatorManager.getSGHostingHosts()) {
                if(host.getCPUCapacity() >= predictedCPUDemand.get(host) + vm.getCPUDemand() &&
                        host.getMemSize() >= predictedMemDemand.get(host) + vm.getMemSize()) {
                    dest = host;
                    break;
                }
            }

            if(dest == null) {
                result.state = ComputingResult.State.RECONFIGURATION_FAILED;
                return;
            }

            // Schedule the migration
            predictedCPUDemand.put(dest, predictedCPUDemand.get(dest) + vm.getCPUDemand());
            predictedMemDemand.put(dest, predictedMemDemand.get(dest) + vm.getMemSize());
            XHost source = sources.get(vm);
            if(!source.getName().equals(dest.getName())) {
                migrations.add(new Migration(vm, source, dest));
            }
        }
    }
}
<file_sep>/visu/generate_figures.py
#!/usr/bin/python

import csv
import subprocess
import time
import os


################################################################################
# Constant and parameters
################################################################################

duration = 3600

################################################################################
# Functions of the script
################################################################################
def execute_cmd(args):
	print "%s" % args
	# return "%s" % args
	out, err = subprocess.Popen(args,
                   shell=False,
                   stdout=subprocess.PIPE,
                   stderr=subprocess.PIPE).communicate()
	if not err == "":
		print err
	return out

################################################################################
# Clean results folder
################################################################################
execute_cmd(["rm", "-r", "results"])
execute_cmd(["mkdir", "results"])

################################################################################
# Regenerate allfigure.r
################################################################################
execute_cmd(["rm", "scripts/allfigure.r"])

open("scripts/allfigure.r", 'a').close()
all_figure_script = open("scripts/allfigure.r", 'a')
with all_figure_script as f:
    f.write("#!/usr/bin/env Rscript")

    execute_cmd(["chmod", "+x", "scripts/allfigure.r"])


    ############################################################################
    # Append all scripts to allfigure.r
    ############################################################################
    for dirname, dirnames, filenames in os.walk('./scripts'):
        # print path to all subdirectories first.
        for filename in filenames:
            if not filename == "allfigure.r":
                # print filename
                # ins = open("%s/%s" % (dirname, filename), "r" )
                # for line in ins:
                #     if not line.startswith("#!"):
                #     	popen("ls")
                #     	# execute_cmd(["echo", "toto"])
                execute_cmd(["/usr/bin/env", "Rscript", "%s/%s" % (dirname, filename)])
                basename_script = filename.split(".")[0]
                execute_cmd(["mv", "Rplots.pdf", "results/%s.pdf" % (basename_script)])
<file_sep>/src/main/java/configuration/ExtendedRandom.java
package configuration;

import java.util.Random;

public class ExtendedRandom extends Random {

	public ExtendedRandom() { super(); }
	public ExtendedRandom(long seed) {super(seed);}
	
	public double nextExp() {
		return - Math.log(1.0-nextDouble());
	}
	public double nextExp(double lambda) {
		return lambda*nextExp();
	}
	
	public double nextGamma(double shape) {
		
		if(shape == 1.0) {
			return nextExp();
		} else if (shape < 1.0) {
			double uniform, exp;
			while(true) {
				uniform = nextDouble();
				exp	= nextExp();
				if( uniform <= 1.0 - shape) {
					double res = Math.pow(uniform, 1.0/shape);
					if(res <= exp) return res;
				} else {
					double tmp = -Math.log((1-uniform) / shape);
					double res = Math.pow(1.0 + shape*(tmp - 1.0), 1.0/shape);
					if(res <= exp + tmp) return res;
				}
			}
		} else {
			double mshape = shape - (1.0/3.0);
			double coef = 1.0/Math.sqrt(9.0 * mshape);
			double g, tmp, uniform;
			while(true) {
				g = nextGaussian();
				tmp = 1.0 + coef * g;
				while (tmp <= 0.0) {
					g = nextGaussian();
					tmp = 1.0 + coef * g;
				}
				tmp = tmp * tmp * tmp; 
				uniform = nextDouble();
				if(uniform < 1.0 - 0.0331 * (g*g*g*g)) return (mshape * tmp);
				if(Math.log(uniform) < 0.5*g*g + mshape*(1.0 - tmp + Math.log(tmp))) return (mshape * tmp);
			}
		}
	}
	public double nextGamma(double shape, double scale) {
		return scale * nextGamma(shape);
	}
	
	public double nextBeta(double alpha, double beta) {
		if((alpha <= 1.0) && (beta <= 1.0)) {
			double p1, p2;
			while(true) {
				p1 = Math.pow(nextDouble(), 1.0/alpha);
				p2 = Math.pow(nextDouble(), 1.0/beta);
				if((p1 + p2) <= 1.0) 
					return (p1/(p1+p2));
			}
		} else {
			double g1 = nextGamma(alpha);
			double g2 = nextGamma(beta);
			return (g1/(g1+g2));
		}
	}
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
}
<file_sep>/src/main/java/scheduling/hierarchical/snooze/SnoozeProperties.java
package scheduling.hierarchical.snooze;

import configuration.SimulatorProperties;
import scheduling.GeneralProperties;

import java.io.File;

/**
 * Created by alebre on 16/07/14.
 */
public class SnoozeProperties extends GeneralProperties {


        private static final long serialVersionUID = 7229931356566105645L;

        //Default location of the properties file
        public static final String DEFAULT_PROP_FILE = "config" + File.separator + "snooze.properties";

        //Singleton
        public final static SnoozeProperties INSTANCE = new SnoozeProperties();


        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //Property keys
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        public final static String ALG_VARIANT = "snooze.alg-variant";
        public final static String GM_NUMBER = "snooze.gm-number";
        public final static String HEARTBEAT_PERIODICITY = "snooze.hb-periodicity";
        public final static String HEARTBEAT_TIMEOUT = "snooze.hb-timeout";
        public final static String SCHEDULING_PERIODIC = "snooze.scheduling-periodic";
        public final static String SCHEDULING_PERIODICITY = "snooze.scheduling-periodicity";
        public final static String INFO_LEVEL = "snooze.info-level";
        public final static String INFO_PERIODICITY = "snooze.info-periodicity";
        public final static String SIMULATE_LOCALCOMPUTATION = "snooze.simulate-localcomputation";

        public final static String FAULT_MODE = "snooze.faultmode";
        public final static String FAULT_MODE_GLPERIOD = "snooze.glcrash-period";
         public final static String FAULT_MODE_GMPERIOD = "snooze.gmcrash-period";

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //Property default values
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public final static int DEFAULT_GM_NUMBER = SimulatorProperties.getNbOfServiceNodes();
        public final static long DEFAULT_HEARTBEAT_PERIODICITY = 2;
        public final static boolean DEFAULT_SCHEDULING_PERIODIC = true;
        public final static long DEFAULT_SCHEDULING_PERIODICITY = 30;
        public final static long DEFAULT_HEARTBEAT_TIMEOUT = 5;


        public final static int DEFAULT_INFO_LEVEL = 2;
        public final static int DEFAULT_INFO_PERIODICITY = 5;

        public static boolean DEFAULT_SIMULATE_LOCALCOMPUTATION = false;
        public static boolean DEFAULT_FAULT_MODE = false ;
        public static long DEFAULT_FAULT_MODE_GLPERIOD = SimulatorProperties.getDuration()/2 ;
        public static long DEFAULT_FAULT_MODE_GMPERIOD = 300 ;

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //Constructors
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public SnoozeProperties(String file) {
            super(file);
        }

        public SnoozeProperties() {
            this(DEFAULT_PROP_FILE);
        }


        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //Class methods
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public static String getAlgVariant() {
        String algVariant = "";
        algVariant = INSTANCE.getProperty(ALG_VARIANT);
        if (algVariant.equals(""))
            algVariant = "hierarchical-" +
                    (getSchedulingPeriodic() ? "periodic" + getSchedulingPeriodicity() + "s-" : "reactive-") +
                    (SimulatorProperties.getNbOfServiceNodes()-1) + "GMs-" +
                    SimulatorProperties.getNbOfHostingNodes() + "LCs-" +
                    "beatFreq" + getHeartBeatPeriodicity() +"s";
        return algVariant;
    }

    public static int getGMNumber() {
            return INSTANCE.getPropertyAsInt(GM_NUMBER, DEFAULT_GM_NUMBER);

        }

        public static long getHeartBeatPeriodicity(){
            return INSTANCE.getPropertyAsLong(HEARTBEAT_PERIODICITY, DEFAULT_HEARTBEAT_PERIODICITY);
        }

        public static boolean getSchedulingPeriodic(){
           return INSTANCE.getPropertyAsBoolean(SCHEDULING_PERIODIC, DEFAULT_SCHEDULING_PERIODIC);
        }

        public static long getSchedulingPeriodicity(){
            return INSTANCE.getPropertyAsLong(SCHEDULING_PERIODICITY, DEFAULT_SCHEDULING_PERIODICITY);
        }

        public static long getHeartBeatTimeout() {
         return INSTANCE.getPropertyAsLong(HEARTBEAT_TIMEOUT, DEFAULT_HEARTBEAT_TIMEOUT);
        }

        public static int getInfoLevel() {
            return INSTANCE.getPropertyAsInt(INFO_LEVEL, DEFAULT_INFO_LEVEL);
        }

        public static int getInfoPeriodicity() {
            return INSTANCE.getPropertyAsInt(INFO_PERIODICITY, DEFAULT_INFO_PERIODICITY);
        }

    public static boolean shouldISleep() {
        return INSTANCE.getPropertyAsBoolean(SIMULATE_LOCALCOMPUTATION, DEFAULT_SIMULATE_LOCALCOMPUTATION);
    }

    public static boolean faultMode() {
        return INSTANCE.getPropertyAsBoolean(FAULT_MODE, DEFAULT_FAULT_MODE);
    }

    public static long getGLFaultPeriodicity(){
        return INSTANCE.getPropertyAsLong(FAULT_MODE_GLPERIOD, DEFAULT_FAULT_MODE_GLPERIOD);
    }

    public static long getGMFaultPeriodicity(){
        return INSTANCE.getPropertyAsLong(FAULT_MODE_GMPERIOD, DEFAULT_FAULT_MODE_GMPERIOD);
    }



    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //Methods for properties currently not stored in the properties file
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////


        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //Other methods
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////

}
<file_sep>/src/main/java/migration/MigrationPlan.java
package migration;

import configuration.*;

/**
 * Created by jonathan on 12/10/17.
 */
public class MigrationPlan {
    public XHost origin;
    public XHost destination;
    public configuration.XVM vm;
}
<file_sep>/src/main/java/bug/MyProcess.java
package bug;

import configuration.XHost;
import configuration.XVM;
import org.simgrid.msg.*;
import org.simgrid.msg.Process;

public class MyProcess extends Process {
    public MyProcess(Host host, String name, String[] args) throws HostNotFoundException {
        super(host, name, args);
    }

    @Override
    public void main(String[] args) throws MsgException {
        // Start a bunch of processes on node1
        Host node1 = Host.getByName("node1");
        XHost host = new XHost(node1, 4096, 8, 800,1000, null);
        Msg.info("Got " + node1.getName());

        XVM vm =  new XVM(host, "vm", 1, 1024, 125, null, 0, 125, 40);
        vm.start();
        vm.setLoad(20);

        waitFor(1000);
        vm.suspend();
        vm.setLoad(80);

        waitFor(10);
        vm.resume();
        waitFor(500);

        vm.shutdown();

        Msg.info("This is the end");
    }
}

<file_sep>/src/main/java/simulation/SimpleMain.java
/**
 * Copyright 2012-2013-2014. The SimGrid Team. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the license (GNU LGPL) which comes with this package.
 *
 * This file is the launcher on the Simgrid VM injector
 * The main is composed of three part:
 * 1./ Generate the deployment file according to the number of nodes and the algorithm you want to evaluate
 * 2./ Configure, instanciate and assign each VM on the different PMs
 * 3./ Launch the injector and the other simgrid processes in order to run the simulation.
 *
 * Please note that all parameters of the simulation are given in the ''simulator.properties'' file available
 * in the ''config'' directory
 *
 * @author: <EMAIL>
 */

package simulation;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.util.StatusPrinter;
import choco.cp.solver.constraints.global.geost.geometricPrim.Obj;
import com.hubspot.jinjava.Jinjava;
import configuration.SimulatorProperties;
import configuration.XHost;
import org.docopt.Docopt;
import org.json.JSONObject;
import org.simgrid.msg.Msg;
import org.simgrid.msg.Process;
import org.slf4j.LoggerFactory;
import scheduling.hierarchical.snooze.AUX;
import trace.Trace;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;


public class SimpleMain {

    private static final String doc =
        "VMPlaceS simulation launcher (simulation.Main).\n"
        + "\n"
        + "Usage:\n"
        + "  simplemain [--platform=FILE] [--deployment=FILE] --algo=<value> [--impl=<value>] [--duration=<value>] [--loadperiod=<value>] [--nb_hosts=<value>] [--nb_vms=<value>] [--netbw=<value>] [--vm_maxcpuconsumption=<value>] [--vm_nbcpuconsumptionslots=<value>] [--load_mean=<value>] [--load_std=<value>] [--dry-run]\n"
        + "  simplemain --list-algos\n"
        + "\n"
        + "Options:\n"
        + "  -h --help          Show this screen.\n"
        + "\n";

    private static JSONObject load_json_file(String filename) {
        String jsonContent;
        try {
            jsonContent = new Scanner(new File(filename)).useDelimiter("\\Z").next();
        } catch (FileNotFoundException e) {
            jsonContent = "{}";
        }
        return new JSONObject(jsonContent);
    }

    private static String get_template_content(String template_path) {
        String template_content;
        try {
            template_content = new Scanner(new File(template_path)).useDelimiter("\\Z").next();
        } catch (FileNotFoundException e) {
            template_content = "";
        }
        return template_content;
    }

    private static String get_deployment_template(String algorithm_name) {
        JSONObject algorithms_description = load_json_file("config/algorithms.json");
        String template_path = algorithms_description.getJSONObject("algorithms").getJSONObject(algorithm_name).getString("deploy_xml_template");

        return get_template_content(template_path);
    }

    private static Map<String, Object> build_context(Map<String, Object> opts) {
        JSONObject algorithms_description = load_json_file("config/algorithms.json");
        Map<String, Object> context = new HashMap<String, Object>();

        Object selected_algo = opts.get("--algo") != null ? opts.get("--algo") : SimulatorProperties.getAlgo();
        context.put("algo", selected_algo);

        String defaultImpl = algorithms_description.getJSONObject("algorithms").
                                                    getJSONObject(selected_algo.toString()).
                                                    getJSONArray("scheduling_algorithm").
                                                    get(0)
                                                    .toString();

        Object selected_impl = opts.get("--impl") != null? opts.get("--impl") : defaultImpl;
        context.put("impl", selected_impl);

        Object nb_hosts = opts.get("--nb_hosts") != null ? opts.get("--nb_hosts") : SimulatorProperties.getNbOfHostingNodes();
        context.put("nb_hosts", nb_hosts);

        Object nb_vms = opts.get("--nb_vms") != null ? opts.get("--nb_vms") : SimulatorProperties.getNbOfVMs();
        context.put("nb_vms", nb_vms);

        Object nb_service_nodes = opts.get("--nb_service_nodes") != null ? opts.get("--nb_service_nodes") : SimulatorProperties.getNbOfServiceNodes();
        context.put("nb_service_nodes", nb_service_nodes);

        Object nb_cpus = opts.get("--nb_cpus") != null ? opts.get("--nb_cpus") : SimulatorProperties.getNbOfCPUs();
        context.put("nb_cpus", nb_cpus);

        Object cpu_capacity = opts.get("--cpu_capacity") != null ? opts.get("--cpu_capacity") : SimulatorProperties.getCPUCapacity();
        context.put("cpu_capacity", cpu_capacity);

        Object ram_capacity = opts.get("--ram_capacity") != null ? opts.get("--ram_capacity") : SimulatorProperties.getMemoryTotal();
        context.put("ram_capacity", ram_capacity);

        Object netbw = opts.get("--netbw") != null ? opts.get("--netbw") : SimulatorProperties.getNetCapacity();
        context.put("netbw", netbw);

        Object vm_maxcpuconsumption = opts.get("--vm_maxcpuconsumption") != null ? opts.get("--vm_maxcpuconsumption") : SimulatorProperties.getVMMAXCPUConsumption();
        context.put("vm_maxcpuconsumption", vm_maxcpuconsumption);

        Object vm_nbcpuconsumptionslots = opts.get("--vm_nbcpuconsumptionslots") != null ? opts.get("--vm_nbcpuconsumptionslots") : SimulatorProperties.getNbOfCPUConsumptionSlots();
        context.put("vm_nbcpuconsumptionslots", vm_nbcpuconsumptionslots);

        Object load_mean = opts.get("--load_mean") != null ? opts.get("--load_mean") : SimulatorProperties.getMeanLoad();
        context.put("load_mean", load_mean);

        Object load_std = opts.get("--load_std") != null ? opts.get("--load_std") : SimulatorProperties.getStandardDeviationLoad();
        context.put("load_std", load_std);

        Object duration = opts.get("--duration") != null ? opts.get("--duration") : SimulatorProperties.getDuration();
        context.put("duration", duration);

        Object loadperiod = opts.get("--loadperiod") != null ? opts.get("--loadperiod") : SimulatorProperties.getLoadPeriod();
        context.put("loadperiod", loadperiod);

        Object port = opts.get("--port") != null ? opts.get("--port") : 23000;
        context.put("port", port);

        List<Integer> range = IntStream.range(0, Integer.parseInt(nb_hosts.toString())).boxed().collect(Collectors.toList());
        context.put("node_range", range);

        return context;
    }

    private static boolean generate_deployment_file(String output_path, Map<String, Object> context) {
        Jinjava jinjava = new Jinjava ();
        String templateContent = get_deployment_template(SimulatorProperties.getAlgo());

        String renderedTemplate = jinjava.render(templateContent, context);

        try(  PrintWriter out = new PrintWriter(output_path)  ){
            out.println(renderedTemplate);
        } catch (FileNotFoundException e) {
            return false;
        }

        return true;
    }

    private static boolean generate_platform_file(String output_path, Map<String, Object> context) {
        Jinjava jinjava = new Jinjava ();
        String templateContent = get_template_content("./templates/cluster_platform.xml");

        String renderedTemplate = jinjava.render(templateContent, context);

        try(  PrintWriter out = new PrintWriter(output_path)  ){
            out.println(renderedTemplate);
        } catch (FileNotFoundException e) {
            return false;
        }

        return true;
    }

    private static boolean generate_simulation_config_file(String output_path, Map<String, Object> context) {
        Jinjava jinjava = new Jinjava ();
        String templateContent = get_template_content("./templates/simulator.properties");

        String renderedTemplate = jinjava.render(templateContent, context);

        try(  PrintWriter out = new PrintWriter(output_path)  ){
            out.println(renderedTemplate);
        } catch (FileNotFoundException e) {
            return false;
        }

        return true;
    }

    /**
     * The Simulator launcher
     *
     * @param args
     */
    public static void main(String[] args) throws Exception {

        Map<String, Object> opts =
                new Docopt(doc).withVersion("VMPlaceS 1.0").parse(args);
        System.out.println(opts);

        Map<String, Object> context = build_context(opts);

        // Historical fix to get the internal logs of Entropy correctly
        // assume SLF4J is bound to logback in the current environment
        LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
        // print logback's internal status
        StatusPrinter.print(lc);

        // Save the begining time
        SimulatorManager.setBeginTimeOfSimulation(System.currentTimeMillis());

        // Create temporary folder
        File file = new File("./tmp/config");
        if (!file.exists()) {
            file.mkdirs();
        }

        // Generate configuration file
        String generated_config_path = "./tmp/config/simulator.properties";
        boolean configuration_is_generated = generate_simulation_config_file(generated_config_path, context);
        if (! configuration_is_generated) {
            throw new Exception(String.format("Could not generate '%s'", generated_config_path));
        }
        SimulatorProperties.setInstance(new SimulatorProperties(generated_config_path));

        // Generate platform file
        String generated_platform_path = "./tmp/config/cluster_platform.xml";
        boolean platform_is_generated = generate_platform_file(generated_platform_path, context);
        if (! platform_is_generated) {
            throw new Exception(String.format("Could not generate '%s'", generated_platform_path));
        }

        // Generate a deployment file
        String generated_deploy_path = "./tmp/config/generated_deploy.xml";
        boolean deployment_is_generated = generate_deployment_file(generated_deploy_path, context);
        if (! deployment_is_generated) {
            throw new Exception(String.format("Could not generate '%s'", generated_deploy_path));
        }

        String platformConfigurationLocation = "./tmp/config/cluster_platform.xml";
        String deploymentConfigurationLocation = "./tmp/config/generated_deploy.xml";

        if (opts.containsKey("--dry-run") && opts.get("--dry-run").toString().equals("true")) {
            return;
        }

        // Init. internal values
        Msg.energyInit();
        String[] classpathOptions = {
                platformConfigurationLocation,
                deploymentConfigurationLocation,
                "--cfg=cpu/optim:Full",
                "--cfg=tracing:1",
                "--cfg=tracing/filename:simu.trace",
                "--cfg=tracing/platform:1"
        };
        Msg.init(classpathOptions);

        Msg.createEnvironment(platformConfigurationLocation);
        Msg.deployApplication(deploymentConfigurationLocation);

        /* Create all VM instances and assign them on the PMs */
        /* The initial deployment is based on a round robin fashion */
        System.out.println("Configure simulation" + new Date().toString());
        SimulatorManager.cleanLog();
        // True means round robin placement.
        SimulatorManager.configureHostsAndVMs(SimulatorProperties.getNbOfHostingNodes(), SimulatorProperties.getNbOfServiceNodes(), SimulatorProperties.getNbOfVMs(), true);
        SimulatorManager.writeCurrentConfiguration();

        String algorithmName = SimulatorProperties.getAlgo();
        String algorithmDetails = "{}";
        if (algorithmName.equals("hierarchical")) {
            int lcsRatio = SimulatorProperties.getNbOfHostingNodes() / (SimulatorProperties.getNbOfServiceNodes() -1 );
            algorithmDetails = String.format("{\"assignmentAlgorithm\": \"%s\", \"lcsRatio\": %d}", AUX.assignmentAlg, lcsRatio);
        }

        if(algorithmName.equals("centralized"))
            algorithmName = SimulatorProperties.getImplementation().substring(SimulatorProperties.getImplementation().lastIndexOf('.') + 1);

        Trace.simulationDeclare(algorithmName, SimulatorProperties.getNbOfHostingNodes(), SimulatorProperties.getNbOfServiceNodes(), SimulatorProperties.getNbOfVMs(), algorithmDetails);

        /* Prepare TRACE variables */
        System.out.println("Prepare TRACE module" + new Date().toString());
        // A node can be underloaded
        Trace.hostStateDeclare("PM");
        Trace.hostStateDeclareValue("PM", "underloaded", "0 1 1");
        Trace.hostStateDeclareValue("PM", "normal", "1 1 1");
        Trace.hostStateDeclareValue("PM", "violation", "1 0 0");
        Trace.hostStateDeclareValue("PM", "violation-det", "0 1 0");
        Trace.hostStateDeclareValue("PM", "violation-out", "1 0 0");

        Trace.hostStateDeclare("SERVICE");
        Trace.hostStateDeclareValue("SERVICE", "free", "1 1 1");
        Trace.hostStateDeclareValue("SERVICE", "booked", "0 0 1");
        Trace.hostStateDeclareValue("SERVICE", "compute", "1 0 1");
        Trace.hostStateDeclareValue("SERVICE", "reconfigure", "1 1 0");
        Trace.hostStateDeclareValue("SERVICE", "migrate", "1 0 0");

        Trace.hostVariableDeclare("LOAD");
        Trace.hostVariableDeclare("NB_MC");  // Nb of microcosms (only for DVMS)
        Trace.hostVariableDeclare("NB_MIG"); //Nb of migration
        Trace.hostVariableDeclare("NB_VM"); //To follow number of VMs.
        Trace.hostVariableDeclare("NB_VM_TRUE"); //To follow the true number of VMs.

        Trace.hostVariableDeclare("ENERGY");
        Trace.hostVariableDeclare("NB_OFF"); //Nb of hosts turned off
        Trace.hostVariableDeclare("NB_ON"); //Nb of hosts turned on

        for(XHost host: SimulatorManager.getSGHosts()) {
            Trace.hostVariableSet(host.getName(), "NB_ON", 1);
            Trace.hostVariableSet(host.getName(), "NB_OFF", 0);
        }

        // Turn off the hosts that we don't need
        int nOff = 0;
        if(SimulatorProperties.getHostsTurnoff()) {
            for (XHost h : SimulatorManager.getSGHostingHosts())
                if (h.getRunnings().size() <= 0) {
                    SimulatorManager.turnOff(h);
                    nOff++;
                }
            Msg.info(String.format("Turned off unused %d nodes before starting", nOff));
        }

	    /*  execute the simulation. */
        System.out.println("Launcher: begin Msg.run()" + new Date().toString());
        notify(String.format("Started %s with %d hosts and %d VMs", SimulatorProperties.getImplementation(), SimulatorProperties.getNbOfHostingNodes(), SimulatorProperties.getNbOfVMs()));

        Msg.run();

        System.out.println("Launcher: end of Msg.run()" + new Date().toString());
        Trace.close();
        Msg.info("End of run");

        notify(String.format("End of simulation %s", SimulatorProperties.getImplementation()));

        Process.killAll(-1);
        Msg.info(String.format("There are still %d processes running", Process.getCount()));
    }

    private static void notify(String message) {
        Msg.info(message);
    }
}
<file_sep>/docs/javadoc/index-files/index-18.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (1.8.0_131) on Wed Dec 13 18:37:12 CET 2017 -->
<title>T-Index</title>
<meta name="date" content="2017-12-13">
<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
<script type="text/javascript" src="../script.js"></script>
</head>
<body>
<script type="text/javascript"><!--
    try {
        if (location.href.indexOf('is-external=true') == -1) {
            parent.document.title="T-Index";
        }
    }
    catch(err) {
    }
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<!-- ========= START OF TOP NAVBAR ======= -->
<div class="topNav"><a name="navbar.top">
<!--   -->
</a>
<div class="skipNav"><a href="#skip.navbar.top" title="Skip navigation links">Skip navigation links</a></div>
<a name="navbar.top.firstrow">
<!--   -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../overview-summary.html">Overview</a></li>
<li>Package</li>
<li>Class</li>
<li><a href="../overview-tree.html">Tree</a></li>
<li><a href="../deprecated-list.html">Deprecated</a></li>
<li class="navBarCell1Rev">Index</li>
<li><a href="../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="index-17.html">Prev Letter</a></li>
<li><a href="index-19.html">Next Letter</a></li>
</ul>
<ul class="navList">
<li><a href="../index.html?index-files/index-18.html" target="_top">Frames</a></li>
<li><a href="index-18.html" target="_top">No&nbsp;Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_top">
<li><a href="../allclasses-noframe.html">All&nbsp;Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
  allClassesLink = document.getElementById("allclasses_navbar_top");
  if(window==top) {
    allClassesLink.style.display = "block";
  }
  else {
    allClassesLink.style.display = "none";
  }
  //-->
</script>
</div>
<a name="skip.navbar.top">
<!--   -->
</a></div>
<!-- ========= END OF TOP NAVBAR ========= -->
<div class="contentContainer"><a href="index-1.html">A</a>&nbsp;<a href="index-2.html">B</a>&nbsp;<a href="index-3.html">C</a>&nbsp;<a href="index-4.html">D</a>&nbsp;<a href="index-5.html">E</a>&nbsp;<a href="index-6.html">F</a>&nbsp;<a href="index-7.html">G</a>&nbsp;<a href="index-8.html">H</a>&nbsp;<a href="index-9.html">I</a>&nbsp;<a href="index-10.html">K</a>&nbsp;<a href="index-11.html">L</a>&nbsp;<a href="index-12.html">M</a>&nbsp;<a href="index-13.html">N</a>&nbsp;<a href="index-14.html">O</a>&nbsp;<a href="index-15.html">P</a>&nbsp;<a href="index-16.html">R</a>&nbsp;<a href="index-17.html">S</a>&nbsp;<a href="index-18.html">T</a>&nbsp;<a href="index-19.html">U</a>&nbsp;<a href="index-20.html">V</a>&nbsp;<a href="index-21.html">W</a>&nbsp;<a href="index-22.html">X</a>&nbsp;<a name="I:T">
<!--   -->
</a>
<h2 class="title">T</h2>
<dl>
<dt><a href="../scheduling/hierarchical/snooze/msg/TermGLMsg.html" title="class in scheduling.hierarchical.snooze.msg"><span class="typeNameLink">TermGLMsg</span></a> - Class in <a href="../scheduling/hierarchical/snooze/msg/package-summary.html">scheduling.hierarchical.snooze.msg</a></dt>
<dd>
<div class="block">Created by sudholt on 20/07/2014.</div>
</dd>
<dt><span class="memberNameLink"><a href="../scheduling/hierarchical/snooze/msg/TermGLMsg.html#TermGLMsg-java.lang.String-java.lang.String-java.lang.String-java.lang.String-">TermGLMsg(String, String, String, String)</a></span> - Constructor for class scheduling.hierarchical.snooze.msg.<a href="../scheduling/hierarchical/snooze/msg/TermGLMsg.html" title="class in scheduling.hierarchical.snooze.msg">TermGLMsg</a></dt>
<dd>&nbsp;</dd>
<dt><a href="../scheduling/hierarchical/snooze/msg/TermGMMsg.html" title="class in scheduling.hierarchical.snooze.msg"><span class="typeNameLink">TermGMMsg</span></a> - Class in <a href="../scheduling/hierarchical/snooze/msg/package-summary.html">scheduling.hierarchical.snooze.msg</a></dt>
<dd>
<div class="block">Created by sudholt on 04/07/2014.</div>
</dd>
<dt><span class="memberNameLink"><a href="../scheduling/hierarchical/snooze/msg/TermGMMsg.html#TermGMMsg-java.lang.String-java.lang.String-java.lang.String-java.lang.String-">TermGMMsg(String, String, String, String)</a></span> - Constructor for class scheduling.hierarchical.snooze.msg.<a href="../scheduling/hierarchical/snooze/msg/TermGMMsg.html" title="class in scheduling.hierarchical.snooze.msg">TermGMMsg</a></dt>
<dd>&nbsp;</dd>
<dt><a href="../test/package-summary.html">test</a> - package test</dt>
<dd>&nbsp;</dd>
<dt><a href="../scheduling/hierarchical/snooze/Test.html" title="class in scheduling.hierarchical.snooze"><span class="typeNameLink">Test</span></a> - Class in <a href="../scheduling/hierarchical/snooze/package-summary.html">scheduling.hierarchical.snooze</a></dt>
<dd>
<div class="block">Created by sudholt on 20/07/2014.</div>
</dd>
<dt><span class="memberNameLink"><a href="../scheduling/hierarchical/snooze/Test.html#Test-org.simgrid.msg.Host-java.lang.String-">Test(Host, String)</a></span> - Constructor for class scheduling.hierarchical.snooze.<a href="../scheduling/hierarchical/snooze/Test.html" title="class in scheduling.hierarchical.snooze">Test</a></dt>
<dd>&nbsp;</dd>
<dt><a href="../test/TestA.html" title="class in test"><span class="typeNameLink">TestA</span></a> - Class in <a href="../test/package-summary.html">test</a></dt>
<dd>&nbsp;</dd>
<dt><span class="memberNameLink"><a href="../test/TestA.html#TestA-org.simgrid.msg.Host-java.lang.String-java.lang.String:A-">TestA(Host, String, String[])</a></span> - Constructor for class test.<a href="../test/TestA.html" title="class in test">TestA</a></dt>
<dd>&nbsp;</dd>
<dt><a href="../test/TestB.html" title="class in test"><span class="typeNameLink">TestB</span></a> - Class in <a href="../test/package-summary.html">test</a></dt>
<dd>&nbsp;</dd>
<dt><span class="memberNameLink"><a href="../test/TestB.html#TestB-org.simgrid.msg.Host-java.lang.String-java.lang.String:A-">TestB(Host, String, String[])</a></span> - Constructor for class test.<a href="../test/TestB.html" title="class in test">TestB</a></dt>
<dd>&nbsp;</dd>
<dt><a href="../scheduling/hierarchical/snooze/msg/TestFailGLMsg.html" title="class in scheduling.hierarchical.snooze.msg"><span class="typeNameLink">TestFailGLMsg</span></a> - Class in <a href="../scheduling/hierarchical/snooze/msg/package-summary.html">scheduling.hierarchical.snooze.msg</a></dt>
<dd>
<div class="block">Created by sudholt on 19/07/2014.</div>
</dd>
<dt><span class="memberNameLink"><a href="../scheduling/hierarchical/snooze/msg/TestFailGLMsg.html#TestFailGLMsg-java.lang.String-java.lang.String-java.lang.String-java.lang.String-">TestFailGLMsg(String, String, String, String)</a></span> - Constructor for class scheduling.hierarchical.snooze.msg.<a href="../scheduling/hierarchical/snooze/msg/TestFailGLMsg.html" title="class in scheduling.hierarchical.snooze.msg">TestFailGLMsg</a></dt>
<dd>&nbsp;</dd>
<dt><a href="../scheduling/hierarchical/snooze/msg/TestFailGMMsg.html" title="class in scheduling.hierarchical.snooze.msg"><span class="typeNameLink">TestFailGMMsg</span></a> - Class in <a href="../scheduling/hierarchical/snooze/msg/package-summary.html">scheduling.hierarchical.snooze.msg</a></dt>
<dd>
<div class="block">Created by sudholt on 20/07/2014.</div>
</dd>
<dt><span class="memberNameLink"><a href="../scheduling/hierarchical/snooze/msg/TestFailGMMsg.html#TestFailGMMsg-java.lang.String-java.lang.String-java.lang.String-java.lang.String-">TestFailGMMsg(String, String, String, String)</a></span> - Constructor for class scheduling.hierarchical.snooze.msg.<a href="../scheduling/hierarchical/snooze/msg/TestFailGMMsg.html" title="class in scheduling.hierarchical.snooze.msg">TestFailGMMsg</a></dt>
<dd>&nbsp;</dd>
<dt><span class="memberNameLink"><a href="../scheduling/hierarchical/snooze/Test.html#testsToBeTerminated">testsToBeTerminated</a></span> - Variable in class scheduling.hierarchical.snooze.<a href="../scheduling/hierarchical/snooze/Test.html" title="class in scheduling.hierarchical.snooze">Test</a></dt>
<dd>&nbsp;</dd>
<dt><a href="../scheduling/hierarchical/snooze/ThreadPool.html" title="class in scheduling.hierarchical.snooze"><span class="typeNameLink">ThreadPool</span></a> - Class in <a href="../scheduling/hierarchical/snooze/package-summary.html">scheduling.hierarchical.snooze</a></dt>
<dd>
<div class="block">Created by sudholt on 31/07/2014.</div>
</dd>
<dt><span class="memberNameLink"><a href="../scheduling/distributed/dvms2/TimeoutCheckerProcess.html#timeoutActor">timeoutActor</a></span> - Variable in class scheduling.distributed.dvms2.<a href="../scheduling/distributed/dvms2/TimeoutCheckerProcess.html" title="class in scheduling.distributed.dvms2">TimeoutCheckerProcess</a></dt>
<dd>&nbsp;</dd>
<dt><span class="memberNameLink"><a href="../scheduling/distributed/dvms2/TimeoutCheckerProcess.TimeoutCheckerActor.html#TimeoutCheckerActor-scheduling.distributed.dvms2.SGNodeRef-configuration.XHost-scheduling.distributed.dvms2.DVMSProcess-">TimeoutCheckerActor(SGNodeRef, XHost, DVMSProcess)</a></span> - Constructor for class scheduling.distributed.dvms2.<a href="../scheduling/distributed/dvms2/TimeoutCheckerProcess.TimeoutCheckerActor.html" title="class in scheduling.distributed.dvms2">TimeoutCheckerProcess.TimeoutCheckerActor</a></dt>
<dd>&nbsp;</dd>
<dt><a href="../scheduling/distributed/dvms2/TimeoutCheckerProcess.html" title="class in scheduling.distributed.dvms2"><span class="typeNameLink">TimeoutCheckerProcess</span></a> - Class in <a href="../scheduling/distributed/dvms2/package-summary.html">scheduling.distributed.dvms2</a></dt>
<dd>&nbsp;</dd>
<dt><span class="memberNameLink"><a href="../scheduling/distributed/dvms2/TimeoutCheckerProcess.html#TimeoutCheckerProcess-configuration.XHost-java.lang.String-int-scheduling.distributed.dvms2.SGNodeRef-scheduling.distributed.dvms2.DVMSProcess-">TimeoutCheckerProcess(XHost, String, int, SGNodeRef, DVMSProcess)</a></span> - Constructor for class scheduling.distributed.dvms2.<a href="../scheduling/distributed/dvms2/TimeoutCheckerProcess.html" title="class in scheduling.distributed.dvms2">TimeoutCheckerProcess</a></dt>
<dd>&nbsp;</dd>
<dt><a href="../scheduling/distributed/dvms2/TimeoutCheckerProcess.TimeoutCheckerActor.html" title="class in scheduling.distributed.dvms2"><span class="typeNameLink">TimeoutCheckerProcess.TimeoutCheckerActor</span></a> - Class in <a href="../scheduling/distributed/dvms2/package-summary.html">scheduling.distributed.dvms2</a></dt>
<dd>&nbsp;</dd>
<dt><a href="../scheduling/distributed/dvms2/TimeoutSnoozerProcess.html" title="class in scheduling.distributed.dvms2"><span class="typeNameLink">TimeoutSnoozerProcess</span></a> - Class in <a href="../scheduling/distributed/dvms2/package-summary.html">scheduling.distributed.dvms2</a></dt>
<dd>
<div class="block">Created by jonathan on 24/11/14.</div>
</dd>
<dt><span class="memberNameLink"><a href="../scheduling/distributed/dvms2/TimeoutSnoozerProcess.html#TimeoutSnoozerProcess-org.simgrid.msg.Host-java.lang.String-java.lang.String-int-">TimeoutSnoozerProcess(Host, String, String, int)</a></span> - Constructor for class scheduling.distributed.dvms2.<a href="../scheduling/distributed/dvms2/TimeoutSnoozerProcess.html" title="class in scheduling.distributed.dvms2">TimeoutSnoozerProcess</a></dt>
<dd>&nbsp;</dd>
<dt><span class="memberNameLink"><a href="../configuration/VMClasses.VMClass.html#toString--">toString()</a></span> - Method in class configuration.<a href="../configuration/VMClasses.VMClass.html" title="class in configuration">VMClasses.VMClass</a></dt>
<dd>&nbsp;</dd>
<dt><span class="memberNameLink"><a href="../configuration/XVM.html#toString--">toString()</a></span> - Method in class configuration.<a href="../configuration/XVM.html" title="class in configuration">XVM</a></dt>
<dd>&nbsp;</dd>
<dt><span class="memberNameLink"><a href="../injector/FaultEvent.html#toString--">toString()</a></span> - Method in class injector.<a href="../injector/FaultEvent.html" title="class in injector">FaultEvent</a></dt>
<dd>&nbsp;</dd>
<dt><span class="memberNameLink"><a href="../injector/LoadEvent.html#toString--">toString()</a></span> - Method in class injector.<a href="../injector/LoadEvent.html" title="class in injector">LoadEvent</a></dt>
<dd>&nbsp;</dd>
<dt><span class="memberNameLink"><a href="../injector/VMSuspendResumeEvent.html#toString--">toString()</a></span> - Method in class injector.<a href="../injector/VMSuspendResumeEvent.html" title="class in injector">VMSuspendResumeEvent</a></dt>
<dd>&nbsp;</dd>
<dt><span class="memberNameLink"><a href="../scheduling/distributed/dvms2/SGNodeRef.html#toString--">toString()</a></span> - Method in class scheduling.distributed.dvms2.<a href="../scheduling/distributed/dvms2/SGNodeRef.html" title="class in scheduling.distributed.dvms2">SGNodeRef</a></dt>
<dd>&nbsp;</dd>
<dt><span class="memberNameLink"><a href="../scheduling/hierarchical/snooze/msg/SnoozeMsg.html#toString--">toString()</a></span> - Method in class scheduling.hierarchical.snooze.msg.<a href="../scheduling/hierarchical/snooze/msg/SnoozeMsg.html" title="class in scheduling.hierarchical.snooze.msg">SnoozeMsg</a></dt>
<dd>&nbsp;</dd>
<dt><span class="memberNameLink"><a href="../scheduling/Scheduler.ComputingResult.State.html#toString--">toString()</a></span> - Method in enum scheduling.<a href="../scheduling/Scheduler.ComputingResult.State.html" title="enum in scheduling">Scheduler.ComputingResult.State</a></dt>
<dd>&nbsp;</dd>
<dt><span class="memberNameLink"><a href="../scheduling/Scheduler.SchedulerResult.State.html#toString--">toString()</a></span> - Method in enum scheduling.<a href="../scheduling/Scheduler.SchedulerResult.State.html" title="enum in scheduling">Scheduler.SchedulerResult.State</a></dt>
<dd>&nbsp;</dd>
<dt><a href="../trace/package-summary.html">trace</a> - package trace</dt>
<dd>&nbsp;</dd>
<dt><a href="../trace/Trace.html" title="class in trace"><span class="typeNameLink">Trace</span></a> - Class in <a href="../trace/package-summary.html">trace</a></dt>
<dd>
<div class="block">Created by jonathan on 17/09/14.</div>
</dd>
<dt><span class="memberNameLink"><a href="../trace/Trace.html#Trace--">Trace()</a></span> - Constructor for class trace.<a href="../trace/Trace.html" title="class in trace">Trace</a></dt>
<dd>&nbsp;</dd>
<dt><a href="../trace/TraceImpl.html" title="class in trace"><span class="typeNameLink">TraceImpl</span></a> - Class in <a href="../trace/package-summary.html">trace</a></dt>
<dd>
<div class="block">Copyright 2012-2013-2014.</div>
</dd>
<dt><span class="memberNameLink"><a href="../trace/TraceImpl.html#TraceImpl--">TraceImpl()</a></span> - Constructor for class trace.<a href="../trace/TraceImpl.html" title="class in trace">TraceImpl</a></dt>
<dd>&nbsp;</dd>
<dt><a href="../trace/TraceTest.html" title="class in trace"><span class="typeNameLink">TraceTest</span></a> - Class in <a href="../trace/package-summary.html">trace</a></dt>
<dd>&nbsp;</dd>
<dt><span class="memberNameLink"><a href="../trace/TraceTest.html#TraceTest--">TraceTest()</a></span> - Constructor for class trace.<a href="../trace/TraceTest.html" title="class in trace">TraceTest</a></dt>
<dd>&nbsp;</dd>
<dt><span class="memberNameLink"><a href="../configuration/XHost.html#turnOff--">turnOff()</a></span> - Method in class configuration.<a href="../configuration/XHost.html" title="class in configuration">XHost</a></dt>
<dd>
<div class="block">turnOff a host (the host should be off, otherwise nothing happens)</div>
</dd>
<dt><span class="memberNameLink"><a href="../simulation/SimulatorManager.html#turnOff-configuration.XHost-">turnOff(XHost)</a></span> - Static method in class simulation.<a href="../simulation/SimulatorManager.html" title="class in simulation">SimulatorManager</a></dt>
<dd>
<div class="block">Turn off the XHost host</div>
</dd>
<dt><span class="memberNameLink"><a href="../configuration/XHost.html#turnOn--">turnOn()</a></span> - Method in class configuration.<a href="../configuration/XHost.html" title="class in configuration">XHost</a></dt>
<dd>
<div class="block">Turn on a host (the host should have been turn off previously), otherwise nothing happens</div>
</dd>
<dt><span class="memberNameLink"><a href="../simulation/SimulatorManager.html#turnOn-configuration.XHost-">turnOn(XHost)</a></span> - Static method in class simulation.<a href="../simulation/SimulatorManager.html" title="class in simulation">SimulatorManager</a></dt>
<dd>
<div class="block">Turn on the XHost host</div>
</dd>
</dl>
<a href="index-1.html">A</a>&nbsp;<a href="index-2.html">B</a>&nbsp;<a href="index-3.html">C</a>&nbsp;<a href="index-4.html">D</a>&nbsp;<a href="index-5.html">E</a>&nbsp;<a href="index-6.html">F</a>&nbsp;<a href="index-7.html">G</a>&nbsp;<a href="index-8.html">H</a>&nbsp;<a href="index-9.html">I</a>&nbsp;<a href="index-10.html">K</a>&nbsp;<a href="index-11.html">L</a>&nbsp;<a href="index-12.html">M</a>&nbsp;<a href="index-13.html">N</a>&nbsp;<a href="index-14.html">O</a>&nbsp;<a href="index-15.html">P</a>&nbsp;<a href="index-16.html">R</a>&nbsp;<a href="index-17.html">S</a>&nbsp;<a href="index-18.html">T</a>&nbsp;<a href="index-19.html">U</a>&nbsp;<a href="index-20.html">V</a>&nbsp;<a href="index-21.html">W</a>&nbsp;<a href="index-22.html">X</a>&nbsp;</div>
<!-- ======= START OF BOTTOM NAVBAR ====== -->
<div class="bottomNav"><a name="navbar.bottom">
<!--   -->
</a>
<div class="skipNav"><a href="#skip.navbar.bottom" title="Skip navigation links">Skip navigation links</a></div>
<a name="navbar.bottom.firstrow">
<!--   -->
</a>
<ul class="navList" title="Navigation">
<li><a href="../overview-summary.html">Overview</a></li>
<li>Package</li>
<li>Class</li>
<li><a href="../overview-tree.html">Tree</a></li>
<li><a href="../deprecated-list.html">Deprecated</a></li>
<li class="navBarCell1Rev">Index</li>
<li><a href="../help-doc.html">Help</a></li>
</ul>
</div>
<div class="subNav">
<ul class="navList">
<li><a href="index-17.html">Prev Letter</a></li>
<li><a href="index-19.html">Next Letter</a></li>
</ul>
<ul class="navList">
<li><a href="../index.html?index-files/index-18.html" target="_top">Frames</a></li>
<li><a href="index-18.html" target="_top">No&nbsp;Frames</a></li>
</ul>
<ul class="navList" id="allclasses_navbar_bottom">
<li><a href="../allclasses-noframe.html">All&nbsp;Classes</a></li>
</ul>
<div>
<script type="text/javascript"><!--
  allClassesLink = document.getElementById("allclasses_navbar_bottom");
  if(window==top) {
    allClassesLink.style.display = "block";
  }
  else {
    allClassesLink.style.display = "none";
  }
  //-->
</script>
</div>
<a name="skip.navbar.bottom">
<!--   -->
</a></div>
<!-- ======== END OF BOTTOM NAVBAR ======= -->
</body>
</html>
<file_sep>/src/main/java/scheduling/centralized/ffd/OptimisticFirstFitDecreased.java
package scheduling.centralized.ffd;

import configuration.SimulatorProperties;
import configuration.XHost;
import configuration.XVM;
import org.simgrid.msg.Msg;
import simulation.SimulatorManager;

import java.util.*;

public class OptimisticFirstFitDecreased extends FirstFitDecreased {

    public OptimisticFirstFitDecreased(Collection<XHost> hosts) {
        this(hosts, new Random(SimulatorProperties.getSeed()).nextInt());
    }

    public OptimisticFirstFitDecreased(Collection<XHost> hosts, Integer id) {
        super(hosts, id);
    }

    @Override
    protected void manageOverloadedHost(List<XHost> overloadedHosts, ComputingResult result) {
        TreeSet<XVM> toSchedule = new TreeSet<>(new XVMComparator(true, useLoad));
        Map<XVM, XHost> sources = new HashMap<>();

        for(XHost host: SimulatorManager.getSGHostingHosts()) {
            predictedCPUDemand.put(host, host.getCPUDemand());
            predictedMemDemand.put(host, host.getMemDemand());
        }

        // Remove all VMs from the overloaded hosts
        for(XHost host: overloadedHosts) {
            for(XVM vm: host.getRunnings()) {
                toSchedule.add(vm);
                sources.put(vm, host);
            }

            predictedCPUDemand.put(host, 0D);
            predictedMemDemand.put(host, 0);
        }

        for(XVM vm: toSchedule) {
            XHost dest = null;

            // Try find a new host for the VMs
            for(XHost host: SimulatorManager.getSGHostingHosts()) {
                if(host.getCPUCapacity() >= predictedCPUDemand.get(host) + vm.getCPUDemand() &&
                        host.getMemSize() >= predictedMemDemand.get(host) + vm.getMemSize()) {
                    dest = host;
                    break;
                }
            }

            if(dest == null) {
                result.state = ComputingResult.State.RECONFIGURATION_FAILED;
                return;
            }

            if(predictedCPUDemand.get(dest) >= dest.getCPUCapacity())
                System.out.println("!!");
            // Schedule the migration
            predictedCPUDemand.put(dest, predictedCPUDemand.get(dest) + vm.getCPUDemand());
            predictedMemDemand.put(dest, predictedMemDemand.get(dest) + vm.getMemSize());
            XHost source = sources.get(vm);
            if(!source.getName().equals(dest.getName())) {
                migrations.add(new Migration(vm, source, dest));
            }
        }
    }
}
<file_sep>/src/main/java/injector/VMSuspendResumeEvent.java
package injector;

import configuration.XVM;
import org.simgrid.msg.*;
import simulation.SimulatorManager;
import trace.Trace;

public class VMSuspendResumeEvent implements InjectorEvent{
    private long id ;
    private double time;
    private XVM vm;
    private boolean state; // suspend = 0 ; resume = 1

    public VMSuspendResumeEvent(long id, double time, XVM vm, boolean state) {
        this.id = id;
        this.time = time;
        this.vm = vm;
        this.state = state ;

    }

    public long getId(){
        return this.id;
    }
    public double getTime() {
        return this.time;
    }

    public XVM getVM(){
        return this.vm;
    }

    public void play(){
            if (this.state) {
                SimulatorManager.resumeVM(vm.getName(), vm.getLocation().getName());

                Trace.hostVariableAdd(SimulatorManager.getInjectorNodeName(), "NB_VM_TRUE", 1);

            } else {

                SimulatorManager.suspendVM(vm.getName(), vm.getLocation().getName());
                Trace.hostVariableSub(SimulatorManager.getInjectorNodeName(), "NB_VM_TRUE", 1);
            }
    }

    public String toString(){
        return this.getTime() + "/" + this.getVM().getName() + "/" + this.state;
    }

    public boolean getState() {
        return state;
    }
}
<file_sep>/README.md
# VMPlaceS

[![Build Status](https://travis-ci.org/BeyondTheClouds/VMPlaceS.svg?branch=master)](https://travis-ci.org/BeyondTheClouds/VMPlaceS)

This repository contains the source of a dedicated framework to evaluate and compare VM placement algorithms.

For more details, a deeper scientific description of the project can be found [here](http://beyondtheclouds.github.io/VMPlaceS).

## Requirements
* sbt
* java 8 : **openjdk-8**
* python
* r language (optional: visualisation)

## Installation

### 1- Simgrid

#### 1.1- Get Simgrid

```
git clone git://scm.gforge.inria.fr/simgrid/simgrid.git
```

#### 1.2- Compile and install Simgrid
In the simgrid folder, run the following:

```
cmake -Denable_tracing=ON -Denable_documentation=OFF -Denable_java=ON -Denable_smpi=OFF .
```
and then

```
make 
```
please note that you can compile the src code faster by using -j argument of make command (man make for further information)

```
make install
```
file named **simgrid.jar**, containing java bindings to simgrid should be located in the simgrid folder:


```
jonathan@artoo ~/simgrid (master)> ls -lh *.jar
-rw-r--r--  1 jonathan  staff    43K Nov  4 17:28 simgrid.jar
```

This file will be used during step **2.2**.

### 2- SBT

#### 2.1- Installation of sbt:

Please follow the instructions corresponding to your operating system [here](http://www.scala-sbt.org/release/tutorial/Setup.html).

#### 2.2- Installation of dependencies

Inside the project source folder, run the following:

```
$ sbt update
```

and then copy the **simgrid.jar** from **step 1.2** in the lib folder

### 3- Running the program 

You can decide which algorithm you want to test (see [here](http://github.com/BeyondTheClouds/VMPlaceS/blob/master/ALGORITHMS.md)).

#### 3.1- IntelliJ

##### 3.1.1- Make the project compatible with IntelliJ

Inside the project source folder, run the following:

```
$ sbt gen-idea
```

and open the folder in intelliJ: a fully configured project has been generated.

##### 3.1.2- Set the configuration

Click on **Run > Edit configurations...** and then the **plus (+)** button in the top left corner. Choose **Application**.

Name it as you wish, for instance _VMPlaceS_, and set the options:

Option Type             | Value
------------------------|-------------
Main class              | simulation.Main
VM_OPTIONS              | -Xmx4G -d64 -Dlogback.configurationFile=config/logback.xml
PROGRAM_ARGUMENTS       | ./config/cluster_platform.xml ./config/generated_deploy.xml  --cfg=cpu/optim:Full --cfg=tracing:1  --cfg=tracing/filename:simu.trace --cfg=tracing/platform:1
Use classpath of module | VMPlaceS

##### 3.1.3- Run the program

Click **Run > Run 'VMPlaceS'**.

#### 3.2- Command line

##### 3.2.1- Set the environment variables

Environment var    | Value
-------------------|-------------
VM_OPTIONS         | -Xmx4G -d64 -Dlogback.configurationFile=config/logback.xml
PROGRAM_ARGUMENTS  | ./config/cluster_platform.xml ./config/generated_deploy.xml  --cfg=cpu/optim:Full --cfg=tracing:1  --cfg=tracing/filename:simu.trace --cfg=tracing/platform:1

##### 3.2.2- Create the jar

Inside the project source folder, run the following command:

```
sbt assembly
```

it results in the creation of a **fat-jar** named **simulation.jar** in the target folder:

```
jonathan@artoo ~/D/w/VMPlaceS (master)> ls -lh target/*.jar
-rw-r--r--  1 jonathan  staff    12M Dec 18 14:21 target/simulation.jar
```

This jar contains all dependencies and can be run with the java command. Please not that the jar must be located in a folder that contains the **config** folder.

##### 3.2.3- Run the program

Thus it is possible to run the jar with the following command:

```
java -jar $VM_OPTIONS simulation.Main $PROGRAM_ARGUMENTS
```

### 4- Running experiments on grid'5000

We developed some scripts to ease the conduction of experiments on grid'5000. These scripts are located on the Rennes site, in the folder /home/jpastor.

Further documentation will arrive later: in case you plan to use it now, do not hesitate to contact us!

### 5- Running energy comparison of centralized algorithms

Run all the algorithms sequentially, turning off/not turning off the unused hosts:
```
$ rm -f energy.dat && sbt assembly && ./run_all.sh
```

Make the plots:
```
$ visu/energy_plot.py run_all.log energy.dat
```
<file_sep>/src/main/java/simulation/SimulatorManager.java
/**
 * Copyright 2012-2013-2014. The SimGrid Team. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the license (GNU LGPL) which comes with this package.
 *
 * This class aims at controlling the interactions between the different components of the injector simulator.
 * It is mainly composed of static methods. Although it is rather ugly, this is the direct way to make a kind of
 * singleton ;)
 *
 * @author <EMAIL>
 * @contributor <EMAIL>
 */

package simulation;

import configuration.*;
import org.simgrid.msg.Host;
import org.simgrid.msg.HostNotFoundException;
import org.simgrid.msg.Msg;
import org.simgrid.msg.MsgException;
import scheduling.Scheduler;
import scheduling.hierarchical.snooze.LocalController;
import scheduling.hierarchical.snooze.Logger;
import trace.Trace;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: alebre
 * Date: 14/01/14
 * Time: 10:49
 * To change this template use File | Settings | File Templates.
 */
public class SimulatorManager {
    public static int iSuspend = 0;
    public static int iResume = 0;

    /**
     * Stupid variable to monitor the duration of the simulation
     */
    private static double beginTimeOfSimulation = -1;
    /**
     * Stupid variable to monitor the duration of the simulation
     */
    private static double endTimeOfSimulation = -1;

    /**
     * The list of XVMs that are considered as off (i.e. the hosting machine is off)
     * @see configuration.XVM
     */
    private static HashMap<String,XVM> sgVMsOff = null;

    /**
     * The list of XVMs that run
     * @see configuration.XVM
     */
    private static HashMap<String,XVM> sgVMsOn = null;

    /**
     * The list of XVMs that should be suspend (right now, it is impossible to suspend VMs that are currently migrated)
     * This collection is used to suspend VMs after the completion of the migration process.
     * @see configuration.XVM
     */
    public static HashMap<String,XVM> sgVMsToSuspend = null;

    /**
     * The list of XHosts that are off
     * @see configuration.XHost
     */
    private static HashMap<String,XHost> sgHostsOff= null;
    /**
     * The list of Xhosts  that are running
     */
    private static HashMap<String,XHost> sgHostsOn= null;

    /**
     * The list of all XHosts
     * @see configuration.XHost
     */
    private static HashMap<String,XHost> sgHostingHosts= null;
    /**
     * The list of Xhosts  that are running
     */
    private static HashMap<String, XHost> sgServiceHosts= null;
    /**
     * Just a stupid sorted table to have a reference toward each host and vm
     * Used by the injector when generating the different event queues.
     */
    private static XHost[] xhosts = null;
    private static XVM[] xvms = null;
    /**
     * Average CPU demand of the infrastructure (just a hack to avoid to compute the CPUDemand each time (computing the CPU demand is O(n)
     */
    // TODO Adrien the currentCPUDemand is currently not correctly assigned (this should be done in the update function)
    private static double currentCPUDemand = 0;

    /**
     * The previous energy consumption
     */
    private static Map<XHost, Double> lastEnergy = new HashMap<>();

    /**
     * Reference toward the scheduler
     */
    private static boolean isSchedulerActive;


    public static boolean isSchedulerActive() {
        return isSchedulerActive;
    }

    public static void setSchedulerActive(boolean val) {
        isSchedulerActive=val;
    }

    /**
     * Set the scheduler
     */

    /**
     * When the injection is complete, we turn the endOfInjection boolean to true and kill the running daemon inside each VM
     */
    public static void setEndOfInjection() {
        endTimeOfSimulation = System.currentTimeMillis();
    }

    public static void finalizeSimulation(){
        Msg.info(String.format("Hosts up: %d/%d", sgHostsOn.size(), getSGHosts().size()));
        Msg.info(String.format("VMs up: %d/%d", sgVMsOn.size(), getSGVMs().size()));

        for (XHost host : SimulatorManager.getSGHosts()) {
            Msg.info(host.getName() + " has been turned off "+host.getTurnOffNb()+" times and violated "+host.getNbOfViolations());
        }

        // Kill all VMs daemons in order to finalize the simulation correctly
        for (XVM vm : SimulatorManager.getSGVMs()) {
            Msg.info(vm.getName() + " load changes: "+vm.getNbOfLoadChanges() + "/ migrated: "+vm.getNbOfMigrations());
            if(vm.isRunning()) {
                Msg.info("VM is running");
                Msg.info("VM is migrating: " + vm.isMigrating());
                Msg.info("Daemon is suspended: " + vm.getDaemon().isSuspended());
                vm.getDaemon().kill();
            }
            else {
                Msg.info("VM is suspended");
            }
        }
        Msg.info("Duration of the simulation in ms: "+(endTimeOfSimulation - beginTimeOfSimulation));
        Msg.info(Daemon.n_daemon + " daemons are still running");

    }

    /**
     * @return whether the injection is completed or not
     */
    public static boolean isEndOfInjection(){
        return (endTimeOfSimulation != -1);
    }


    /**
     * @return the collection of XVMs: all VMs, the running and the ones that are considered as dead
     * (i.e. hosted on hosts that have been turned off)
     */
    public static Collection<XVM> getSGVMs(){
        LinkedList<XVM> tmp = new LinkedList<>(sgVMsOn.values());
        tmp.addAll(sgVMsOff.values());
        return tmp;
    }

    /**
     * @return the collection of running XVMs
     */
    public static Collection<XVM> getSGVMsOn(){
        return sgVMsOn.values();
    }

    /**
     * @return the collection of the XVMs considered as dead
     */
    public static Collection<XVM> getSGVMsOff(){
        return sgVMsOff.values();
    }


    /**
     * @return the collection of XHosts (i.e. the hosts that composed the infrastructure).
     * Please note that the returned collection is not sorted. If you need a sorted structure, you should call getSGHostsToArray() that returns an simple array
     */
    public static Collection<XHost> getSGHosts(){
        LinkedList<XHost> tmp = new LinkedList<XHost>(sgHostingHosts.values());
        tmp.addAll(sgServiceHosts.values());

        return tmp;
    }

    /**
     * @return the collection of XHosts (i.e. the hosts that composed the infrastructure).
     * Please note that the returned collection is not sorted. If you need a sorted structure, you should call getSGHosts() that returns an simple array
     */
    public static XHost[] getSGHostsToArray(){
        return xhosts;
    }

    public static XVM[] getSGVMsToArray() {
        return xvms;
    }

    /**
     * @return the collection of XHosts that have been declared as hosting nodes (i.e. that can host VMs)
     * Please note that all HostingHosts are returned (without making any distinctions between on and off hosts)
     */
    public static Collection<XHost> getSGHostingHosts(){
        return sgHostingHosts.values();
    }

    /**
     * @return the collection of XHosts that have been declared as hosting nodes (i.e. that can host VMs) and that are turned on.
     */
    public static Collection<XHost> getSGTurnOnHostingHosts() {
        LinkedList<XHost> tmp = new LinkedList<XHost>();
        for (XHost h: sgHostingHosts.values())
            if (!h.isOff())
                tmp.add(h);

        return tmp;
    }

    public static Collection<XHost> getSGTurnOffHostingHosts() {
        LinkedList<XHost> tmp = new LinkedList<XHost>();
        for(XHost h: sgHostingHosts.values())
            if(h.isOff())
                tmp.add(h);

        return tmp;
    }

    /**
     * @return the collection of XHosts that have been declared as services nodes (i.e. that cannot host VMs)
     */
    public static Collection<XHost> getSGServiceHosts(){
        return sgServiceHosts.values();
    }


    /**
     * @return the name of the service node (generally node0, if you do not change the first part of the main regarding the generation
     * of the deployment file).
     * If you change it, please note that you should then update the getInjectorNodeName code.
     */
    public static String getInjectorNodeName() {
        return "node"+(SimulatorProperties.getNbOfHostingNodes()+SimulatorProperties.getNbOfServiceNodes());
    }

    /**
     * For each MSG host (but the service node), the function creates an associated XHost.
     * As a reminder, the XHost class extends the Host one by aggregation.
     * At the end, all created hosts have been inserted into the sgHosts collection (see getSGHostingHosts function)
     * @param nbOfHostingHosts the number of hosts that will be used to host VMs
     * @param nbOfServiceHosts the number of hosts that will be used to host services
     */
    public static void initHosts(int nbOfHostingHosts, int nbOfServiceHosts){
        // Since SG does not make any distinction between Host and Virtual Host (VMs and Hosts belong to the Host SG table)
        // we should retrieve first the real host in a separated table
        // Please remind that node0 does not host VMs (it is a service node) and hence, it is managed separately (getInjectorNodeName())
        sgHostsOn = new HashMap<String,XHost>();
        sgHostsOff = new HashMap<String,XHost>();
        sgHostingHosts = new HashMap<String,XHost>();
        sgServiceHosts = new HashMap<String,XHost>();
        xhosts = new XHost[nbOfHostingHosts+nbOfServiceHosts];

        XHost xtmp;

        // Hosting hosts
        for(int i = 0 ; i < nbOfHostingHosts ; i ++){
            try {
                Host tmp = Host.getByName("node" + i);
                // The SimulatorProperties.getCPUCapacity returns the value indicated by nodes.cpucapacity in the simulator.properties file
                xtmp = new XHost (tmp, SimulatorProperties.getMemoryTotal(), SimulatorProperties.getNbOfCPUs(), SimulatorProperties.getCPUCapacity(), SimulatorProperties.getNetCapacity(), "127.0.0.1");
                xtmp.turnOn();
                sgHostsOn.put("node"+i, xtmp);
                sgHostingHosts.put("node" + i, xtmp);
                xhosts[i]=xtmp;
            } catch (HostNotFoundException e) {
                e.printStackTrace();
            }
        }

        //Service hosts
        for(int i = nbOfHostingHosts ; i < nbOfHostingHosts+nbOfServiceHosts ; i ++){
            try {
                Host tmp = Host.getByName("node" + i);
                // The SimulatorProperties.getCPUCapacity returns the value indicated by nodes.cpucapacity in the simulator.properties file
                xtmp = new XHost (tmp, SimulatorProperties.getMemoryTotal(), SimulatorProperties.getNbOfCPUs(), SimulatorProperties.getCPUCapacity(), SimulatorProperties.getNetCapacity(), "127.0.0.1");
                xtmp.turnOn();
                sgHostsOn.put("node" + i, xtmp);
                sgServiceHosts.put("node" + i, xtmp);
                xhosts[i]=xtmp;
            } catch (HostNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Create and assign the VMs on the different hosts.
     * For the moment, the initial placement follows a simple round robin strategy
     * The algorithm fill the first host with the n first VMs until it reaches either the memory limit, then it switches to the second host and so on.
     * Note that if the ''balance'' mode is enabled then the initial placement will put the same number of VMs on each node.
     * The function can crash if there are two many VMs for the physical resources.
     * At the end the collection SimulatorManager.getSGVMs() is filled.
     * @param nbOfHostingHosts the number of the hosts composing the infrastructure
     * @param nbOfServiceHosts the number of the hosts composing the infrastructure
     * @param nbOfVMs the number of the VMs to instanciate
     */
    public static void configureHostsAndVMs(int nbOfHostingHosts, int nbOfServiceHosts, int nbOfVMs, boolean balance) {
        int nodeIndex = 0;
        int[] nodeMemCons = new int[nbOfHostingHosts];
        int[] nodeCpuCons = new int[nbOfHostingHosts];
        int vmIndex= 0;
        int nbVMOnNode;
        Random r = new Random(SimulatorProperties.getSeed());
        int nbOfVMClasses = VMClasses.CLASSES.size();
        VMClasses.VMClass vmClass;

        initHosts(nbOfHostingHosts, nbOfServiceHosts);
        sgVMsOn = new HashMap<String,XVM>();
        sgVMsOff = new HashMap<String,XVM>();
        sgVMsToSuspend = new HashMap<String,XVM>();


        xvms = new XVM[nbOfVMs];

        XVM sgVMTmp;

        Iterator<XHost> sgHostsIterator = SimulatorManager.getSGHostingHosts().iterator();

        XHost sgHostTmp = sgHostsIterator.next();
        nodeMemCons[nodeIndex]=0;
        nodeCpuCons[nodeIndex]=0;
        nbVMOnNode =0;

        //Add VMs to each node, preventing memory over provisioning
        while(vmIndex < nbOfVMs){

            // Select the class for the VM
            vmClass = VMClasses.CLASSES.get(r.nextInt(nbOfVMClasses));

            //Check whether we can put this VM on the current node if not get the next one
            //The first condition controls the memory over provisioning issue while the second one enables to switch to
            // the next node if the ''balance'' mode is enabled.
            // If there is no more nodes, then we got an exception and the simulator.properties should be modified.

            double vmsPerNodeRatio = ((double) nbOfVMs)/nbOfHostingHosts;

            try {
                while ((nodeMemCons[nodeIndex] + vmClass.getMemSize() > sgHostTmp.getMemSize()
                        || nodeCpuCons[nodeIndex] + SimulatorProperties.getMeanLoad() > sgHostTmp.getCPUCapacity())
                        || (balance && nbVMOnNode >= vmsPerNodeRatio)) {
                    sgHostTmp = sgHostsIterator.next();
                    nodeMemCons[++nodeIndex] = 0;
                    nodeCpuCons[nodeIndex] = 0;
                    nbVMOnNode = 0;
                }
            } catch(NoSuchElementException ex){
                System.err.println("There is not enough memory on the physical hosts to start all VMs");
                System.err.println(String.format("Number of hosts: %d", nbOfHostingHosts));
                System.err.println(String.format("Number of VMs: %d", nbOfVMs));
                System.err.println(String.format("VM placed: %d", vmIndex));
                System.err.println("(Please fix simulator.properties parameters and you should dive in the SimulatorManager.configureHostsAndVMs() function");
                System.exit(1);
            }

            // Creation of the VM
            sgVMTmp = new XVM(sgHostTmp, "vm-" + vmIndex,
                    vmClass.getNbOfCPUs(), vmClass.getMemSize(), vmClass.getNetBW(), null, -1, vmClass.getMigNetBW(), vmClass.getMemIntensity());
            sgVMsOn.put("vm-"+vmIndex, sgVMTmp);

            xvms[vmIndex] = sgVMTmp;
            vmIndex++;

            Msg.info(String.format("vm: %s, %d, %d, %s",
                    sgVMTmp.getName(),
                    vmClass.getMemSize(),
                    vmClass.getNbOfCPUs(),
                    "NO IPs defined"
            ));
            Msg.info("vm " + sgVMTmp.getName() + " is " + vmClass.getName() + ", dp is " + vmClass.getMemIntensity());

            // Assign the new VM to the current host.
            sgHostTmp.start(sgVMTmp);     // When the VM starts, its getCPUDemand equals 0
            nbVMOnNode ++;
            nodeMemCons[nodeIndex] += sgVMTmp.getMemSize();
            nodeCpuCons[nodeIndex] += SimulatorProperties.getMeanLoad();
        }
    }

    /**
     * write the current configuration in the ''logs/simulatorManager/'' directory
     */
    public static void writeCurrentConfiguration(){
        try {
            File file = new File("logs/simulatorManager/conf-"+ System.currentTimeMillis() + ".txt");
            file.getParentFile().mkdirs();
            BufferedWriter bw = new BufferedWriter(new FileWriter(file));
            for (XHost h: SimulatorManager.getSGHostingHosts()){
                bw.write(h.getName()+":");
                for (XVM vm: h.getRunnings()){
                    bw.write(" "+vm.getName());
                }
                bw.write("\n");
                bw.flush();
            }

            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * Remove all logs from the previous run
     */
    public static void cleanLog(){
        try {
            Runtime.getRuntime().exec("rm -rf ./logs/simulatorManager");
            Runtime.getRuntime().exec("rm -rf ./logs/entropy");
            Runtime.getRuntime().exec("rm -rf ./logs/entropy.log");
            Runtime.getRuntime().exec("rm -rf ./logs/btrplace");
            Runtime.getRuntime().exec("rm -rf ./logs/btrplace.log");
            Runtime.getRuntime().exec("rm -rf ./logs/ffd");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * @return whether the current placement is viable or not (i.e. if every VM gets its expectations).
     * Please note that we are considering only the hosts that are running.
     * Complexity O(n)
     */
    public static boolean isViable() {
        for (XHost h: sgHostsOn.values()){
            if(!h.isViable())
                return false;
        }
        return true;
    }

    /**
     * @return the average expected load at a particular moment (i.e. average load of each node)
     * Please note that we are considering only the hosts hosting VMs and that are up.
     */
    public static double computeCPUDemand() {

        double globalCpuDemand = 0.0;
        int globalCpuCapacity = 0;

        for(XHost h: sgHostingHosts.values()){
            if(h.isOn()) {
                globalCpuDemand += h.getCPUDemand();
                globalCpuCapacity += h.getCPUCapacity();
            }
        }
        return 100 * globalCpuDemand / globalCpuCapacity;
    }

    public static double getCPUDemand(){
        // TODO Adrien, maintain the current CPU Demand in order to avoid O(n)
        //return currentCPUDemand;
        return computeCPUDemand();
    }
    /**
     * @return the number of hosts that are active (i.e. that host at least one VM)
     * Complexity O(n)
     */
    public static int getNbOfUsedHosts() {
        int i=0;
        for (XHost h: sgHostsOn.values()){
            if(h.getNbVMs()>0)
                i++;
        }
        return i;
    }

    /**
     * Return the XHost entitled ''name'', if not return null (please note that the search is performed by considering
     * all hosts (i.e. On/Off and Hosting/Service ones)
     * @param name the name of the host requested
     * @return the corresponding XHost instance (null if there is no corresponding host in the sgHosts collection)
     */
    public static XHost getXHostByName(String name) {
        XHost tmp = sgHostingHosts.get(name);
        if (tmp == null)
            tmp = sgServiceHosts.get(name);
        return tmp;
    }

    /**
     * Return the XVM entitled ''name'', if not return null please note that the search is performed by considering
     * all VMs (i.e. event the off ones)
     * @param name the name of the vm requested
     * @return the corresponding XVM instance (null if there is no corresponding vm in the sgVMs collection)
     */
    public static XVM getXVMByName(String name) {
        XVM tmp = sgVMsOn.get(name);
        if (tmp == null)
            tmp = sgVMsOff.get(name);
        if(tmp == null)
            tmp = sgVMsToSuspend.get(name);


        if(tmp == null) {
            Msg.error("No ");
        }
        return tmp;
    }

    /**
     * Change the load of a VM.
     * Please note that we do not detect violations on off hosts (i.e. if the nodes that hosts the VM is off, we change
     * the load of the vm for consistency reasons but we do not consider the violation that may state from this change).
     * @param sgVM the VM that should be updated
     * @param load the new expected load
     */
    public static void updateVM(XVM sgVM, double load) {

        if(sgVM.isRunning()) {

            XHost tmpHost = sgVM.getLocation();
            boolean previouslyViable = tmpHost.isViable();

            // A simple hack to avoid computing on-the-fly the CPUDemand of each host
            double vmPreviousLoad = sgVM.getCPUDemand();
            double hostPreviousLoad = tmpHost.getCPUDemand();
            // Msg.info("Previous Load was" + hostPreviousLoad);

            tmpHost.setCPUDemand(hostPreviousLoad - vmPreviousLoad + load);
            //  Msg.info("New Load is "+ tmpHost.getCPUDemand());

            sgVM.setLoad(load);

            // If the node is off, we change the VM load but we do not consider it for possible violation and do not update
            // neither the global load of the node nor the global load of the cluster.
            // Violations are detected only on running node
            if (!tmpHost.isOff()) {


                //    Msg.info("Current getCPUDemand "+SimulatorManager.getCPUDemand()+"\n");


                if (previouslyViable && (!tmpHost.isViable())) {
                    Msg.info("STARTING VIOLATION ON " + tmpHost.getName() + "\n");
                    tmpHost.incViolation();
                    Trace.hostSetState(tmpHost.getName(), "PM", "violation");

                } else if ((!previouslyViable) && (tmpHost.isViable())) {
                    Msg.info("ENDING VIOLATION ON " + tmpHost.getName() + "\n");
                    Trace.hostSetState(tmpHost.getName(), "PM", "normal");
                }
                // else Do nothing the state does not change.

                // Update getCPUDemand of the host
                Trace.hostVariableSet(tmpHost.getName(), "LOAD", tmpHost.getCPUDemand());

                // TODO this is costly O(HOST_NB) - SHOULD BE FIXED
                //Update global getCPUDemand
                Trace.hostVariableSet(SimulatorManager.getInjectorNodeName(), "LOAD", SimulatorManager.getCPUDemand());

            }

            double energy = tmpHost.getSGHost().getConsumedEnergy();
            if (lastEnergy.containsKey(tmpHost))
                energy -= lastEnergy.get(tmpHost);

            Trace.hostVariableSet(tmpHost.getName(), "ENERGY", energy);
            lastEnergy.put(tmpHost, tmpHost.getSGHost().getConsumedEnergy());
        } else { // VM is suspended: just update the load for consistency reason (i.e. when the VM will be resumed, we should assign the expected load
            sgVM.setLoad(load);
        }
    }

    public static boolean willItBeViableWith(XVM sgVM, int load){
        XHost tmpHost = sgVM.getLocation();
        double hostPreviousLoad = tmpHost.getCPUDemand();
        double vmPreviousLoad = sgVM.getCPUDemand();
        return ((hostPreviousLoad-vmPreviousLoad+load) <= tmpHost.getCPUCapacity());
    }

    /**
     * Turn on the XHost host
     * @param host the host to turn on
     */
    public static void turnOn(XHost host) {
        String name = host.getName();
        if(host.isOff()) {
            Msg.info("Turn on node "+name);
            host.turnOn();
            Trace.hostVariableAdd(host.getName(), "NB_ON", 1);
            sgHostsOff.remove(name);
            sgHostsOn.put(name, host);

            // If your turn on an hosting node, then update the LOAD
            if(sgHostingHosts.containsKey(name)) {

                for (XVM vm: host.getRunnings()){
                    Msg.info("TURNING NODE "+name+"ON - ADD VM "+vm.getName());
                    sgVMsOff.remove(vm.getName());
                    sgVMsOn.put(vm.getName(), vm);
                }

                // Update getCPUDemand of the host
                Trace.hostVariableSet(name, "LOAD", host.getCPUDemand());

                // TODO test whether the node is violated or not (this can occur)

                //Update global getCPUDemand
                Trace.hostVariableSet(SimulatorManager.getInjectorNodeName(), "LOAD", SimulatorManager.getCPUDemand());
            }
            if (SimulatorProperties.getAlgo().equals("hierarchical")) {
                int hostNo = Integer.parseInt(name.replaceAll("\\D", ""));
                if (hostNo < SimulatorProperties.getNbOfHostingNodes()) {
                    try {
                        String[] lcArgs = new String[]{name, "dynLocalController-" + hostNo};
                        LocalController lc =
                                new LocalController(host.getSGHost(), "dynLocalController-" + hostNo, lcArgs);
                        lc.start();
                        Logger.info("[SimulatorManager.turnOn] Dyn. LC added: " + lcArgs[1]);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        } else{
            Msg.info("Weird... you are asking to turn on a host that is already on !");
        }
    }

    /**
     * Turn off the XHost host
     * @param host the host to turn off
     */
    public static void turnOff(XHost host) {

        if(host.isOnGoingMigration()){
            Msg.info("WARNING = WE ARE NOT GOING TO TURN OFF HOST "+host.getName()+" BECAUSE THERE IS AN ON-GOING MIGRATION");
            return;
        }
        if(!host.isOff()) {
            Msg.info("Turn off "+host.getName());

            // if this is an hosting host, then you should deal with VM aspects
            if(sgHostingHosts.containsKey(host.getName())) {
                // First remove all VMs hosted on the node from the global collection
                // The VMs are still referenced on the node
                for (XVM vm : host.getRunnings()) {
                    Msg.info("TURNING NODE "+host.getName()+"OFF - REMOVE VM "+vm.getName());
                    sgVMsOn.remove(vm.getName());
                    sgVMsOff.put(vm.getName(), vm);
                }
                // Update getCPUDemand of the host
                Trace.hostVariableSet(host.getName(), "LOAD", 0);

                // TODO if the node is violated then it is no more violated
                //Update global getCPUDemand
                Trace.hostVariableSet(SimulatorManager.getInjectorNodeName(),  "LOAD", SimulatorManager.getCPUDemand());

            }


            int previousCount = org.simgrid.msg.Process.getCount();
            // Turn the node off
            host.turnOff();

            // Finally, remove the node from the collection of running host and add it to the collection of off ones
            sgHostsOn.remove(host.getName());
            sgHostsOff.put(host.getName(), host);

            //  Msg.info("Nb of remaining processes on " + host.getName() + ": " + (previousCount - org.simgrid.msg.Process.getCount()));
            Trace.hostVariableAdd(host.getName(), "NB_OFF", 1);


        }
        else{
            Msg.info("Weird... you are asking to turn off a host that is already off !");
        }
    }


    private static int getProcessCount(XHost host) {
        Msg.info ("TODO");
        System.exit(-1);
        return -1;

    }


    /**
     * Stupid variable to monitor the duration of the simulation
     */
    public static void setBeginTimeOfSimulation(double beginTimeOfSimulation) {
        SimulatorManager.beginTimeOfSimulation = beginTimeOfSimulation;
    }

    /**
     * Stupid variable to monitor the duration of the simulation
     */
    public static void setEndTimeOfSimulation(double endTimeOfSimulation) {
        SimulatorManager.endTimeOfSimulation = endTimeOfSimulation;
    }

    /**
     * Stupid variable to monitor the duration of the simulation
     */
    public static double getSimulationDuration() {
        return (endTimeOfSimulation != -1) ?  endTimeOfSimulation - beginTimeOfSimulation : endTimeOfSimulation;
    }

    public static void writeEnergy(String logPath) {
        Double energy = 0D;
        for(XHost h: SimulatorManager.getSGHosts())
            energy += h.getSGHost().getConsumedEnergy();

        try {
            String message = null;
            if(SimulatorProperties.getAlgo().equals("centralized")) {
                String implem = SimulatorProperties.getImplementation();
                implem = implem.substring(implem.lastIndexOf('.') + 1, implem.length());
                message = String.format(Locale.US, "%d %s %s %b %f\n", SimulatorProperties.getNbOfHostingNodes(), SimulatorProperties.getAlgo(), implem, SimulatorProperties.getHostsTurnoff(), energy);
            }
            else
                message = String.format(Locale.US, "%d %s %b %f\n", SimulatorProperties.getNbOfHostingNodes(), SimulatorProperties.getAlgo(), SimulatorProperties.getHostsTurnoff(), energy);

            Files.write(Paths.get(logPath), message.getBytes(), StandardOpenOption.CREATE, StandardOpenOption.APPEND);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }



    public static boolean suspendVM(String vmName, String hostName){

        boolean correctlyCompleted= true;
        Msg.info("Suspending VM " + vmName + " on " + hostName);

        if (vmName != null) {
            XVM vm =  SimulatorManager.getXVMByName(vmName);
            XHost host = SimulatorManager.getXHostByName(hostName);

            if (vm != null) {
                double timeStartingSuspension = Msg.getClock();
                Trace.hostPushState(vmName, "SERVICE", "suspend", String.format("{\"vm_name\": \"%s\", \"on\": \"%s\"}", vmName, hostName));
                boolean previouslyViable = host.isViable();
                // 0 if success, 1 should be postponed, -1 if failure, -2 if already suspended
                int res = host.suspendVM(vm);
                Trace.hostPopState(vmName, "SERVICE", String.format("{\"vm_name\": \"%s\", \"state\": %d}", vmName, res));
                double suspensionDuration = Msg.getClock() - timeStartingSuspension;

                switch (res) {
                    case 0:
//                        Msg.info("End of suspension operation of VM " + vmName + " on " + hostName);

                        if (!previouslyViable && host.isViable()){
                            Msg.info("END OF VIOLATION ON " + host.getName() + "\n");
                            Trace.hostSetState(host.getName(), "PM", "normal");
                        }

                        SimulatorManager.iSuspend++;

                        /* Export that the suspension has finished */
                        Trace.hostSetState(vmName, "suspension", "finished", String.format(Locale.US, "{\"vm_name\": \"%s\", \"on\": \"%s\", \"duration\": %f}", vmName, hostName, suspensionDuration));
                        Trace.hostPopState(vmName, "suspension");

                        if (sgVMsOn.remove(vm.getName()) == null && sgVMsToSuspend.remove(vm.getName())== null){
                            System.err.println("You are trying to suspend a VM which is not on... weird");
                            System.exit(-1);
                        }
                        sgVMsOff.put(vm.getName(), vm);
                        Trace.hostVariableSub(SimulatorManager.getInjectorNodeName(), "NB_VM", 1);
                        break;

                    case 1:
                        Msg.info("Suspension of VM has been postponed" + vmName + " on " + hostName);

                        Trace.hostSetState(vmName, "suspension", "postponed", String.format(Locale.US, "{\"vm_name\": \"%s\", \"on\": \"%s\", \"duration\": %f}", vmName, hostName, suspensionDuration));
                        Trace.hostPopState(vmName, "suspension");

                        sgVMsOn.remove(vm.getName());
                        sgVMsToSuspend.put(vm.getName(), vm);
                        break;

                    default:
                        correctlyCompleted = false;
                        System.err.println("Unexpected state from XHost.suspend()");
                        System.exit(-1);
                }
            }

        } else {
            System.err.println("You are trying to suspend a non-existing VM");
            System.exit(-1);
        }
        return correctlyCompleted;
    }

    public static boolean resumeVM(String vmName, String hostName){

        boolean correctlyCompleted = true;

        Msg.info("Resuming VM " + vmName + " on " + hostName);

        if (vmName != null) {
            XVM vm =  SimulatorManager.getXVMByName(vmName);
            XHost host = SimulatorManager.getXHostByName(hostName);

            if (vm != null) {
                double timeStartingSuspension = Msg.getClock();
                Trace.hostPushState(vmName, "SERVICE", "resume", String.format("{\"vm_name\": \"%s\", \"on\": \"%s\"}", vmName, hostName));
                boolean previouslyViable = host.isViable();
                // 0 if success, -1 if failure, 1 if already running
                int res = host.resumeVM(vm);
                Msg.info(vm.getName() + " resume returned " + res);
                Trace.hostPopState(vmName, "SERVICE", String.format("{\"vm_name\": \"%s\", \"state\": %d}", vmName, res));
                double suspensionDuration = Msg.getClock() - timeStartingSuspension;

                switch (res) {
                    case 0:
//                        Msg.info("End of operation resume of VM " + vmName + " on " + hostName);

                        if (sgVMsOff.remove(vmName) == null)  { // If the VM is not marked off, there is an issue
                            System.err.println("Unexpected state from XHost.resume()");
                            System.exit(-1);
                        }
                        sgVMsOn.put(vm.getName(), vm);
                        Trace.hostVariableAdd(SimulatorManager.getInjectorNodeName(), "NB_VM", 1);
                        SimulatorManager.iResume++;

                        if ((previouslyViable) && (!host.isViable())) {
                            Msg.info("STARTING VIOLATION ON " + host.getName() + "\n");
                            Trace.hostSetState(host.getName(), "PM", "violation");
                        }

                        Trace.hostSetState(vmName, "resume", "finished", String.format(Locale.US, "{\"vm_name\": \"%s\", \"on\": \"%s\", \"duration\": %f}", vmName, hostName, suspensionDuration));
                        Trace.hostPopState(vmName, "resume");

                        break;

                    case 1:
                        if(sgVMsToSuspend.remove(vmName) == null) { // If the VM is not marked off, there is an issue
                            System.err.println("Unexpected state from XHost.resume()");
                            System.exit(-1);
                        }
                        sgVMsOn.put(vm.getName(), vm);
                        //SimulatorManager.iResume++;

                        /* Export that the suspension has finished */
                        Trace.hostSetState(vmName, "resume", "cancelled", String.format(Locale.US, "{\"vm_name\": \"%s\", \"on\": \"%s\", \"duration\": %f}", vmName, hostName, suspensionDuration));
                        Trace.hostPopState(vmName, "resume");


                        break;

                    default:
                        correctlyCompleted = false;
                        System.err.println("Unexpected state from XHost.resume()");
                        System.exit(-1);
                }
            }

        } else {
            System.err.println("You are trying to resume a non-existing VM");
            System.exit(-1);
        }
        return correctlyCompleted;
    }

    /**
     * Migrate a VM
     * @param vmName
     * @param sourceName
     * @param destName
     * @return true migration has been correctly performed, false migration cannot complete.
     */


    public static boolean migrateVM(String vmName, String sourceName, String destName) {

        boolean completionOk = true;
        double timeStartingMigration = Msg.getClock();
        Trace.hostPushState(vmName, "SERVICE", "migrate", String.format("{\"vm_name\": \"%s\", \"from\": \"%s\", \"to\": \"%s\"}", vmName, sourceName, destName));

        XHost sourceHost = SimulatorManager.getXHostByName(sourceName);
        XHost destHost = SimulatorManager.getXHostByName(destName);

        int res = sourceHost.migrate(vmName, destHost);
        // TODO, we should record the res of the migration operation in order to count for instance how many times a migration crashes ?
        // To this aim, please extend the hostPopState API to add meta data information

        Trace.hostPopState(vmName, "SERVICE", String.format("{\"vm_name\": \"%s\", \"state\": %d}", vmName, res));
        double migrationDuration = Msg.getClock() - timeStartingMigration;

        if (res == 0) {
            Msg.info("End of migration of VM " + vmName + " from " + sourceName + " to " + destName);

            if (!destHost.isViable()) {
                Msg.info("ARTIFICIAL VIOLATION ON " + destHost.getName() + "\n");
                // If Trace.hostGetState(destHost.getName(), "PM").equals("normal")
                Trace.hostSetState(destHost.getName(), "PM", "violation-out");
            }
            if (sourceHost.isViable()) {
                Msg.info("END OF VIOLATION ON " + sourceHost.getName() + "\n");
                Trace.hostSetState(sourceHost.getName(), "PM", "normal");
            }

                                    /* Export that the migration has finished */
            Trace.hostSetState(vmName, "migration", "finished", String.format(Locale.US, "{\"vm_name\": \"%s\", \"from\": \"%s\", \"to\": \"%s\", \"duration\": %f}", vmName, sourceName, destName, migrationDuration));
            Trace.hostPopState(vmName, "migration");

            // Patch to handle postponed supsend that may have been requested during the migration.
            XVM suspendedVm = SimulatorManager.sgVMsToSuspend.remove(vmName);
            if (suspendedVm != null) { // The VM has been marked to be suspended, so do it
                Msg.info("The VM " + vmName + "has been marked to be suspended after migration");
                SimulatorManager.sgVMsOn.put(vmName, suspendedVm);
                SimulatorManager.suspendVM(vmName, destName);
            }

        } else {

            Trace.hostSetState(vmName, "migration", "failed", String.format(Locale.US, "{\"vm_name\": \"%s\", \"from\": \"%s\", \"to\": \"%s\", \"duration\": %f}", vmName, sourceName, destName, migrationDuration));
            Trace.hostPopState(vmName, "migration");

            Msg.info("Something was wrong during the migration of  " + vmName + " from " + sourceName + " to " + destName);
            Msg.info("Reconfiguration plan cannot be completely applied so abort it");
            completionOk = false;
        }
        return completionOk;
    }

}
<file_sep>/src/main/java/simulation/Main.java
/**
 * Copyright 2012-2013-2014. The SimGrid Team. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the license (GNU LGPL) which comes with this package.
 *
 * This file is the launcher on the Simgrid VM injector
 * The main is composed of three part:
 * 1./ Generate the deployment file according to the number of nodes and the algorithm you want to evaluate
 * 2./ Configure, instanciate and assign each VM on the different PMs
 * 3./ Launch the injector and the other simgrid processes in order to run the simulation.
 *
 * Please note that all parameters of the simulation are given in the ''simulator.properties'' file available
 * in the ''config'' directory
 *
 * @author: <EMAIL>
 */

package simulation;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.util.StatusPrinter;
import configuration.SimulatorProperties;
import configuration.XHost;
import org.simgrid.msg.Msg;
import org.simgrid.msg.Process;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Date;

import scheduling.hierarchical.snooze.AUX;
import trace.Trace;


public class Main {

    /**
     * The Simulator launcher
     *
     * @param args
     */
    public static void main(String[] args) {

        // Historical fix to get the internal logs of Entropy correctly
        // assume SLF4J is bound to logback in the current environment
        LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
        // print logback's internal status
        StatusPrinter.print(lc);

        // Save the begining time
        SimulatorManager.setBeginTimeOfSimulation(System.currentTimeMillis());

        // Automatically generate deployment file that is mandatory for launching the simgrid simulation.
        // TODO - implement a more generic way to generate the deployment file
        try {
            String[] cmd = null;
            if (SimulatorProperties.getAlgo().equals("distributed")) {
                Msg.info("Distributed scheduling selected (generating deployment file)");
                cmd = new String[] {"/bin/sh", "-c", "python generate.py " + SimulatorProperties.getAlgo() + " " +
                        SimulatorProperties.getNbOfHostingNodes() + " " +
                        SimulatorProperties.getNbOfCPUs() + " " +
                        SimulatorProperties.getCPUCapacity() + " " +
                        SimulatorProperties.getMemoryTotal() + " 23000 > config/generated_deploy.xml"};
                //"Usage: python generate.py nb_nodes nb_cpu total_cpu_cap ram port >
            } else if (SimulatorProperties.getAlgo().equals("hierarchical")) {
                Msg.info("Hierarchical scheduling selected (generating deployment file for hierarchical approach)");

                //"Usage: python generate.py nb_nodes
                cmd = new String[] {"/bin/sh", "-c", "python generate.py " + SimulatorProperties.getAlgo() + " " + SimulatorProperties.getNbOfHostingNodes() + " " + SimulatorProperties.getNbOfServiceNodes() + " > config/generated_deploy.xml"};
            } else if (SimulatorProperties.getAlgo().equals("example")) {
                Msg.info("Simple scheduling selected (generating deployment file for simple approach)");

                //"Usage: python generate.py nb_nodes
                cmd = new String[] {"/bin/sh", "-c", "python generate.py " + SimulatorProperties.getAlgo() + " " + SimulatorProperties.getNbOfHostingNodes() + " " + SimulatorProperties.getNbOfServiceNodes() + " > config/generated_deploy.xml"};
            } else { //(SimulatorProperties.getAlgo().equals("centralized"))
                Msg.info("Default selected (generating deployment file for centralized approach)");

                //"Usage: python generate.py nb_nodes
                cmd = new String[] {"/bin/sh", "-c", "python generate.py " + SimulatorProperties.getAlgo() + " " + SimulatorProperties.getNbOfHostingNodes() + " > config/generated_deploy.xml"};
            }

            try {
                Runtime.getRuntime().exec(cmd).waitFor();
            } catch (InterruptedException e) {
                // Ignore
            }
        } catch (IOException e) {
            e.printStackTrace();
        }


        // Init. internal values
        Msg.energyInit();
        Msg.init(args);

        /* construct the platform and deploy the application */
        Msg.createEnvironment(args[0]);
        Msg.deployApplication(args[1]);

        /* Create all VM instances and assign them on the PMs */
        /* The initial deployment is based on a round robin fashion */
        System.out.println("Configure simulation" + new Date().toString());
        SimulatorManager.cleanLog();
        // True means round robin placement.
        SimulatorManager.configureHostsAndVMs(SimulatorProperties.getNbOfHostingNodes(), SimulatorProperties.getNbOfServiceNodes(), SimulatorProperties.getNbOfVMs(), true);
        SimulatorManager.writeCurrentConfiguration();

        String algorithmName = SimulatorProperties.getAlgo();
        String algorithmDetails = "{}";
        if (algorithmName.equals("hierarchical")) {
            int lcsRatio = SimulatorProperties.getNbOfHostingNodes() / (SimulatorProperties.getNbOfServiceNodes() -1 );
            algorithmDetails = String.format("{\"assignmentAlgorithm\": \"%s\", \"lcsRatio\": %d}", AUX.assignmentAlg, lcsRatio);
        }

        if(algorithmName.equals("centralized"))
            algorithmName = SimulatorProperties.getImplementation().substring(SimulatorProperties.getImplementation().lastIndexOf('.') + 1);

        Trace.simulationDeclare(algorithmName, SimulatorProperties.getNbOfHostingNodes(), SimulatorProperties.getNbOfServiceNodes(), SimulatorProperties.getNbOfVMs(), algorithmDetails);

        /* Prepare TRACE variables */
        System.out.println("Prepare TRACE module" + new Date().toString());
        // A node can be underloaded
        Trace.hostStateDeclare("PM");
        Trace.hostStateDeclareValue("PM", "underloaded", "0 1 1");
        Trace.hostStateDeclareValue("PM", "normal", "1 1 1");
        Trace.hostStateDeclareValue("PM", "violation", "1 0 0");
        Trace.hostStateDeclareValue("PM", "violation-det", "0 1 0");
        Trace.hostStateDeclareValue("PM", "violation-out", "1 0 0");

        Trace.hostStateDeclare("SERVICE");
        Trace.hostStateDeclareValue("SERVICE", "free", "1 1 1");
        Trace.hostStateDeclareValue("SERVICE", "booked", "0 0 1");
        Trace.hostStateDeclareValue("SERVICE", "compute", "1 0 1");
        Trace.hostStateDeclareValue("SERVICE", "reconfigure", "1 1 0");
        Trace.hostStateDeclareValue("SERVICE", "migrate", "1 0 0");

        Trace.hostVariableDeclare("LOAD");
        Trace.hostVariableDeclare("NB_MC");  // Nb of microcosms (only for DVMS)
        Trace.hostVariableDeclare("NB_MIG"); //Nb of migration
        Trace.hostVariableDeclare("NB_VM"); //To follow number of VMs.
        Trace.hostVariableDeclare("NB_VM_TRUE"); //To follow the true number of VMs.

        Trace.hostVariableDeclare("ENERGY");
        Trace.hostVariableDeclare("NB_OFF"); //Nb of hosts turned off
        Trace.hostVariableDeclare("NB_ON"); //Nb of hosts turned on

        for(XHost host: SimulatorManager.getSGHosts()) {
            Trace.hostVariableSet(host.getName(), "NB_ON", 1);
            Trace.hostVariableSet(host.getName(), "NB_OFF", 0);
        }

        // Turn off the hosts that we don't need
        int nOff = 0;
        if(SimulatorProperties.getHostsTurnoff()) {
            for (XHost h : SimulatorManager.getSGHostingHosts())
                if (h.getRunnings().size() <= 0) {
                    SimulatorManager.turnOff(h);
                    nOff++;
                }
            Msg.info(String.format("Turned off unused %d nodes before starting", nOff));
        }

	    /*  execute the simulation. */
        System.out.println("Launcher: begin Msg.run()" + new Date().toString());
        notify(String.format("Started %s with %d hosts and %d VMs", SimulatorProperties.getImplementation(), SimulatorProperties.getNbOfHostingNodes(), SimulatorProperties.getNbOfVMs()));

        Msg.run();

        System.out.println("Launcher: end of Msg.run()" + new Date().toString());
        Trace.close();
        Msg.info("End of run");

        notify(String.format("End of simulation %s", SimulatorProperties.getImplementation()));

        Process.killAll(-1);
        Msg.info(String.format("There are still %d processes running", Process.getCount()));
    }

    private static void notify(String message) {
        Msg.info(message);
    }
}
