/* * Copyright 2010 Aalto University, ComNet * Released under GPLv3. See LICENSE.txt for details. */ package ui; import interfaces.ConnectionsFromFileInterface; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.Collection; import java.util.LinkedList; import java.util.StringTokenizer; import report.Report; import core.ConnectedWorld; import core.DTNHost; import core.NetworkInterface; import core.Settings; import core.SettingsError; import core.SimClock; import core.SimError; import core.SimScenario; /** * Simple text-based user interface. */ public class ConnectionSimTextUI extends DTNSimUI { private long lastUpdateRt; // real time of last ui update private long startTime; // simulation start time /** How often the UI view is updated (milliseconds) */ public static final long UI_UP_INTERVAL = 60000; protected ConnectedWorld world; private Double newestCachedConnection = 0.00; private int caches = 0; private boolean fileFinshed = false; /** * Starts the simulation. */ @Override public void start() { initConnectionModel(); runSim(); } /** * Initializes the simulator model. */ private void initConnectionModel() { Settings settings = null; try { settings = new Settings(); this.scen = SimScenario.getInstance(); // add reports for (int i=1, n = settings.getInt(NROF_REPORT_S); i<=n; i++){ String reportClass = settings.getSetting(REPORT_S + i); addReport((Report)settings.createObject(REPORT_PAC + reportClass)); } double warmupTime = 0; if (settings.contains(MM_WARMUP_S)) { warmupTime = settings.getDouble(MM_WARMUP_S); if (warmupTime > 0) { SimClock c = SimClock.getInstance(); c.setTime(-warmupTime); } } this.world = (ConnectedWorld) this.scen.getWorld(); } catch (SettingsError se) { System.err.println("Can't start: error in configuration file(s)"); System.err.println(se.getMessage()); System.exit(-1); } catch (SimError er) { System.err.println("Can't start: " + er.getMessage()); System.err.println("Caught at " + er.getStackTrace()[0]); System.exit(-1); } } private void cacheConnections() { int parp = 0; StringTokenizer st; Collection interfaces; // We want to make starting of the simulator faster in connection only mode // check connections only once and store them in memory try { System.out.println(scen.connectionsFile); // Get the object of DataInputStream BufferedReader br = new BufferedReader(new FileReader(scen.connectionsFile), 8192); String strLine; String arr[]; int cacheLimit = 100000; // line limit per cache run int cacheAmounts = 0; int loop = 0; // calculate lines to skip int cachedLines = caches * cacheLimit; // delete old connections for hosts for(DTNHost h : scen.hosts) { interfaces = h.getInterfaces(); for (NetworkInterface in11 : interfaces) { ((ConnectionsFromFileInterface)in11).upConnections.clear(); ((ConnectionsFromFileInterface)in11).downConnections.clear(); } } //Read File Line By Line try { // System.out.println("Creating Connections for " + this.getAddress()); while ((strLine = br.readLine()) != null && cacheAmounts < cacheLimit ) { if(cachedLines > loop) { // already read these lines loop++; } else { cacheAmounts++; // example lines // 86082.00 CONN 552 658 up // 86082.00 CONN 552 658 down // 1) explode the parts st = new StringTokenizer(strLine, " "); arr = new String[st.countTokens()]; //when there are still more tokens, place it in the array: parp = 0; while(st.hasMoreTokens()){ arr[parp] = st.nextToken(); parp++; } newestCachedConnection = Double.valueOf(arr[0]); try { // add connections for the interface in arr[2] interfaces = scen.hosts.get(Integer.parseInt(arr[2])).getInterfaces(); for (NetworkInterface in11 : interfaces) { // if it is then we have a connection // is it up or down? if(arr[4].compareTo("up") == 0) { //System.out.println("Up: " + Integer.parseInt(arr[0]) + " " + arr[3]); if(((ConnectionsFromFileInterface)in11).upConnections.get(Double.valueOf(arr[0])) != null) { ((ConnectionsFromFileInterface)in11).upConnections.get(Double.valueOf(arr[0])).add(arr[3]); } else { ((ConnectionsFromFileInterface)in11).upConnections.put(Double.valueOf(arr[0]), new LinkedList()); ((ConnectionsFromFileInterface)in11).upConnections.get(Double.valueOf(arr[0])).add(arr[3]); } //((ConnectionsFromFileInterface)in11).upConnections.add(new Pair(arr[0], arr[3])); } else if(arr[4].compareTo("down") == 0) { if(((ConnectionsFromFileInterface)in11).downConnections.get(Double.valueOf(arr[0])) != null) { ((ConnectionsFromFileInterface)in11).downConnections.get(Double.valueOf(arr[0])).add(arr[3]); } else { ((ConnectionsFromFileInterface)in11).downConnections.put(Double.valueOf(arr[0]), new LinkedList()); ((ConnectionsFromFileInterface)in11).downConnections.get(Double.valueOf(arr[0])).add(arr[3]); } //((ConnectionsFromFileInterface)in11).downConnections.add(new Pair(arr[0], arr[3])); } } } catch(ArrayIndexOutOfBoundsException e) { System.out.println("ERROR: In the following trace file line:"); for(String punks : arr){ System.out.println(punks); } } } } if(cacheAmounts == 0) this.fileFinshed = true; // System.out.println("Finished Creating Connections for " + this.getAddress()); } catch (NumberFormatException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } //Close the input stream br.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } System.out.println("New Connections cached"); // test out the hosts connections /* for(DTNHost h : scen.hosts) { interfaces = h.getInterfaces(); for (NetworkInterface in11 : interfaces) { System.out.println("New Connections for " + h.getAddress() + " = " + ((ConnectionsFromFileInterface)in11).upConnections.size()); System.out.println("Down Connections for " + h.getAddress() + " = " + ((ConnectionsFromFileInterface)in11).downConnections.size()); } } */ } protected void runSim() { double simTime = SimClock.getTime(); double endTime = scen.getEndTime(); print("Running simulation '" + scen.getName()+"'"); startTime = System.currentTimeMillis(); lastUpdateRt = startTime; while (simTime < endTime && !simCancelled){ try { world.update(); if(!fileFinshed && simTime >= newestCachedConnection) { cacheConnections(); caches++; } } catch (AssertionError e) { e.printStackTrace(); done(); return; } simTime = SimClock.getTime(); this.update(false); } double duration = (System.currentTimeMillis() - startTime)/1000.0; simDone = true; done(); this.update(true); // force final UI update print("Simulation done in " + String.format("%.2f", duration) + "s"); } /** * Updates user interface if the long enough (real)time (update interval) * has passed from the previous update. * @param forced If true, the update is done even if the next update * interval hasn't been reached. */ private void update(boolean forced) { long now = System.currentTimeMillis(); long diff = now - this.lastUpdateRt; double dur = (now - startTime)/1000.0; if (forced || (diff > UI_UP_INTERVAL)) { // simulated seconds/second calc double ssps = ((SimClock.getTime() - lastUpdate)*1000) / diff; print(String.format("%.1f %d: %.2f 1/s", dur, SimClock.getIntTime(),ssps)); this.lastUpdateRt = System.currentTimeMillis(); this.lastUpdate = SimClock.getTime(); } } private void print(String txt) { System.out.println(txt); } }