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();
+ }
+ }
+}