package edu.brown.workload;
import java.io.File;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import org.voltdb.catalog.Column;
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.benchmark.tm1.procedures.GetAccessData;
import edu.brown.benchmark.tm1.procedures.UpdateLocation;
import edu.brown.mappings.ParameterMappingsSet;
import edu.brown.plannodes.PlanNodeUtil;
import edu.brown.utils.CollectionUtil;
import edu.brown.utils.ProjectType;
public class TestWorkloadSummarizer extends BaseTestCase {
private static final int NUM_PARTITIONS = 100;
private static final int NUM_TRANSACTIONS = 10;
private static final int NUM_QUERIES = 5;
private static final Object PARAMS[] = { new Long(100), new String("ABC123") };
private static ParameterMappingsSet mappings;
private WorkloadSummarizer summarizer;
private Workload workload;
private Procedure catalog_proc;
private Statement catalog_stmt;
@Override
protected void setUp() throws Exception {
super.setUp(ProjectType.TM1);
this.addPartitions(NUM_PARTITIONS);
if (mappings == null) {
File f = this.getParameterMappingsFile(ProjectType.TM1);
mappings = new ParameterMappingsSet();
mappings.load(f, catalog_db);
}
summarizer = new WorkloadSummarizer(catalog_db, p_estimator, mappings);
catalog_proc = this.getProcedure(UpdateLocation.class);
catalog_stmt = this.getStatement(catalog_proc, "update");
// Construct a synthetic workload with duplicate TransactionTraces that each have
// duplicate QueryTraces
workload = new Workload(catalog);
for (int i = 0; i < NUM_TRANSACTIONS; i++) {
TransactionTrace txn_trace = new TransactionTrace(i, catalog_proc, PARAMS);
for (int j = 0; j < NUM_QUERIES; j++) {
QueryTrace query_trace = new QueryTrace(catalog_stmt, PARAMS, i % 3);
txn_trace.addQuery(query_trace);
} // FOR
workload.addTransaction(catalog_proc, txn_trace);
} // FOR
assertEquals(NUM_TRANSACTIONS, workload.getTransactionCount());
}
/**
* testBuildTargetParameters
*/
public void testBuildTargetParameters() throws Exception {
StmtParameter catalog_param = catalog_stmt.getParameters().get(1);
assertNotNull(catalog_param);
Column catalog_col = PlanNodeUtil.getColumnForStmtParameter(catalog_param);
assertNotNull(catalog_col);
Collection<Column> columns = CollectionUtil.addAll(new HashSet<Column>(), catalog_col);
summarizer = new WorkloadSummarizer(catalog_db, p_estimator, mappings, catalog_db.getProcedures(), columns);
ProcParameter expected = this.getProcParameter(catalog_proc, 1);
List<ProcParameter> proc_params = summarizer.getTargetParameters(catalog_proc);
assertNotNull(proc_params);
assertEquals(1, proc_params.size());
assert(proc_params.contains(expected)) : proc_params;
}
/**
* testRemoveDuplicateQueries
*/
public void testRemoveDuplicateQueries() throws Exception {
Workload pruned = this.summarizer.removeDuplicateQueries(workload);
assertNotNull(pruned);
assertEquals(NUM_TRANSACTIONS, pruned.getTransactionCount());
for (TransactionTrace txn_trace : pruned) {
assertNotNull(txn_trace);
// System.err.println(txn_trace.debug(catalog_db) + "\n");
assertEquals(1, txn_trace.getQueryCount());
for (QueryTrace query_trace : txn_trace.getQueries()) {
assertNotNull(query_trace);
assertEquals(NUM_QUERIES, query_trace.getWeight());
} // FOR
} // FOR
// Then add another transaction for another procedure that doesn't have
// duplicate queries
Procedure new_proc = this.getProcedure(GetAccessData.class);
Statement new_stmt = this.getStatement(new_proc, "GetData");
TransactionTrace new_txn_trace = new TransactionTrace(pruned.getTransactionCount() + 100, new_proc, new Object[] { new Long(1), new Long(2) });
for (int i = 0; i < NUM_QUERIES; i++) {
Object new_params[] = new Object[] { new Long(i), new Long(2) };
QueryTrace new_query_trace = new QueryTrace(new_stmt, new_params, i % 3);
new_txn_trace.addQuery(new_query_trace);
} // FOR
workload.addTransaction(new_proc, new_txn_trace);
pruned = this.summarizer.removeDuplicateQueries(workload);
assertNotNull(pruned);
assertEquals(NUM_TRANSACTIONS+1, pruned.getTransactionCount());
for (TransactionTrace txn_trace : pruned) {
assertNotNull(txn_trace);
boolean is_new_proc = txn_trace.getCatalogItem(catalog_db).equals(new_proc);
// System.err.println(txn_trace.debug(catalog_db) + "\n");
if (is_new_proc) {
assertEquals(NUM_QUERIES, txn_trace.getQueryCount());
} else {
assertEquals(this.summarizer.getTransactionTraceSignature(new_proc, txn_trace, null), 1, txn_trace.getQueryCount());
}
for (QueryTrace query_trace : txn_trace.getQueries()) {
assertNotNull(query_trace);
if (is_new_proc) {
assertEquals(1, query_trace.getWeight());
} else {
// FIXME assertEquals(NUM_QUERIES, query_trace.getWeight());
}
} // FOR
} // FOR
}
/**
* testRemoveDuplicateQueriesWithCandidates
*/
public void testRemoveDuplicateQueriesWithCandidates() throws Exception {
// Make a new workload where the first parameter is different for each QueryTrace
// The default WorkloadSummarizer should not identify any duplicate queries
workload = new Workload(catalog);
for (int i = 0; i < NUM_TRANSACTIONS; i++) {
TransactionTrace txn_trace = new TransactionTrace(i, catalog_proc, PARAMS);
for (int j = 0; j < NUM_QUERIES; j++) {
Object query_params[] = { new Long(j), new String("H-STORE!") };
QueryTrace query_trace = new QueryTrace(catalog_stmt, query_params, i % 3);
txn_trace.addQuery(query_trace);
} // FOR
workload.addTransaction(catalog_proc, txn_trace);
} // FOR
assertEquals(NUM_TRANSACTIONS, workload.getTransactionCount());
Workload pruned = this.summarizer.removeDuplicateQueries(workload);
assertNotNull(pruned);
assertEquals(NUM_TRANSACTIONS, pruned.getTransactionCount());
assertEquals(NUM_TRANSACTIONS*NUM_QUERIES, pruned.getQueryCount());
for (TransactionTrace txn_trace : pruned) {
assertNotNull(txn_trace);
assertEquals(NUM_QUERIES, txn_trace.getQueryCount());
for (QueryTrace query_trace : txn_trace.getQueries()) {
assertEquals(1, query_trace.getWeight());
} // FOR (query)
// System.err.println(txn_trace.debug(catalog_db));
// System.err.println("----------------------------------------------");
} // (txn)
// System.err.println(StringUtil.repeat("+", 100));
// We then tell the WorkloadSummarizer that only care about the column that is mapped to the second query
// parameter. All of the queries should then be collapsed into a single weighted query
StmtParameter catalog_param = catalog_stmt.getParameters().get(1);
assertNotNull(catalog_param);
Column catalog_col = PlanNodeUtil.getColumnForStmtParameter(catalog_param);
assertNotNull(catalog_col);
Collection<Column> columns = CollectionUtil.addAll(new HashSet<Column>(), catalog_col);
summarizer = new WorkloadSummarizer(catalog_db, p_estimator, mappings, catalog_db.getProcedures(), columns);
pruned = this.summarizer.removeDuplicateQueries(workload);
assertNotNull(pruned);
assertEquals(NUM_TRANSACTIONS, pruned.getTransactionCount());
assertEquals(NUM_TRANSACTIONS, pruned.getQueryCount());
for (TransactionTrace txn_trace : pruned) {
assertNotNull(txn_trace);
assertEquals(1, txn_trace.getQueryCount());
for (QueryTrace query_trace : txn_trace.getQueries()) {
assertEquals(NUM_QUERIES, query_trace.getWeight());
} // FOR (query)
// System.err.println(txn_trace.debug(catalog_db));
// System.err.println("----------------------------------------------");
} // FOR (txn)
}
/**
* testRemoveDuplicateTransactions
*/
public void testRemoveDuplicateTransactions() throws Exception {
// Make a new workload where the first parameter is different for each TransactionTrace
// The default WorkloadSummarizer should not identify any duplicate transactions
workload = new Workload(catalog);
for (int i = 0; i < NUM_TRANSACTIONS; i++) {
Object txn_params[] = { new Long(i), new String("EVAN GOT MARRIED?!?") };
TransactionTrace txn_trace = new TransactionTrace(i, catalog_proc, txn_params);
for (int j = 0; j < NUM_QUERIES; j++) {
Object query_params[] = { new Long(j + 9999*i), "H-STORE" };
QueryTrace query_trace = new QueryTrace(catalog_stmt, query_params, i % 3);
txn_trace.addQuery(query_trace);
} // FOR
workload.addTransaction(catalog_proc, txn_trace);
} // FOR
assertEquals(NUM_TRANSACTIONS, workload.getTransactionCount());
Workload pruned = this.summarizer.removeDuplicateTransactions(workload);
assertNotNull(pruned);
for (TransactionTrace txn_trace : pruned) {
assertNotNull(txn_trace);
assertEquals(NUM_QUERIES, txn_trace.getQueryCount());
for (QueryTrace query_trace : txn_trace.getQueries()) {
assertEquals(1, query_trace.getWeight());
} // FOR (query)
// System.err.println(summarizer.getTransactionTraceSignature(catalog_proc, txn_trace));
// System.err.println("----------------------------------------------");
} // (txn)
assertEquals(NUM_TRANSACTIONS, pruned.getTransactionCount());
assertEquals(NUM_TRANSACTIONS*NUM_QUERIES, pruned.getQueryCount());
// System.err.println(StringUtil.repeat("+", 100));
// We then tell the WorkloadSummarizer that only care about the column that is mapped to the second
// parameter. All of the queries should then be collapsed into a single weighted query
StmtParameter catalog_param = catalog_stmt.getParameters().get(1);
assertNotNull(catalog_param);
Column catalog_col = PlanNodeUtil.getColumnForStmtParameter(catalog_param);
assertNotNull(catalog_col);
Collection<Column> columns = CollectionUtil.addAll(new HashSet<Column>(), catalog_col);
summarizer = new WorkloadSummarizer(catalog_db, p_estimator, mappings, catalog_db.getProcedures(), columns);
pruned = this.summarizer.removeDuplicateTransactions(workload);
assertNotNull(pruned);
for (TransactionTrace txn_trace : pruned) {
assertNotNull(txn_trace);
// System.err.println(txn_trace.debug(catalog_db));
// System.err.println(summarizer.getTransactionTraceSignature(catalog_proc, txn_trace));
// System.err.println("----------------------------------------------");
assertEquals(NUM_QUERIES, txn_trace.getQueryCount());
for (QueryTrace query_trace : txn_trace.getQueries()) {
assertEquals(1, query_trace.getWeight());
} // FOR (query)
} // FOR (txn)
assertEquals(1, pruned.getTransactionCount());
assertEquals(NUM_QUERIES, pruned.getQueryCount());
}
/**
* testProcess
*/
public void testProcess() throws Exception {
// Make a new workload where the first parameter is different for each TransactionTrace
// The default WorkloadSummarizer should not identify any duplicate transactions
workload = new Workload(catalog);
for (int i = 0; i < NUM_TRANSACTIONS; i++) {
Object txn_params[] = { new Long(i), new String("EVAN GOT MARRIED?!?") };
TransactionTrace txn_trace = new TransactionTrace(i, catalog_proc, txn_params);
for (int j = 0; j < NUM_QUERIES; j++) {
Object query_params[] = { new Long(j + 9999*i), "H-STORE" };
QueryTrace query_trace = new QueryTrace(catalog_stmt, query_params, i % 3);
txn_trace.addQuery(query_trace);
} // FOR
workload.addTransaction(catalog_proc, txn_trace);
} // FOR
assertEquals(NUM_TRANSACTIONS, workload.getTransactionCount());
Workload pruned = this.summarizer.process(workload);
assertNotNull(pruned);
for (TransactionTrace txn_trace : pruned) {
assertNotNull(txn_trace);
assertEquals(NUM_QUERIES, txn_trace.getQueryCount());
for (QueryTrace query_trace : txn_trace.getQueries()) {
assertEquals(1, query_trace.getWeight());
} // FOR (query)
// System.err.println(summarizer.getTransactionTraceSignature(catalog_proc, txn_trace));
// System.err.println("----------------------------------------------");
} // (txn)
assertEquals(NUM_TRANSACTIONS, pruned.getTransactionCount());
assertEquals(NUM_TRANSACTIONS*NUM_QUERIES, pruned.getQueryCount());
// System.err.println(StringUtil.repeat("+", 100));
// We then tell the WorkloadSummarizer that only care about the column that is mapped to the second
// parameter. All of the queries and transactions should then be collapsed into a single weighted transaction
// with a single weight query
StmtParameter catalog_param = catalog_stmt.getParameters().get(1);
assertNotNull(catalog_param);
Column catalog_col = PlanNodeUtil.getColumnForStmtParameter(catalog_param);
assertNotNull(catalog_col);
Collection<Column> columns = CollectionUtil.addAll(new HashSet<Column>(), catalog_col);
summarizer = new WorkloadSummarizer(catalog_db, p_estimator, mappings, catalog_db.getProcedures(), columns);
pruned = this.summarizer.process(workload);
assertNotNull(pruned);
for (TransactionTrace txn_trace : pruned) {
assertNotNull(txn_trace);
// System.err.println(txn_trace.debug(catalog_db));
// System.err.println(summarizer.getTransactionTraceSignature(catalog_proc, txn_trace));
// System.err.println("----------------------------------------------");
assert(txn_trace.getWeight() > 1);
assertEquals(1, txn_trace.getQueryCount());
for (QueryTrace query_trace : txn_trace.getQueries()) {
assertEquals(NUM_QUERIES * NUM_TRANSACTIONS, query_trace.getWeight() * txn_trace.getWeight());
} // FOR (query)
} // FOR (txn)
assertEquals(1, pruned.getTransactionCount());
assertEquals(1, pruned.getQueryCount());
}
}