MarkovEstimate initial_est = s.getInitialEstimate();
assert (initial_est != null);
MarkovEstimate last_est = s.getLastEstimate();
assert (last_est != null);
MarkovGraph markov = s.getMarkovGraph();
assert (markov != null);
final int base_partition = s.getBasePartition();
final int num_estimates = s.getEstimateCount();
List<Estimate> estimates = null;
// This is strictly for the paper so that we can show how slow it would
// be to have calculate probabilities through a traversal for each batch
if (this.force_regenerate_markovestimates) {
if (debug.val) {
String name = TransactionUtil.formatTxnName(markov.getProcedure(), s.getTransactionId());
LOG.debug("Using " + MarkovProbabilityCalculator.class.getSimpleName() + " to calculate MarkoEstimates for " + name);
}
estimates = new ArrayList<Estimate>();
for (Estimate e : s.getEstimates()) {
MarkovEstimate est = (MarkovEstimate)e;
MarkovVertex v = est.getVertex();
MarkovEstimate new_est = MarkovProbabilityCalculator.generate(this.catalogContext, markov, v);
assert (new_est != null);
estimates.add(est);
} // FOR
} else {
estimates = s.getEstimates();
}
boolean e_singlepartitioned = initial_est.isSinglePartitioned(this.thresholds);
boolean a_singlepartitioned = (this.a_all_partitions.size() == 1);
boolean first_penalty = true;
if (trace.val) {
LOG.trace("Estimated Read Partitions: " + this.e_read_partitions);
LOG.trace("Estimated Write Partitions: " + this.e_write_partitions);
LOG.trace("Actual Read Partitions: " + this.a_read_partitions);
LOG.trace("Actual Write Partitions: " + this.a_write_partitions);
}
// ----------------------------------------------------------------------------
// BASE PARTITION
// ----------------------------------------------------------------------------
PartitionSet most_touched = initial_est.getMostTouchedPartitions(this.thresholds);
Integer e_base_partition = null;
if (most_touched.size() > 1) {
e_base_partition = CollectionUtil.random(most_touched);
} else {
e_base_partition = CollectionUtil.first(most_touched);
}
if (e_base_partition == null || e_base_partition != base_partition) {
if (trace.val) {
LOG.trace(String.format("Estimated base partition for txn #%d was %d but PartitionEstimator says it should be %d", s.getTransactionId(), e_base_partition, base_partition));
}
this.penalties.add(Penalty.WRONG_BASE_PARTITION);
// assert(false) : e_base_partition + " != " + base_partition + " "
// + most_touched;
}
// ----------------------------------------------------------------------------
// ABORTS
// If the transaction was predicted to be single-partitioned and we
// don't predict that it's going to
// abort when it actually did, then that's bad! Really bad!
// ----------------------------------------------------------------------------
first_penalty = true;
if (initial_est.isAbortable(this.thresholds) == false && a_last.isAbortVertex()) {
if (trace.val) {
if (first_penalty) {
LOG.trace("PENALTY: " + MarkovOptimization.OP3_ABORTS);
first_penalty = false;
}
LOG.trace(String.format("Txn #%d aborts but we predicted that it would never!", s.getTransactionId()));
}
this.penalties.add(a_singlepartitioned ? Penalty.MISSED_ABORT_SINGLE : Penalty.MISSED_ABORT_MULTI);
}
// For each MarkovEstimate, check whether there is a path in the graph
// for the current vertex
// to the abort state. If there isn't, then we need to check whether
// This should match ExecutionSite.executeLocalPlan()
MarkovVertex abort_v = markov.getAbortVertex();
boolean last_hadAbortPath = true;
first_penalty = true;
for (Estimate e : estimates) {
MarkovEstimate est = (MarkovEstimate)e;
assert(est.isInitialized()) : "Uninitialized MarkovEstimate from " + s;
MarkovVertex v = est.getVertex();
assert (v != null) : "No vertex?\n" + est;
boolean isAbortable = est.isAbortable(this.thresholds);
boolean isReadOnly = est.isReadOnlyPartition(this.thresholds, base_partition);
boolean hasAbortPath;
synchronized (markov) {
hasAbortPath = (markov.getPath(v, abort_v).isEmpty() == false);
} // SYNCH
// Make sure that we didn't have a path for the last MarkovEstimate
// but
// we somehow have one now
if (hasAbortPath && last_hadAbortPath == false) {
LOG.info("MARKOV: " + MarkovUtil.exportGraphviz(markov, false, markov.getPath(v, abort_v)).writeToTempFile());
assert (last_hadAbortPath);
}
// If the path is not empty, then this txn could still abort
if (hasAbortPath)