Package edu.brown.utils

Source Code of edu.brown.utils.TestPartitionEstimator

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);
    }
   
}
TOP

Related Classes of edu.brown.utils.TestPartitionEstimator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.