Renamed devicemanager, flowprogrammer, linkdiscovery and util packages

net.onrc.onos.ofcontroller.devicemanager.* => net.onrc.onos.core.devicemanager.*
net.onrc.onos.ofcontroller.flowprogrammer.* => net.onrc.onos.core.flowprogrammer.*
net.onrc.onos.ofcontroller.linkdiscovery.* => net.onrc.onos.core.linkdiscovery.*
net.onrc.onos.ofcontroller.util.* => net.onrc.onos.core.util.*

Change-Id: Iaa865af552e8fb3a589e73d006569ac79f5a0f08
diff --git a/src/main/java/net/onrc/onos/core/util/PerformanceMonitor.java b/src/main/java/net/onrc/onos/core/util/PerformanceMonitor.java
new file mode 100644
index 0000000..dd5e36f
--- /dev/null
+++ b/src/main/java/net/onrc/onos/core/util/PerformanceMonitor.java
@@ -0,0 +1,292 @@
+package net.onrc.onos.core.util;
+
+import java.util.Map.Entry;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class for collecting performance measurements
+ */
+public class PerformanceMonitor {
+    private final static Logger log = LoggerFactory.getLogger(PerformanceMonitor.class);
+
+    // experiment name -> PerformanceMonitor
+    private static final ConcurrentHashMap<String,PerformanceMonitor> perfMons = new ConcurrentHashMap<>();
+    public static PerformanceMonitor experiment(String name) {
+	PerformanceMonitor pm = perfMons.get(name);
+	if (pm == null) {
+	    pm = new PerformanceMonitor();
+	    PerformanceMonitor existing = perfMons.putIfAbsent(name, pm);
+	    if (existing != null) {
+		pm = existing;
+	    }
+	}
+	return pm;
+    }
+
+    // tag -> Measurements
+    private final ConcurrentHashMap<String, Queue<Measurement>> map = new ConcurrentHashMap<>();
+    private long overhead;
+    private long experimentStart = Long.MAX_VALUE;
+    private final static double normalization = Math.pow(10, 6);
+
+    /**
+     * Start a performance measurement, identified by a tag
+     *
+     * Note: Only a single measurement can use the same tag at a time.
+     * ..... not true anymore.
+     *
+     * @param tag for performance measurement
+     */
+    public Measurement startStep(String tag) {
+	long start = System.nanoTime();
+	if(start < experimentStart) {
+	    experimentStart = start;
+	}
+	Queue<Measurement> list = map.get(tag);
+	if(list == null) {
+	    list = new ConcurrentLinkedQueue<Measurement>();
+	    Queue<Measurement> existing_list = map.putIfAbsent(tag, list);
+	    if (existing_list != null) {
+		// someone concurrently added, using theirs
+		list = existing_list;
+	    }
+	}
+	Measurement m = new Measurement();
+	list.add(m);
+	m.start();
+	overhead += System.nanoTime() - start;
+	return m;
+    }
+
+    /**
+     * Stop a performance measurement.
+     *
+     * You must have already started a measurement with tag.
+     *
+     * @param tag for performance measurement
+     */
+    public void stopStep(String tag) {
+	long time = System.nanoTime();
+	Queue<Measurement> list = map.get(tag);
+	if(list == null || list.size() == 0) {
+	    log.error("Tag {} does not exist", tag);
+	}
+	list.peek().stop(time);
+	if(list.size() > 1) {
+	    log.error("Tag {} has multiple measurements", tag);
+	}
+	overhead += System.nanoTime() - time;
+    }
+
+    /**
+     * Clear all performance measurements.
+     */
+    public void reset() {
+	map.clear();
+	overhead = 0;
+	experimentStart = Long.MAX_VALUE;
+    }
+
+    /**
+     * Write all performance measurements to the log
+     */
+    public void reportAll() {
+	String result = "Performance Results: (avg/start/stop/count)\n";
+	if(map.size() == 0) {
+	    result += "No Measurements";
+	    log.error(result);
+	    return;
+	}
+	long experimentEnd = -1;
+	for(Entry<String, Queue<Measurement>> e : map.entrySet()) {
+	    String key = e.getKey();
+	    Queue<Measurement> list = e.getValue();
+	    long total = 0, count = 0;
+	    long start = Long.MAX_VALUE, stop = -1;
+	    for(Measurement m : list) {
+		if(m.stop < 0) {
+		    continue; // measurement has not been stopped
+		}
+		// Collect overall start and end times
+		if(m.start < start) {
+		    start = m.start;
+		}
+		if(m.stop > stop) {
+		    stop = m.stop;
+		    if(stop > experimentEnd) {
+			experimentEnd = stop;
+		    }
+		}
+		// Collect statistics for average
+		total += m.elapsed();
+		count++;
+	    }
+	    double avg = (double) total / count;
+	    // Normalize start/stop
+	    start -= experimentStart;
+	    stop -= experimentStart;
+	    result += key + '=' +
+		    (avg / normalization) + '/' +
+		    (start / normalization) + '/' +
+		    (stop / normalization) + '/' +
+		    count + '\n';
+	}
+	double overheadMs = overhead / normalization;
+	double experimentElapsed = (experimentEnd - experimentStart) / normalization;
+	result += "TotalTime:" + experimentElapsed + "/Overhead:" + overheadMs;
+	log.error(result);
+//	log.error("Performance Results: {} with measurement overhead: {} ms", map, overheadMilli);
+    }
+
+    /**
+     * Write the performance measurement for a tag to the log
+     *
+     * @param tag the tag name.
+     */
+    public void reportStep(String tag) {
+	Queue<Measurement> list = map.get(tag);
+	if(list == null) {
+	    return; //TODO
+	}
+	//TODO: fix this;
+	Measurement m = list.peek();
+	if (m != null) {
+	    log.error("Performance Result: tag = {} start = {} stop = {} elapsed = {}",
+		      tag, m.start, m.stop, m.toString());
+	} else {
+	    log.error("Performance Result: unknown tag {}", tag);
+	}
+    }
+
+    /**
+     * A single performance measurement
+     */
+    public static class Measurement {
+	long start;
+	long stop = -1;
+
+	/**
+	 * Start the measurement
+	 */
+	public void start() {
+	    if(start <= 0) {
+		start = System.nanoTime();
+	    }
+	}
+
+	/**
+	 * Stop the measurement
+	 */
+	public void stop() {
+	    long now = System.nanoTime();
+	    stop(now);
+	}
+
+	/**
+	 * Stop the measurement at a specific time
+	 * @param time to stop
+	 */
+	public void stop(long time){
+	    if(stop <= 0) {
+		stop = time;
+	    }
+	}
+
+	/**
+	 * Compute the elapsed time of the measurement in nanoseconds
+	 *
+	 * @return the measurement time in nanoseconds, or -1 if the measurement is stil running.
+	 */
+	public long elapsed() {
+	    if(stop <= 0) {
+		return -1;
+	    }
+	    else {
+		return stop - start;
+	    }
+	}
+
+	/**
+	 * Returns the number of milliseconds for the measurement as a String.
+	 */
+	@Override
+	public String toString() {
+	    double milli = elapsed() / normalization;
+	    double startMs = start / normalization;
+	    double stopMs = stop / normalization;
+
+	    return milli + "ms/" + startMs + '/' + stopMs;
+	}
+    }
+
+    @Deprecated
+    private static final PerformanceMonitor theInstance = new PerformanceMonitor();
+
+    @Deprecated
+    public static Measurement start(String tag) {
+	return theInstance.startStep(tag);
+    }
+
+    @Deprecated
+    public static void stop(String tag) {
+	theInstance.stopStep(tag);;
+    }
+
+    @Deprecated
+    public static void clear() {
+	theInstance.reset();;
+    }
+
+    @Deprecated
+    public static void report() {
+	theInstance.reportAll();;
+    }
+
+    @Deprecated
+    public static void report(String tag) {
+	theInstance.reportStep(tag);
+    }
+
+    public static void main(String args[]){
+	// test the measurement overhead
+	String tag;
+	for(int i = 0; i < 2; i++){
+	    tag = "foo foo foo";
+	    Measurement m;
+	    m = start(tag); System.out.println(tag); m.stop();
+	    m = start(tag); System.out.println(tag); m.stop();
+	    m = start(tag); System.out.println(tag); m.stop();
+	    m = start(tag); System.out.println(tag); m.stop();
+	    tag = "bar";
+	    start(tag); stop(tag);
+	    tag = "baz";
+	    start(tag); stop(tag);
+	    report();
+	    clear();
+	}
+	for(int i = 0; i < 100; i++){
+	    tag = "a";
+	    start(tag); stop(tag);
+	    start(tag); stop(tag);
+
+	    start(tag); stop(tag);
+	    start(tag); stop(tag);
+	    start(tag); stop(tag);
+	    start(tag); stop(tag);
+	    start(tag); stop(tag);
+	    start(tag); stop(tag);
+
+	    tag = "b";
+	    start(tag); stop(tag);
+	    tag = "c";
+	    start(tag); stop(tag);
+	    report();
+	    clear();
+	}
+    }
+}