package edu.brown.markov; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.log4j.Logger; import edu.brown.logging.LoggerUtil; import edu.brown.logging.LoggerUtil.LoggerBoolean; /** * Special container for keeping track of transaction visitation times at MarkovVertexes * @author pavlo */ public class MarkovGraphTimes { private static final Logger LOG = Logger.getLogger(MarkovGraphTimes.class); private final static LoggerBoolean debug = new LoggerBoolean(); private final static LoggerBoolean trace = new LoggerBoolean(); static { LoggerUtil.attachObserver(LOG, debug, trace); } /** * The execution times of the transactions in the on-line run * A map of the xact_id to the time it took to get to this vertex */ private final Map<MarkovVertex, Map<Long, Long>> instancetimes = new HashMap<MarkovVertex, Map<Long,Long>>(); /** * Normalizes the times kept during online tallying of execution times. * TODO (svelagap): What about aborted transactions? Should they be counted in the normalization? */ public void normalizeTimes(MarkovGraph graph) { Map<Long, Long> stoptimes = this.getInstanceTimes(graph.getCommitVertex()); List<Long> to_remove = new ArrayList<Long>(); for (MarkovVertex v : graph.getVertices()) { this.normalizeInstanceTimes(v, stoptimes, to_remove); to_remove.clear(); } // FOR } /** * Add another instance time to the map. We use these times to figure out how long each * transaction takes to execute in the on-line model. */ public MarkovVertex addInstanceTime(MarkovVertex v, Long xact_id, long time) { Map<Long, Long> m = this.instancetimes.get(v); if (m == null) { m = new HashMap<Long, Long>(); this.instancetimes.put(v, m); } m.put(xact_id, time); return (v); } /** * Since we cannot know when a transaction ends in the on-line updates world, we wait until we find out * that we need to recompute, then we normalize all the vertices in every graph with the end times, to * get how long the xact actually lasted * @param end_times */ protected void normalizeInstanceTimes(MarkovVertex v, Map<Long, Long> end_times, Collection<Long> to_remove) { Map<Long, Long> m = this.instancetimes.get(v); for (Entry<Long, Long> e : m.entrySet()) { Long stop = end_times.get(e.getKey()); if (e.getValue() != null && stop != null) { long time = stop.longValue() - e.getValue().longValue(); v.addExecutionTime(time); to_remove.add(e.getKey()); if (trace.val) LOG.trace(String.format("Updating %s with %d time units from txn #%d", v, time, e.getKey())); } } // FOR for (Long txn_id : to_remove) { end_times.remove(txn_id); } // FOR } /** * @return a map of xact_ids to times */ public Map<Long,Long> getInstanceTimes(MarkovVertex v) { return this.instancetimes.get(v); } }