Package edu.brown.designer.partitioners

Source Code of edu.brown.designer.partitioners.RandomPartitioner

/**
*
*/
package edu.brown.designer.partitioners;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.apache.log4j.Logger;
import org.voltdb.catalog.CatalogType;
import org.voltdb.catalog.Column;
import org.voltdb.catalog.ProcParameter;
import org.voltdb.catalog.Procedure;
import org.voltdb.catalog.Table;

import edu.brown.catalog.special.NullProcParameter;
import edu.brown.catalog.special.ReplicatedColumn;
import edu.brown.designer.AccessGraph;
import edu.brown.designer.Designer;
import edu.brown.designer.DesignerHints;
import edu.brown.designer.DesignerInfo;
import edu.brown.designer.partitioners.plan.PartitionPlan;
import edu.brown.statistics.TableStatistics;
import edu.brown.utils.CollectionUtil;

/**
* @author pavlo
*/
public class RandomPartitioner extends AbstractPartitioner {
    protected static final Logger LOG = Logger.getLogger(RandomPartitioner.class);

    private final Random rand = new Random(0);
    private boolean limit_columns = true;

    /**
     * Full Constructor
     *
     * @param designer
     * @param info
     * @param limit_columns
     */
    public RandomPartitioner(Designer designer, DesignerInfo info, boolean limit_columns) {
        super(designer, info);
        this.setLimitedColumns(limit_columns);
    }

    /**
     * @param designer
     * @param info
     */
    public RandomPartitioner(Designer designer, DesignerInfo info) {
        this(designer, info, true);
    }

    public void setLimitedColumns(boolean flag) {
        LOG.debug("Limit Column Selection: " + (flag ? "ENABLED" : "DISABLED"));
        this.limit_columns = flag;
    }

    /*
     * (non-Javadoc)
     * @see
     * edu.brown.designer.partitioners.AbstractPartitioner#generate(edu.brown
     * .designer.DesignerHints)
     */
    @Override
    public PartitionPlan generate(DesignerHints hints) throws Exception {
        Map<CatalogType, CatalogType> pplan_map = new HashMap<CatalogType, CatalogType>();

        // Do we need to worry about memory?
        boolean calculate_memory = (hints.force_replication_size_limit != null && hints.max_memory_per_partition != 0);

        // Generate the list of which columns we will randomly select from for
        // each table
        Map<Table, List<Column>> table_columns = new HashMap<Table, List<Column>>();
        AccessGraph agraph = (this.limit_columns ? this.generateAccessGraph() : null);
        for (Table catalog_tbl : info.catalogContext.database.getTables()) {
            List<Column> columns = new ArrayList<Column>();
            if (this.limit_columns) {
                List<Column> column_keys = PartitionerUtil.generateColumnOrder(info, agraph, catalog_tbl, hints, true, false);
                assert (!column_keys.isEmpty()) : "No potential partitioning columns selected for " + catalog_tbl;
                columns.addAll(column_keys);
            } else {
                CollectionUtil.addAll(columns, catalog_tbl.getColumns());
            }
            table_columns.put(catalog_tbl, columns);
        } // FOR

        // TABLES
        final int rounds = 10;
        int round = rounds;
        while (round >= (-1 * rounds)) {
            double total_memory = 0d;

            for (Table catalog_tbl : info.catalogContext.database.getTables()) {
                TableStatistics ts = info.stats.getTableStatistics(catalog_tbl);
                assert (ts != null);
                List<Column> columns = table_columns.get(catalog_tbl);
                assert (columns != null);
                int size = columns.size();

                // The way this works is that on each interation the value of
                // 'round' is
                // decreasing. This means that selecting a table replication
                // decreases every round
                // until it's at the point where we won't select replication at
                // all
                int idx = this.rand.nextInt((size * rounds) + (round < 0 ? 0 : round)) / rounds;

                Column catalog_col = null;
                if (idx == size) {
                    catalog_col = ReplicatedColumn.get(catalog_tbl);
                    if (calculate_memory)
                        total_memory += ts.tuple_size_total;
                } else {
                    catalog_col = columns.get(idx);
                    if (calculate_memory)
                        total_memory += ts.tuple_size_total / info.getNumPartitions();
                }
                pplan_map.put(catalog_tbl, catalog_col);
            } // FOR
            total_memory = total_memory / (double) hints.max_memory_per_partition;

            // If we're not over our memory limit, then quit here
            if (total_memory <= 1.0)
                break;
            LOG.debug("[" + round + "] TotalMemory=" + total_memory);

            // Otherwise make it so that we are less likely to select the
            // partitioning attribute
            // the next go around
            round--;
        } // WHILE

        // PROCEDURES
        for (Procedure catalog_proc : info.catalogContext.database.getProcedures()) {
            if (catalog_proc.getSystemproc())
                continue;
            int size = catalog_proc.getParameters().size();

            ProcParameter catalog_param = NullProcParameter.singleton(catalog_proc);
            if (size > 0) {
                int idx = this.rand.nextInt(size);
                catalog_param = catalog_proc.getParameters().get(idx);
            }
            pplan_map.put(catalog_proc, catalog_param);
        } // FOR

        return (PartitionPlan.createFromMap(pplan_map));
    }

}
TOP

Related Classes of edu.brown.designer.partitioners.RandomPartitioner

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.