package edu.usc.enl.dynamicmeasurement.util.profile; import edu.usc.enl.dynamicmeasurement.util.Util; import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; /** * Created with IntelliJ IDEA. * User: masoud * Date: 11/4/13 * Time: 4:26 PM <br/> * This class helps to track the latency between two actions in nanoseconds. */ public class LatencyProfiler { private Map<String, Long> profile; private String lastKey; private PrintWriter profileWriter; private int writeEpoch; public LatencyProfiler(Class c) { this(Util.getRootFolder() + "/profile_" + c.getSimpleName() + ".csv"); } public LatencyProfiler(String outputFile) { profile = new HashMap<>(); writeEpoch = 0; try { profileWriter = new PrintWriter(outputFile); } catch (IOException e) { e.printStackTrace(); } } /** * Start tracking the timer for key "key". Can be called once for each key. * Running that again will reset the timestamp of the start of the key. * * @param key */ public void start(String key) { profile.put(key, System.nanoTime()); lastKey = key; } /** * stop tracking the timer for key "key". Can be called once after starting te key * * @param key */ public void stop(String key) { if (profile.containsKey(key)) { profile.put(key, System.nanoTime() - profile.get(key)); } lastKey = null; } /** * Stops tracking for the latest key and starts for the new one * * @param key */ public void sequentialRecord(String key) { if (lastKey != null) { if (key != null && !lastKey.equals(key)) { stop(lastKey);//makes lastkey null start(key); } else { stop(lastKey); } } else if (key != null) { start(key); } } /** * decides to do starting or stopping. Can be called twice for a key. * * @param key */ public void record(String key) { Long timeStamp = profile.get(key); if (timeStamp == null) { profile.put(key, System.nanoTime()); lastKey = key; } else { profile.put(key, System.nanoTime() - timeStamp); lastKey = null; } } /** * clear all statistics */ public void clear() { profile.clear(); lastKey = null; } /** * write the statistics in the file and clear */ public void write() { if (profileWriter != null) { for (Map.Entry<String, Long> entry : profile.entrySet()) { profileWriter.println(writeEpoch + "," + entry.getKey() + "," + entry.getValue()); } profileWriter.flush(); } writeEpoch++; clear(); } public void finish() { if (profileWriter != null) { profileWriter.close(); } } public Long get(String key) { return profile.get(key); } }