package edu.brown.workload.filters;
import org.apache.log4j.Logger;
import org.voltdb.catalog.CatalogType;
import org.voltdb.catalog.Database;
import org.voltdb.catalog.Procedure;
import edu.brown.logging.LoggerUtil.LoggerBoolean;
import edu.brown.utils.PartitionEstimator;
import edu.brown.utils.PartitionSet;
import edu.brown.workload.AbstractTraceElement;
import edu.brown.workload.QueryTrace;
import edu.brown.workload.TransactionTrace;
/**
* Filter TranasctionTraces based on whether they are single-partitioned or not
* @author pavlo
*/
public class MultiPartitionTxnFilter extends Filter {
private static final Logger LOG = Logger.getLogger(MultiPartitionTxnFilter.class);
private static final LoggerBoolean debug = new LoggerBoolean();
private final PartitionEstimator p_estimator;
private final Database catalog_db;
private final boolean singlepartition;
/**
* Constructor
* @param p_estimator
* @param singlepartition - if true, only allow singlepartition txns, otherwise only multipartition txns
*/
public MultiPartitionTxnFilter(PartitionEstimator p_estimator, boolean singlepartition) {
super();
this.p_estimator = p_estimator;
this.catalog_db = p_estimator.getCatalogContext().database;
this.singlepartition = singlepartition;
}
@Override
protected void resetImpl() {
// Ignore...
}
@Override
protected FilterResult filter(AbstractTraceElement<? extends CatalogType> element) {
FilterResult result = FilterResult.ALLOW;
if (element instanceof TransactionTrace) {
TransactionTrace xact = (TransactionTrace)element;
Procedure catalog_proc = xact.getCatalogItem(this.catalog_db);
PartitionSet partitions = new PartitionSet();
try {
int base_partition = this.p_estimator.getBasePartition(catalog_proc, xact.getParams(), true);
partitions.add(base_partition);
for (QueryTrace query : xact.getQueries()) {
this.p_estimator.getAllPartitions(partitions, query, base_partition);
} // FOR
} catch (Exception ex) {
throw new RuntimeException(ex);
}
assert(partitions.isEmpty() == false);
boolean allow = (this.singlepartition ? (partitions.size() == 1) : (partitions.size() > 1));
result = (allow ? FilterResult.ALLOW : FilterResult.SKIP);
if (debug.val)
LOG.debug(String.format("%s :: partitions=%s / allow=%s ==> %s",
xact, partitions, allow, result));
}
return (result);
}
@Override
public String debugImpl() {
return (this.getClass().getSimpleName() + ": singlePartition=" + this.singlepartition);
}
}