gt:             queries[i] = this.createQueryEstimate(traces[i]);
context: package edu.brown.hstore.specexec.checkers;
  
  import java.io.File;
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Set;
  
  import org.junit.Before;
  import org.voltdb.ParameterSet;
  import org.voltdb.VoltProcedure;
  import org.voltdb.benchmark.tpcc.TPCCProjectBuilder;
  import org.voltdb.benchmark.tpcc.procedures.UpdateNewOrder;
  import org.voltdb.benchmark.tpcc.procedures.neworder;
  import org.voltdb.benchmark.tpcc.procedures.ostatByCustomerId;
  import org.voltdb.benchmark.tpcc.procedures.paymentByCustomerId;
  import org.voltdb.benchmark.tpcc.procedures.slev;
  import org.voltdb.catalog.Column;
  import org.voltdb.catalog.ConflictPair;
  import org.voltdb.catalog.ProcParameter;
  import org.voltdb.catalog.Procedure;
  import org.voltdb.catalog.Statement;
  import org.voltdb.catalog.StmtParameter;
  
  import edu.brown.BaseTestCase;
  import edu.brown.catalog.CatalogUtil;
  import edu.brown.catalog.special.CountedStatement;
  import edu.brown.hstore.HStoreSite;
  import edu.brown.hstore.MockHStoreSite;
  import edu.brown.hstore.conf.HStoreConf;
  import edu.brown.hstore.specexec.checkers.MarkovConflictChecker.StatementCache;
  import edu.brown.hstore.txns.AbstractTransaction;
  import edu.brown.hstore.txns.LocalTransaction;
  import edu.brown.mappings.ParameterMapping;
  import edu.brown.mappings.ParametersUtil;
  import edu.brown.markov.EstimationThresholds;
  import edu.brown.markov.containers.MarkovGraphsContainer;
  import edu.brown.markov.containers.MarkovGraphsContainerUtil;
  import edu.brown.statistics.Histogram;
  import edu.brown.statistics.ObjectHistogram;
  import edu.brown.utils.CollectionUtil;
  import edu.brown.utils.PartitionSet;
  import edu.brown.utils.ProjectType;
  import edu.brown.workload.QueryTrace;
  import edu.brown.workload.TransactionTrace;
  import edu.brown.workload.Workload;
  import edu.brown.workload.filters.ProcParameterValueFilter;
  import edu.brown.workload.filters.ProcedureNameFilter;
  
  public class TestMarkovConflictChecker extends BaseTestCase {
  
      private static final int NUM_PARTITIONS = 10;
      private static final int WORKLOAD_XACT_LIMIT = 20;
      private static final int TARGET_WAREHOUSES[] = { 1, 2 };
      private static final Integer TARGET_DISTRICT_ID = 5;
      @SuppressWarnings("unchecked")
      private static final Class<? extends VoltProcedure> TARGET_PROCEDURES[] = (Class<? extends VoltProcedure>[])new Class<?>[]{
          neworder.class,
          ostatByCustomerId.class,
          slev.class,
      };
      
      private static Workload workload;
      private static MarkovGraphsContainer markovs;
      
      private final EstimationThresholds thresholds = new EstimationThresholds();
      private MarkovConflictChecker checker;
      private HStoreSite hstore_site;
      
      private final TPCCProjectBuilder builder = new TPCCProjectBuilder() {
          {
              this.addAllDefaults();
              this.addProcedure(UpdateNewOrder.class);
          }
      };
      
      @Before
      public void setUp() throws Exception {
          this.reset(ProjectType.TPCC);
          super.setUp(this.builder);
          this.addPartitions(NUM_PARTITIONS);
          
          if (isFirstSetup()) {
              
              File file = this.getWorkloadFile(ProjectType.TPCC);
              workload = new Workload(catalogContext.catalog);
              ProcParameterValueFilter filter = new ProcParameterValueFilter().include(1, TARGET_DISTRICT_ID);
              for (int w_id : TARGET_WAREHOUSES) {
                  filter.include(0, w_id);
              } // FOR
              ProcedureNameFilter procFilter = new ProcedureNameFilter(false);
              for (Class<? extends VoltProcedure> procClass : TARGET_PROCEDURES) {
                  procFilter.include(procClass.getSimpleName(), WORKLOAD_XACT_LIMIT);
              } // FOR
              workload.load(file, catalogContext.database, filter.attach(procFilter));
  
              // Generate MarkovGraphs per base partition
              markovs = MarkovGraphsContainerUtil.createBasePartitionMarkovGraphsContainer(catalogContext,
                                                                                           workload, p_estimator);
          }
          assertNotNull(markovs);
          
          this.hstore_site = new MockHStoreSite(0, catalogContext, HStoreConf.singleton());
          this.checker = new MarkovConflictChecker(catalogContext, thresholds);
      }
      
      // ----------------------------------------------------------------------------------
      // HELPER METHODS
      // ----------------------------------------------------------------------------------
      
      private TransactionTrace getTransactionTrace(Procedure proc, int w_id) throws Exception {
          TransactionTrace txn_trace = null;
          int partition = p_estimator.getHasher().hash(w_id);
          for (TransactionTrace tt : workload.getTraces(proc)) {
              // System.err.println(tt + " :: " + w_id + " / " + tt.getParam(0));
              if (partition == p_estimator.getBasePartition(tt)) {
                  txn_trace = tt;
                  break;
              }
          } // FOR
          return (txn_trace);
      }
      
      private TransactionTrace[] getTransactionTraces(Procedure procs[], boolean differentWarehouse) throws Exception {
          TransactionTrace traces[] = new TransactionTrace[procs.length];
          int last = -1;
          
          // Different W_ID
          if (differentWarehouse) {
              for (int i = 0; i < procs.length; i++) {
                  for (int w_id : TARGET_WAREHOUSES) {
                      if (w_id == last) continue;
                      traces[i] = this.getTransactionTrace(procs[i], w_id);
                      if (traces[i] != null) {
                          last = w_id;
                          break;
                      }
                  } // FOR
                  assertNotNull(traces[i]);
                  assert(last >= 0);
              } // FOR
          }
          // Same W_ID
          else {
              for (int w_id : TARGET_WAREHOUSES) {
                  boolean foundAll = true;
                  for (int i = 0; i < procs.length; i++) {
                      traces[i] = this.getTransactionTrace(procs[i], w_id);
                      foundAll = foundAll && (traces[i] != null); 
                  } // FOR
                  if (foundAll) {
                      last = w_id;
                      break;
                  }
              } // FOR
          }
          assert(last >= 0);
          
          return (traces);
      }
  
      private AbstractTransaction createTransaction(TransactionTrace txn_trace) throws Exception {
          PartitionSet partitions = new PartitionSet(); 
          int base_partition = p_estimator.getBasePartition(txn_trace);
          p_estimator.getAllPartitions(partitions, txn_trace);
          LocalTransaction ts = new LocalTransaction(this.hstore_site);
          ts.testInit(txn_trace.getTransactionId(),
                      base_partition,
                      partitions,
                      txn_trace.getCatalogItem(catalogContext.database),
                      txn_trace.getParams());
          return (ts);
      }
      
      private List<CountedStatement> createQueryEstimate(TransactionTrace txn_trace) {
          return this.createQueryEstimate(txn_trace, null);
      }
      
      private List<CountedStatement> createQueryEstimate(TransactionTrace txn_trace, Statement start) {
          Histogram<Statement> stmtHistogram = new ObjectHistogram<Statement>();
          List<CountedStatement> queries = new ArrayList<CountedStatement>();
          boolean include = (start == null);
          for (QueryTrace q : txn_trace.getQueries()) {
              Statement stmt = q.getCatalogItem(catalogContext.database);
              if (include == false && stmt.equals(start) == false) continue;
              include = true;
              queries.add(new CountedStatement(stmt, (int)stmtHistogram.get(stmt, 0l)));
              stmtHistogram.put(stmt);
          } // FOR
          return (queries);
      }
      
      // ----------------------------------------------------------------------------------
      // TESTS
      // ----------------------------------------------------------------------------------
      
      /**
       * testNonConflictingReadOnly
       */
      public void testNonConflictingReadOnly() throws Exception {
          // Quickly check that two read-only txns are non-conflicting 
          // even without a txn estimate
          Procedure proc = this.getProcedure(slev.class);
          int basePartition = 0;
          PartitionSet partitions = catalogContext.getAllPartitionIds(); 
          
          LocalTransaction ts0 = new LocalTransaction(this.hstore_site);
          Object params0[] = new Object[]{ 0, 1, 2 };
          ts0.testInit(10000l, basePartition, partitions, proc, params0);
          
          LocalTransaction ts1 = new LocalTransaction(this.hstore_site);
          Object params1[] = new Object[]{ 0, 1, 2 };
          ts1.testInit(10001l, basePartition, partitions, proc, params1);
          
          boolean ret = this.checker.hasConflictBefore(ts0, ts1, basePartition);
          assertFalse(ret);
      }
      
      /**
       * testNonConflictingDisparateTables
       */
      public void testNonConflictingDisparateTables() throws Exception {
          // Quickly check that two read-only txns are non-conflicting 
          // even without a txn estimate
          int basePartition = 0;
          PartitionSet partitions = catalogContext.getAllPartitionIds(); 
  
          Procedure proc0 = this.getProcedure(paymentByCustomerId.class);
          LocalTransaction ts0 = new LocalTransaction(this.hstore_site);
          Object params0[] = new Object[]{ 0, 1, 2 };
          ts0.testInit(10000l, basePartition, partitions, proc0, params0);
          
          Procedure proc1 = this.getProcedure(UpdateNewOrder.class);
          LocalTransaction ts1 = new LocalTransaction(this.hstore_site);
          Object params1[] = new Object[]{ 0, 0 };
          ts1.testInit(10001l, basePartition, partitions, proc1, params1);
          
          boolean ret = this.checker.hasConflictBefore(ts0, ts1, basePartition);
          assertFalse(ret);
      }
      
      /**
       * testColumnStmtParameters
       */
      public void testColumnStmtParameters() throws Exception {
          Procedure proc = this.getProcedure(neworder.class);
          Statement stmt = this.getStatement(proc, "getDistrict");
          StatementCache cache = this.checker.stmtCache.get(stmt);
          assertNotNull(stmt.fullName(), cache);
          
          Collection<Column> cols = CatalogUtil.getReferencedColumns(stmt);
          assertFalse(cols.isEmpty());
          // System.err.println(stmt.fullName() + " -> " + cols + "\n" + StringUtil.formatMaps(cache.colParams));
          
          Set<StmtParameter> seenParams = new HashSet<StmtParameter>();
          for (Column col : cols) {
              StmtParameter param = cache.colParams.get(col);
              assertNotNull(col.fullName(), param);
              assertFalse(param.fullName(), seenParams.contains(param));
              seenParams.add(param);
          } // FOR
          assertEquals(cols.size(), seenParams.size());
      }
      
      /**
       * testStatementCache
       */
      public void testStatementCache() throws Exception {
          Procedure proc0 = this.getProcedure(slev.class);
          Statement stmt0 = this.getStatement(proc0, "GetStockCount");
          Procedure proc1 = this.getProcedure(neworder.class);
          Statement stmt1 = this.getStatement(proc1, "createOrderLine");
          
          // STMT0 is going to try to read to a table that STMT1 will write to
          // So we should be able to see that conflict
          StatementCache cache = this.checker.stmtCache.get(stmt0);
          assertNotNull(stmt0.fullName(), cache);
          
          ConflictPair cp = cache.conflicts.get(stmt1);
          assertNotNull(stmt0.fullName()+"->"+stmt1.fullName(), cp);
          assertTrue(cp.getAlwaysconflicting());
      }
      
      /**
       * testCanExecuteNonConflicting
       */
      public void testCanExecuteNonConflicting() throws Exception {
          Procedure procs[] = {
              this.getProcedure(neworder.class),
              this.getProcedure(ostatByCustomerId.class),
          };
          Statement startStmts[] = {
              this.getStatement(procs[0], "updateStock"),
              null,
          };
          TransactionTrace traces[] = this.getTransactionTraces(procs, true);
          
          AbstractTransaction txns[] = new AbstractTransaction[procs.length];
          @SuppressWarnings("unchecked")
          List<CountedStatement> queries[] = (List<CountedStatement>[])(new ArrayList<?>[procs.length]);
          for (int i = 0; i < procs.length; i++) {
              txns[i] = this.createTransaction(traces[i]);
              queries[i] = this.createQueryEstimate(traces[i], startStmts[i]);
              assert(queries[i].size() > 0);
          } // FOR
          
          // Both txns should be going after the same warehouse + district id, so 
          // that means they will be conflicting
  //        System.err.println(StringUtil.columns(trace0.debug(catalog_db), trace1.debug(catalog_db)));
  //        System.err.println(StringUtil.columns(
  //                Arrays.toString(traces[0].getParams()),
  //                Arrays.toString(traces[1].getParams())
  //        ));
  //        System.err.println(StringUtil.columns(
  //                StringUtil.join("\n", queries[0].getFirst()),
  //                StringUtil.join("\n", queries[1].getFirst())
  //        ));
          boolean result = this.checker.canExecute(txns[0], queries[0], txns[1], queries[1]);
          assertTrue(result);
      }
      
      /**
       * testCanExecuteNonConflictingUniqueIndex
       */
      public void testCanExecuteNonConflictingUniqueIndex() throws Exception {
          Procedure procs[] = {
              this.getProcedure(ostatByCustomerId.class),
              this.getProcedure(neworder.class),
          };
          TransactionTrace traces[] = this.getTransactionTraces(procs, true);
          
          AbstractTransaction txns[] = new AbstractTransaction[procs.length];
          @SuppressWarnings("unchecked")
          List<CountedStatement> queries[] = (List<CountedStatement>[])(new ArrayList<?>[procs.length]);
          for (int i = 0; i < procs.length; i++) {
              txns[i] = this.createTransaction(traces[i]);
  