@Override
protected void callback(MarkovVertex element) {
MarkovGraph markov = (MarkovGraph)this.getGraph();
// HACK
final DynamicTransactionEstimate est = (this.markov_est != null ? this.markov_est : element);
final Type vtype = element.getType();
if (debug.val) {
if (this.getCounter() > 1) LOG.debug(StringUtil.repeat("-", 100));
LOG.debug(String.format("BEFORE: %s\n%s", element, element.debug()));
// LOG.debug("BEFORE: " + element + " => " + est.getSinglePartitionProbability());
}
// COMMIT/ABORT is always single-partitioned!
if (vtype == MarkovVertex.Type.COMMIT || vtype == MarkovVertex.Type.ABORT) {
// est.setSinglePartitionProbability(1.0f);
// And DONE at all partitions!
// And will not Read/Write Probability
for (int partition : this.all_partitions.values()) {
est.setDoneProbability(partition, 1.0f);
// est.setReadOnlyProbability(partition, 1.0f);
est.setWriteProbability(partition, 0.0f);
} // FOR
// Abort Probability
if (vtype == MarkovVertex.Type.ABORT) {
est.setAbortProbability(1.0f);
} else {
est.setAbortProbability(0.0f);
}
}
// STATEMENT VERTEX
else {
// Make sure everything is set to zero
// est.setSinglePartitionProbability(0f);
for (int partition : this.all_partitions.values()) {
est.setDoneProbability(partition, 0f);
// est.setReadOnlyProbability(partition, 0f);
est.setWriteProbability(partition, 0f);
} // FOR
for (MarkovEdge e : markov.getOutEdges(element)) {
if (this.visited_edges.contains(e)) continue;
MarkovVertex successor = markov.getDest(e);
assert(successor != null) :
"Null successor for " + e.debug(markov);
// assert(successor.isSinglePartitionProbabilitySet()) :
// "Setting " + element + " BEFORE " + successor;
assert(successor.isStartVertex() == false) :
"Invalid edge " + element + " --> " + successor;
if (debug.val)
LOG.debug(String.format("*** NEXT EDGE [%s --%s--> %s]",
element, e, successor));
final Statement successorStmt = successor.getCatalogItem();
final float edgeProbability = e.getProbability();
// SINGLE-PARTITION PROBABILITY
// If our successor only touches partition and that partition is also accessed
// by the current vertex... <-- Not sure we need this last one
// if (successor.isQueryVertex() == false || successor.getPartitions().size() == 1) { // || element.getPartitions().containsAll(successorPartitions)) {
// est.addSinglePartitionProbability(edgeProbability * successor.getSinglePartitionProbability());
// }
// ABORT PROBABILITY
// We need to have seen at least this number of hits before we will use a
// different probability that a transaction could abort
if (element.getTotalHits() >= MarkovGraph.MIN_HITS_FOR_NO_ABORT) {
est.addAbortProbability(edgeProbability * successor.getAbortProbability());
} else {
est.setAbortProbability(1.0f);
}
// DONE/READ/WRITE AT PARTITION PROBABILITY
for (int partition : this.all_partitions.values()) {
boolean accessed = successor.getPartitions().contains(partition);
if (trace.val)
LOG.trace(String.format("****** PARTITION %02d [accessed=%s]",
partition, accessed));
assert(successor.isDoneProbabilitySet(partition)) :
"Setting " + element + " BEFORE " + successor;
// assert(successor.isReadOnlyProbabilitySet(partition)) :
// "Setting " + element + " BEFORE " + successor;
assert(successor.isWriteProbabilitySet(partition)) :
"Setting " + element + " BEFORE " + successor;
// The successor accesses this partition
if (accessed) {
// IMPORTANT: We don't want to add anything to the done probability because
// it's simply based on whether the txn will go to an vertex that
// does not modify that partition.
// If the query writes to this partition, then the write probability
// for this partition must be increased by the edge's probability
// This is because this is the max probability for writing to this partition
if (successorStmt.getReadonly() == false) {
if (debug.val)
LOG.debug(String.format("%s modifies partition %d. " +
"Adding %f to WRITE probability",
successor, partition, edgeProbability));
est.addWriteProbability(partition, edgeProbability);
}
// Otherwise, we need to set the write probability to be based on
// the probability that we will execute a write query at subsequent
// vertices in the graph
else {
if (debug.val)
LOG.debug(String.format("%s does not modify partition %d. " +
"Setting WRITE probability based on children",
element, partition));
est.addWriteProbability(partition, edgeProbability * successor.getWriteProbability(partition));
}
}
// This successor doesn't access this partition, so we are going to use
// the successor's probabilities for our current vertex. But we have to multiply
// their values by the edge's probability
else {
float before;
// DONE
before = est.getDoneProbability(partition);
try {
est.addDoneProbability(partition, (edgeProbability * successor.getDoneProbability(partition)));
} catch (Throwable ex) {
LOG.warn(String.format("Failed to set FINISH probability for %s [partition=%d / edge=%s / successor=%s / before=%f]",
est, partition, e, successor, before), ex);
}
// WRITE
before = est.getWriteProbability(partition);
try {
est.addWriteProbability(partition, (edgeProbability * successor.getWriteProbability(partition)));
} catch (Throwable ex) {
LOG.warn(String.format("Failed to set WRITE probability for %s [partition=%d / edge=%s / successor=%s / before=%f]",
est, partition, e, successor, before), ex);
}
// READ-ONLY