package edu.brown.utils;
import java.util.*;
import org.junit.Ignore;
import org.junit.Test;
import org.voltdb.CatalogContext;
import org.voltdb.VoltTable;
import org.voltdb.VoltTableRow;
import org.voltdb.VoltType;
import org.voltdb.VoltTable.ColumnInfo;
import org.voltdb.benchmark.tpcc.TPCCConstants;
import org.voltdb.benchmark.tpcc.TPCCProjectBuilder;
import org.voltdb.benchmark.tpcc.procedures.neworder;
import org.voltdb.benchmark.tpcc.procedures.paymentByCustomerId;
import org.voltdb.catalog.*;
import org.voltdb.utils.VoltTypeUtil;
import edu.brown.BaseTestCase;
import edu.brown.catalog.CatalogCloner;
import edu.brown.catalog.CatalogKey;
import edu.brown.catalog.CatalogUtil;
import edu.brown.catalog.special.MultiColumn;
import edu.brown.catalog.special.MultiProcParameter;
import edu.brown.hashing.*;
import edu.brown.hstore.HStoreConstants;
/**
* Simple PartitionEstimator Tests
* @author pavlo
*/
public class TestPartitionEstimator extends BaseTestCase {
protected static AbstractHasher hasher;
protected static final int NUM_PARTITIONS = 100;
protected static final int BASE_PARTITION = 1;
private final PartitionSet partitions = new PartitionSet();
private final TPCCProjectBuilder builder = new TPCCProjectBuilder() {
{
addAllDefaults();
addStmtProcedure("SinglePartitionOR",
"SELECT * FROM " + TPCCConstants.TABLENAME_DISTRICT +
" WHERE D_W_ID = ? AND (D_STREET_1 = ? OR D_STREET_2 = ?)");
addStmtProcedure("MultiPartitionOR",
"SELECT * FROM " + TPCCConstants.TABLENAME_DISTRICT +
" WHERE D_W_ID = ? OR D_W_ID = ?");
addStmtProcedure("ConstantOR",
"SELECT * FROM " + TPCCConstants.TABLENAME_DISTRICT +
" WHERE D_W_ID = " + BASE_PARTITION + " OR D_W_ID = ?");
addStmtProcedure("ConstantRange",
"SELECT * FROM " + TPCCConstants.TABLENAME_DISTRICT +
" WHERE D_W_ID > " + BASE_PARTITION);
}
};
@Override
protected void setUp() throws Exception {
super.setUp(builder);
this.addPartitions(NUM_PARTITIONS);
if (hasher == null) {
hasher = new DefaultHasher(catalogContext, NUM_PARTITIONS); // CatalogUtil.getNumberOfPartitions(catalog_db));
}
Table catalog_tbl = this.getTable(TPCCConstants.TABLENAME_WAREHOUSE);
Column catalog_col = this.getColumn(catalog_tbl, "W_ID");
catalog_tbl.setPartitioncolumn(catalog_col);
this.partitions.clear();
}
/**
* testSinglePartitionOR
*/
public void testSinglePartitionOR() throws Exception {
// Check that if we have a query that does a look up on a partitioning column
// but has an OR in it, it's still a single-partition query.
Procedure catalog_proc = this.getProcedure("SinglePartitionOR");
Statement catalog_stmt = CollectionUtil.first(catalog_proc.getStatements());
assertNotNull(catalog_stmt);
Object params[] = new Object[] { BASE_PARTITION, "XXX", "YYY" };
p_estimator.getAllPartitions(partitions, catalog_stmt, params, BASE_PARTITION);
assertEquals(1, partitions.size());
assertEquals(BASE_PARTITION, partitions.get());
}
/**
* testMultiPartitionOR
*/
public void testMultiPartitionOR() throws Exception {
// Check that if we have a query that does a look up on a partitioning column
// but has an OR in it, then it has to be sent to exactly the number of partitions
// that we expected
Procedure catalog_proc = this.getProcedure("MultiPartitionOR");
Statement catalog_stmt = CollectionUtil.first(catalog_proc.getStatements());
assertNotNull(catalog_stmt);
Object params[] = new Object[] { BASE_PARTITION, BASE_PARTITION+1 };
p_estimator.getAllPartitions(partitions, catalog_stmt, params, BASE_PARTITION);
assertEquals(2, partitions.size());
}
/**
* testConstantOR
*/
public void testConstantOR() throws Exception {
// Check that if we have a query that does a look up on a partitioning column
// using a constant but then it has an OR in it, then it has to be sent to
// exactly the number of partitions that we expected
Procedure catalog_proc = this.getProcedure("ConstantOR");
Statement catalog_stmt = CollectionUtil.first(catalog_proc.getStatements());
assertNotNull(catalog_stmt);
// System.err.println(PlanNodeUtil.debug(PlanNodeUtil.getRootPlanNodeForStatement(catalog_stmt, true)));
Object params[] = new Object[] { BASE_PARTITION };
p_estimator.getAllPartitions(partitions, catalog_stmt, params, BASE_PARTITION);
assertEquals(1, partitions.size());
assertEquals(BASE_PARTITION, partitions.get());
partitions.clear();
params = new Object[] { BASE_PARTITION+1 };
p_estimator.getAllPartitions(partitions, catalog_stmt, params, BASE_PARTITION);
assertEquals(2, partitions.size());
}
/**
* testConstantRange
*/
public void testConstantRange() throws Exception {
// Check that if we have a query that does a look up on a partitioning column
// using a constant value with a range expression, the it should be sent
// to all partitions in the cluster
Procedure catalog_proc = this.getProcedure("ConstantRange");
Statement catalog_stmt = CollectionUtil.first(catalog_proc.getStatements());
assertNotNull(catalog_stmt);
Object params[] = new Object[] { };
p_estimator.getAllPartitions(partitions, catalog_stmt, params, BASE_PARTITION);
assertEquals(catalogContext.getAllPartitionIds(), partitions);
}
/**
* testMultiAttributePartitioning
*/
public void testMultiAttributePartitioning() throws Exception {
// This checks that the ProcParameters and the StmtParameters get mapped to
// the same partition for a multi-attribute partitioned Procedure+Table
Database clone_db = CatalogCloner.cloneDatabase(catalogContext.database);
CatalogContext clone_catalogContext = new CatalogContext(clone_db.getCatalog());
PartitionEstimator p_estimator = new PartitionEstimator(clone_catalogContext);
// Procedure
Procedure catalog_proc = this.getProcedure(clone_db, paymentByCustomerId.class);
ProcParameter catalog_params[] = new ProcParameter[] {
this.getProcParameter(clone_db, catalog_proc, 1), // D_ID
this.getProcParameter(clone_db, catalog_proc, 0), // W_ID
};
MultiProcParameter mpp = MultiProcParameter.get(catalog_params);
assertNotNull(mpp);
assert(mpp.getIndex() >= 0);
catalog_proc.setPartitionparameter(mpp.getIndex());
// Table
Table catalog_tbl = this.getTable(clone_db, TPCCConstants.TABLENAME_DISTRICT);
String table_key = CatalogKey.createKey(catalog_tbl);
Column catalog_cols[] = new Column[] {
this.getColumn(clone_db, catalog_tbl, "D_ID"),
this.getColumn(clone_db, catalog_tbl, "D_W_ID"),
};
MultiColumn mc = MultiColumn.get(catalog_cols);
assertNotNull(mc);
catalog_tbl.setPartitioncolumn(mc);
p_estimator.initCatalog(clone_catalogContext);
// Procedure Partition
Long proc_params[] = new Long[catalog_proc.getParameters().size()];
proc_params[0] = new Long(NUM_PARTITIONS-1); // W_ID
proc_params[1] = new Long(BASE_PARTITION); // D_ID
int proc_partition = p_estimator.getBasePartition(catalog_proc, proc_params, true);
assert(proc_partition != HStoreConstants.NULL_DEPENDENCY_ID);
assert(proc_partition >= 0);
assert(proc_partition < NUM_PARTITIONS);
// Statement Partition
Statement catalog_stmt = this.getStatement(clone_db, catalog_proc, "getDistrict");
Long stmt_params[] = new Long[] {
new Long(proc_params[0].longValue()), // W_ID
new Long(proc_params[1].longValue()), // D_ID
};
Map<String, PartitionSet> stmt_partitions = p_estimator.getTablePartitions(catalog_stmt, stmt_params, proc_partition);
System.err.println(StringUtil.formatMaps(stmt_partitions));
assertNotNull(stmt_partitions);
assertEquals(1, stmt_partitions.size());
assert(stmt_partitions.containsKey(table_key));
assertEquals(1, stmt_partitions.get(table_key).size());
assertFalse(stmt_partitions.get(table_key).contains(HStoreConstants.NULL_PARTITION_ID));
assertEquals(stmt_partitions.get(table_key).toString(), proc_partition, CollectionUtil.first(stmt_partitions.get(table_key)).intValue());
}
/**
* testMultiProcParameter
*/
public void testMultiProcParameter() throws Exception {
// Try to partition TPC-C's neworder on W_ID and D_ID parameters
Database clone_db = CatalogCloner.cloneDatabase(catalogContext.database);
Procedure catalog_proc = this.getProcedure(clone_db, neworder.class);
CatalogContext clone_catalogContext = new CatalogContext(clone_db.getCatalog());
PartitionEstimator p_estimator = new PartitionEstimator(clone_catalogContext);
ProcParameter catalog_params[] = new ProcParameter[] {
this.getProcParameter(clone_db, catalog_proc, 0), // W_ID
this.getProcParameter(clone_db, catalog_proc, 1), // D_ID
};
MultiProcParameter mpp = MultiProcParameter.get(catalog_params);
assertNotNull(mpp);
assert(mpp.getIndex() >= 0);
catalog_proc.setPartitionparameter(mpp.getIndex());
p_estimator.initCatalog(clone_catalogContext);
// Case #1: Both parameters have values in the input
Long params[] = new Long[catalog_proc.getParameters().size()];
params[0] = new Long(NUM_PARTITIONS-1); // W_ID
params[1] = new Long(BASE_PARTITION); // D_ID
int partition0 = p_estimator.getBasePartition(catalog_proc, params, true);
assert(partition0 != HStoreConstants.NULL_DEPENDENCY_ID);
assert(partition0 >= 0);
// System.err.println("partition0=" + partition0);
assert(partition0 < NUM_PARTITIONS);
// Case #2: The second parameter is null
params = new Long[catalog_proc.getParameters().size()];
params[0] = new Long(NUM_PARTITIONS-1); // W_ID
params[1] = null; // D_ID
int partition1 = p_estimator.getBasePartition(catalog_proc, params, true);
assert(partition1 != HStoreConstants.NULL_DEPENDENCY_ID);
assert(partition1 >= 0);
assert(partition1 < NUM_PARTITIONS);
// System.err.println("partition1=" + partition1);
assertFalse(partition0 == partition1);
// Case #3: The first parameter is null
params = new Long[catalog_proc.getParameters().size()];
params[0] = null; // W_ID
params[1] = new Long(BASE_PARTITION); // D_ID
int partition2 = p_estimator.getBasePartition(catalog_proc, params, true);
assert(partition2 != HStoreConstants.NULL_DEPENDENCY_ID);
assert(partition2 >= 0);
assert(partition2 < NUM_PARTITIONS);
// System.err.println("partition2=" + partition2);
assertNotSame(partition0, partition2);
}
/**
* testMultiColumn
*/
public void testMultiColumn() throws Exception {
// Try to use multi-column partitioning on DISTRICT and see whether we can
// actually get the right answer for neworder.getDistrict
Database clone_db = CatalogCloner.cloneDatabase(catalogContext.database);
CatalogContext clone_catalogContext = new CatalogContext(clone_db.getCatalog());
Table catalog_tbl = this.getTable(clone_db, TPCCConstants.TABLENAME_DISTRICT);
String table_key = CatalogKey.createKey(catalog_tbl);
Column catalog_col0 = this.getColumn(clone_db, catalog_tbl, "D_ID");
Column catalog_col1 = this.getColumn(clone_db, catalog_tbl, "D_W_ID");
MultiColumn mc = MultiColumn.get(catalog_col0, catalog_col1);
catalog_tbl.setPartitioncolumn(mc);
// System.err.println("MUTLI COLUMN: " + mc);
Procedure catalog_proc = this.getProcedure(clone_db, neworder.class);
Statement catalog_stmt = this.getStatement(clone_db, catalog_proc, "getDistrict");
Long params[] = new Long[] {
new Long(BASE_PARTITION), // D_ID
new Long(NUM_PARTITIONS - 1), // D_W_ID
};
PartitionEstimator p_estimator = new PartitionEstimator(clone_catalogContext);
Map<String, PartitionSet> p = p_estimator.getTablePartitions(catalog_stmt, params, BASE_PARTITION);
assertNotNull(p);
// Just check to make sure that we get back exactly one partition
assert(p.containsKey(table_key));
assertEquals("Unexpected result: " + p.get(table_key), 1, p.get(table_key).size());
int stmt_partition = CollectionUtil.first(p.get(table_key));
assert(stmt_partition >= 0) : "Invalid Partition: " + p.get(table_key);
// Now create VoltTable and test that
VoltTable vt = new VoltTable(new ColumnInfo[] {
new ColumnInfo(catalog_col0.getName(), VoltType.get(catalog_col0.getType())), // D_ID
new ColumnInfo(catalog_col1.getName(), VoltType.get(catalog_col1.getType())), // D_W_ID
});
vt.addRow(params[0], params[1]);
VoltTableRow vt_row = vt.fetchRow(0);
int vt_partition = p_estimator.getTableRowPartition(catalog_tbl, vt_row);
assert(vt_partition >= 0) : "Invalid Partition: " + vt_partition;
assertEquals(stmt_partition, vt_partition);
}
/**
* testArrayParameters
*/
public void testArrayParameters() throws Exception {
// Grab TPC-C's neworder and pass an array of W_ID's to getWarehouseTaxRate
// Check that we get back all of the partitions that we expect from the array
Table catalog_tbl = this.getTable(TPCCConstants.TABLENAME_WAREHOUSE);
String table_key = CatalogKey.createKey(catalog_tbl);
Procedure catalog_proc = this.getProcedure(neworder.class);
Statement catalog_stmt = this.getStatement(catalog_proc, "getWarehouseTaxRate");
int num_warehouses = 5;
Long params_object[] = new Long[num_warehouses];
long params_primitive[] = new long[num_warehouses];
PartitionSet expected = new PartitionSet();
for (int i = 0; i < num_warehouses; i++) {
long w_id = NUM_PARTITIONS - i - 1;
params_object[i] = new Long(w_id);
params_primitive[i] = w_id;
expected.add((int)w_id);
} // FOR
assertEquals(params_object.length, expected.size());
assertEquals(params_primitive.length, expected.size());
// System.err.println("EXPECTED: " + expected);
// OBJECT
Map<String, PartitionSet> p = p_estimator.getTablePartitions(catalog_stmt, new Object[]{ params_object }, BASE_PARTITION);
assertNotNull(p);
assert(p.containsKey(table_key));
// System.err.println("OBJECT: " + p.get(table_key));
assertEquals(expected.size(), p.get(table_key).size());
assertEquals(expected, p.get(table_key));
// PRIMITIVE
p = p_estimator.getTablePartitions(catalog_stmt, new Object[]{ params_object }, BASE_PARTITION);
assertNotNull(p);
assert(p.containsKey(table_key));
// System.err.println("PRIMITIVE: " + p.get(table_key));
assertEquals(expected.size(), p.get(table_key).size());
assertEquals(expected, p.get(table_key));
}
/**
* testSelect
*/
public void testSelect() throws Exception {
Procedure catalog_proc = this.getProcedure(neworder.class);
Statement catalog_stmt = this.getStatement(catalog_proc, "getDistrict");
assertNotNull(catalog_stmt);
// System.err.println(CatalogUtil.getDisplayName(this.getTable(TPCCConstants.TABLENAME_DISTRICT).getPartitioncolumn()));
for (int w_id = 1; w_id < NUM_PARTITIONS; w_id++) {
Object params[] = new Integer[]{ 2, w_id }; // d_id, d_w_id
PartitionEstimator estimator = new PartitionEstimator(catalogContext, hasher);
partitions.clear();
estimator.getAllPartitions(partitions, catalog_stmt, params, BASE_PARTITION);
assertEquals(w_id, (int)CollectionUtil.first(partitions));
} // FOR
}
/**
* testGetPartitionsFragments
*/
@Ignore
public void testFragments() throws Exception {
Table catalog_tbl = this.getTable(TPCCConstants.TABLENAME_DISTRICT);
assertNotNull(catalog_tbl);
Procedure catalog_proc = this.getProcedure("neworder");
assertNotNull(catalog_proc);
Statement catalog_stmt = catalog_proc.getStatements().get("getDistrict");
assertNotNull(catalog_stmt);
for (int w_id = 1; w_id < NUM_PARTITIONS; w_id++) {
Object params[] = new Integer[]{ 2, w_id }; // d_id, d_w_id
PartitionEstimator estimator = new PartitionEstimator(catalogContext, hasher);
partitions.clear();
estimator.getAllPartitions(partitions, catalog_stmt, params, BASE_PARTITION);
assertEquals(w_id, (int)CollectionUtil.first(partitions));
} // FOR
}
/**
* testGetPartitionsInsert
*/
public void testInsert() throws Exception {
Table catalog_tbl = this.getTable(TPCCConstants.TABLENAME_ORDERS);
assertNotNull(catalog_tbl);
Procedure catalog_proc = this.getProcedure("neworder");
assertNotNull(catalog_proc);
Statement catalog_stmt = catalog_proc.getStatements().get("createOrder");
assertNotNull(catalog_stmt);
PartitionEstimator estimator = new PartitionEstimator(catalogContext, hasher);
Object params[] = new Object[catalog_stmt.getParameters().size()];
int w_id = 9;
// 3001, 1, 9, 376, Mon Aug 10 00:28:54 EDT 2009, 0, 13, 1]
for (int i = 0; i < params.length; i++) {
StmtParameter catalog_param = catalog_stmt.getParameters().get(i);
VoltType type = VoltType.get((byte)catalog_param.getJavatype());
if (i == 2) {
params[i] = w_id;
} else {
params[i] = VoltTypeUtil.getRandomValue(type);
}
//System.out.print((i != 0 ? ", " : "[") + params[i].toString() + (i + 1 == params.length ? "\n" : ""));
} // FOR
estimator.getAllPartitions(partitions, catalog_stmt, params, BASE_PARTITION);
// System.out.println(catalog_stmt.getName() + " Partitions: " + partitions);
assertFalse(partitions.isEmpty());
assertEquals(1, partitions.size());
assertEquals(w_id, (int)CollectionUtil.first(partitions));
}
/**
* testReplicatedSelect
*/
@Test
public void testReplicatedSelect() throws Exception {
Catalog new_catalog = new Catalog();
new_catalog.execute(catalogContext.catalog.serialize());
CatalogContext new_catalogContext = new CatalogContext(new_catalog);
final Table new_table = new_catalogContext.database.getTables().get(TPCCConstants.TABLENAME_WAREHOUSE);
assertNotNull(new_table);
new_table.setIsreplicated(true);
new_table.setPartitioncolumn(new Column() {
@SuppressWarnings("unchecked")
@Override
public <T extends CatalogType> T getParent() {
return ((T)new_table);
}
});
PartitionEstimator p_estimator = new PartitionEstimator(new_catalogContext, hasher);
Procedure catalog_proc = new_catalogContext.database.getProcedures().get(neworder.class.getSimpleName());
Statement catalog_stmt = catalog_proc.getStatements().get("getWarehouseTaxRate");
assertNotNull(catalog_stmt);
// We should get back exactly one partition id (base_partition)
Object params[] = new Object[] { new Long(1234) };
p_estimator.getAllPartitions(partitions, catalog_stmt, params, BASE_PARTITION);
assertNotNull(partitions);
assertEquals(1, partitions.size());
assertEquals(BASE_PARTITION, CollectionUtil.first(partitions).intValue());
}
/**
* testInvalidateCache
*/
@Test
public void testInvalidateCache() throws Exception {
Catalog new_catalog = new Catalog();
new_catalog.execute(catalogContext.catalog.serialize());
CatalogContext new_catalogContext = new CatalogContext(new_catalog);
final Table new_table = new_catalogContext.database.getTables().get(TPCCConstants.TABLENAME_WAREHOUSE);
assertNotNull(new_table);
new_table.setPartitioncolumn(new Column() {
@SuppressWarnings("unchecked")
@Override
public <T extends CatalogType> T getParent() {
return ((T)new_table);
}
});
PartitionEstimator p_estimator = new PartitionEstimator(catalogContext, hasher);
Procedure catalog_proc = this.getProcedure(neworder.class);
Statement catalog_stmt = catalog_proc.getStatements().get("getWarehouseTaxRate");
assertNotNull(catalog_stmt);
// First calculate the partitions for the query using the original catalog
// We should get back exactly one partition id (base_partition)
Object params[] = new Object[] { new Long(BASE_PARTITION) };
for (int i = 0; i < 10000; i++) {
String debug = String.format("Attempt #%05d", i);
this.partitions.clear();
p_estimator.getAllPartitions(this.partitions, catalog_stmt, params, BASE_PARTITION);
assertEquals(debug + " -> " + this.partitions.toString(), 1, this.partitions.size());
assertEquals(debug, BASE_PARTITION, CollectionUtil.first(this.partitions).intValue());
assertFalse(debug, this.partitions.contains(HStoreConstants.NULL_PARTITION_ID));
} // FOR
// Then reset the catalog in p_estimator and run the estimation again
// The new catalog has a different partition column for WAREHOUSE, so we should get
// back all the partitions
p_estimator.initCatalog(new_catalogContext);
catalog_proc = new_catalogContext.database.getProcedures().get(catalog_proc.getName());
catalog_stmt = catalog_proc.getStatements().get("getWarehouseTaxRate");
partitions.clear();
p_estimator.getAllPartitions(partitions, catalog_stmt, params, BASE_PARTITION);
PartitionSet all_partitions = new_catalogContext.getAllPartitionIds();
assertNotNull(partitions);
assertEquals(all_partitions.size(), partitions.size());
assertFalse(partitions.contains(HStoreConstants.NULL_PARTITION_ID));
}
/**
* testPopulateColumnJoinsAll
*/
@Ignore
public void testPopulateColumnJoinsAll() {
Map<Column, Set<Column>> column_joins = new TreeMap<Column, Set<Column>>();
Table catalog_tbl = this.getTable(TPCCConstants.TABLENAME_DISTRICT);
Column last = null;
List<Column> order = new ArrayList<Column>();
for (Column catalog_col : catalog_tbl.getColumns()) {
column_joins.put(catalog_col, new TreeSet<Column>());
if (last != null) {
column_joins.get(last).add(catalog_col);
column_joins.get(catalog_col).add(last);
}
last = catalog_col;
order.add(catalog_col);
} // FOR
assertNotNull(last);
PartitionEstimator.populateColumnJoinSets(column_joins);
for (Column catalog_col : order) {
assert(column_joins.containsKey(catalog_col));
assertEquals(order.size() - 1, column_joins.get(catalog_col).size());
} // FOR
}
/**
* testPopulateColumnJoinsSplit
*/
@SuppressWarnings("unchecked")
public void testPopulateColumnJoinsSplit() {
Map<Column, Set<Column>> column_joins = new TreeMap<Column, Set<Column>>();
Table catalog_tbl = this.getTable(TPCCConstants.TABLENAME_DISTRICT);
Column last[] = { null, null };
@SuppressWarnings("rawtypes")
HashSet split[] = {
new HashSet<Column>(),
new HashSet<Column>(),
};
int ctr = 0;
for (Column catalog_col : catalog_tbl.getColumns()) {
column_joins.put(catalog_col, new TreeSet<Column>());
int idx = ctr++ % 2;
if (last[idx] != null) {
column_joins.get(last[idx]).add(catalog_col);
column_joins.get(catalog_col).add(last[idx]);
}
last[idx] = catalog_col;
split[idx].add(catalog_col);
} // FOR
assertNotNull(last);
// System.err.println("split[0]: " + split[0]);
// System.err.println("split[1]: " + split[1] + "\n");
PartitionEstimator.populateColumnJoinSets(column_joins);
ctr = 0;
for (Column catalog_col : catalog_tbl.getColumns()) {
assert(column_joins.containsKey(catalog_col));
int idx = ctr++ % 2;
// System.err.println(catalog_col + ": " + column_joins.get(catalog_col));
assertEquals(split[idx].size() - 1, column_joins.get(catalog_col).size());
column_joins.get(catalog_col).add(catalog_col);
assert(column_joins.get(catalog_col).containsAll(split[idx]));
} // FOR
}
/**
* testGetTableRowPartitionNumeric
*/
public void testGetTableRowPartitionNumeric() throws Exception {
Table catalog_tbl = this.getTable(TPCCConstants.TABLENAME_WAREHOUSE);
Column catalog_col = this.getColumn(catalog_tbl, "W_ID");
catalog_tbl.setPartitioncolumn(catalog_col);
PartitionEstimator p_estimator = new PartitionEstimator(catalogContext);
VoltTable vt = CatalogUtil.getVoltTable(catalog_tbl);
int num_rows = 1000;
Map<Long, Integer> expected = new HashMap<Long, Integer>();
for (int i = 0; i < num_rows; i++) {
Object row[] = new Object[catalog_tbl.getColumns().size()];
for (int j = 0; j < row.length; j++) {
Column col = catalog_tbl.getColumns().get(j);
assertNotNull(col);
VoltType vtype = VoltType.get(col.getType());
if (col.equals(catalog_col)) {
long w_id = (i % NUM_PARTITIONS);
row[j] = w_id;
expected.put(w_id, p_estimator.getHasher().hash(w_id));
}
else row[j] = VoltTypeUtil.getRandomValue(vtype);
} // FOR
vt.addRow(row);
} // FOR
assertEquals(num_rows, vt.getRowCount());
vt.resetRowPosition();
while (vt.advanceRow()) {
VoltTableRow row = vt.getRow();
long w_id = row.getLong(catalog_col.getIndex());
int p = p_estimator.getTableRowPartition(catalog_tbl, row);
assert(p >= 0 && p <= NUM_PARTITIONS);
Integer last = expected.get(w_id);
assertNotNull(last);
assertEquals(last.intValue(), p);
} // WHILE
}
/**
* testGetTableRowPartitionString
*/
public void testGetTableRowPartitionString() throws Exception {
Table catalog_tbl = this.getTable(TPCCConstants.TABLENAME_WAREHOUSE);
Column catalog_col = this.getColumn(catalog_tbl, "W_NAME");
catalog_tbl.setPartitioncolumn(catalog_col);
PartitionEstimator p_estimator = new PartitionEstimator(catalogContext);
Map<String, Integer> expected = new HashMap<String, Integer>();
VoltTable vt = CatalogUtil.getVoltTable(catalog_tbl);
int num_rows = 1000;
for (int i = 0; i < num_rows; i++) {
Object row[] = new Object[catalog_tbl.getColumns().size()];
for (int j = 0; j < row.length; j++) {
Column col = catalog_tbl.getColumns().get(j);
assertNotNull(col);
VoltType vtype = VoltType.get(col.getType());
if (col.equals(catalog_col)) {
String name = "WAREHOUSE-" + (i % NUM_PARTITIONS);
row[j] = name;
expected.put(name, p_estimator.getHasher().hash(name));
}
else row[j] = VoltTypeUtil.getRandomValue(vtype);
} // FOR
vt.addRow(row);
} // FOR
assertEquals(num_rows, vt.getRowCount());
vt.resetRowPosition();
while (vt.advanceRow()) {
VoltTableRow row = vt.getRow();
String w_name = row.getString(catalog_col.getIndex());
int name_p = p_estimator.getHasher().hash(w_name);
assert(name_p >= 0 && name_p <= NUM_PARTITIONS);
int row_p = p_estimator.getTableRowPartition(catalog_tbl, row);
assert(row_p >= 0 && row_p <= NUM_PARTITIONS);
assertEquals(w_name, name_p, row_p);
// System.err.println(w_name + " => " + row_p);
Integer last = expected.get(w_name);
assertNotNull(last);
assertEquals(last.intValue(), row_p);
} // WHILE
// System.err.println(StringUtil.formatMaps(expected));
// System.err.println(actual);
}
}