Package edu.brown.designer.partitioners

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

package edu.brown.designer.partitioners;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

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

import edu.brown.designer.AccessGraph;
import edu.brown.designer.DesignerEdge;
import edu.brown.designer.DesignerEdge.Members;
import edu.brown.utils.CollectionUtil;
import edu.brown.utils.PredicatePairs;

public class TablePartitionSets extends HashSet<TablePartitionSets.Entry> {
    private static final long serialVersionUID = 3462969885348478117L;
    private static final Logger LOG = Logger.getLogger(TablePartitionSets.class.getName());

    private final Map<Table, Set<Entry>> table_entry_xref = new HashMap<Table, Set<Entry>>();
    private final Map<PredicatePairs, Entry> cset_entry_xref = new HashMap<PredicatePairs, Entry>();
    private final Table parent_table;

    /**
     * A unique set of attributes that the parent table can be partitioned on
     */
    public class Entry extends HashSet<Column> {
        private static final long serialVersionUID = 8592594865097644058L;

        protected double weight = 0;

        private final Map<Table, Set<PredicatePairs>> table_cset_xref = new HashMap<Table, Set<PredicatePairs>>();
        private final Map<Table, Set<DesignerEdge>> table_edge_xref = new HashMap<Table, Set<DesignerEdge>>();
        private final Map<Table, Collection<Column>> table_partition_xref = new HashMap<Table, Collection<Column>>();

        /**
         * @param other
         */
        public void merge(Entry other) {
            //
            // Find the intersecting entries in order to scrub the ones that
            // don't belong from the ColumnSets of the merging into
            //
            for (CatalogType catalog_item : other) {
                if (!this.contains(catalog_item)) {
                    //
                    // Loop through all the ColumnSets for the tables that
                    // reference this entry
                    // and remove the attribute from them
                    //
                    for (Table catalog_tbl : other.table_cset_xref.keySet()) {
                        for (PredicatePairs cset : other.table_cset_xref.get(catalog_tbl)) {
                            cset.removeAll(cset.findAll(catalog_item));
                        } // FOR
                    } // FOR
                }
            } // FOR

            this.table_cset_xref.putAll(other.table_cset_xref);
            this.table_edge_xref.putAll(other.table_edge_xref);
            this.table_partition_xref.putAll(other.table_partition_xref);
            return;
        }

        /**
         * Return all the tables used in this PartitionSet
         *
         * @return
         */
        public Set<Table> getTables() {
            return (this.table_cset_xref.keySet());
        }

        /**
         * Return the parent table of this Entry object
         *
         * @return
         */
        public Table getParent() {
            return (TablePartitionSets.this.parent_table);
        }

        /**
         * Returns the edge that connects the parent table in the PartitionSets
         * object to the child table provided
         *
         * @param child_table
         * @return
         */
        public DesignerEdge getEdge(Table child_table) {
            DesignerEdge ret = null;
            if (this.table_edge_xref.containsKey(child_table)) {
                ret = CollectionUtil.first(this.table_edge_xref.get(child_table));
            }
            return (ret);
        }

        /**
         * Returns the list of columns that were used to link the child table
         * provided to the parent table based on this AttributeSet
         *
         * @param child_table
         * @return
         */
        public Collection<Column> getChildAttributes(Table child_table) {
            return (this.table_partition_xref.get(child_table));
        }

        /**
         * @return
         */
        public double getWeight() {
            return this.weight;
        }

        /**
         * @param catalog_tbl
         * @return
         */
        public Set<PredicatePairs> getColumnSets(Table catalog_tbl) {
            return (this.table_cset_xref.get(catalog_tbl));
        }

        public String debug() {
            String ret = this.getClass().getSimpleName() + "\n";
            ret += "  Attributes: " + this.toString() + "\n";
            ret += "  Weight:     " + this.getWeight() + "\n";
            ret += "  Tables:     " + this.table_edge_xref.keySet();
            return (ret);
        }
    } // END CLASS

    public TablePartitionSets(Table parent_table) {
        super();
        this.parent_table = parent_table;
    }

    public Table getParentTable() {
        return this.parent_table;
    }

    public boolean add(Table child_table, DesignerEdge edge) {
        //
        // We first need to convert the ColumnSet into a set of attributes
        // that "connect" the child table with the parent
        //
        PredicatePairs cset = null;
        Entry entry = new Entry();
        if (this.parent_table == child_table) {
            cset = (PredicatePairs) edge.getAttribute(AccessGraph.EdgeAttributes.COLUMNSET.name());
            entry.addAll(cset.findAllForParent(Column.class, child_table));
        } else {
            cset = ((PredicatePairs) edge.getAttribute(AccessGraph.EdgeAttributes.COLUMNSET.name())).createPredicatePairsForParent(Column.class, child_table);
            entry.addAll(cset.findAllForOtherParent(Column.class, child_table));
        }
        double weight = (Double) edge.getAttribute(Members.WEIGHTS.name());
        entry.weight = weight;
        // System.out.println(cset + " Weight=" + entry.weight);

        //
        // Check whether we already contain this AttributeSet
        // If we do, then we need to add the weight of the one we're being given
        // to the one that we already have in there
        //
        boolean found = false;
        for (Entry aset : this) {
            if (aset.equals(entry)) {
                found = true;
                aset.weight += weight;
                entry = aset;
                break;
            }
        } // FOR
        if (!found)
            super.add(entry);

        //
        // Build our various index structures. We probably should probably think
        // this through
        // a bit more than just making anything we want here...
        //

        //
        // Table -> ColumnSets
        //
        if (!entry.table_cset_xref.containsKey(child_table)) {
            entry.table_cset_xref.put(child_table, new HashSet<PredicatePairs>());
        }
        entry.table_cset_xref.get(child_table).add(cset);

        //
        // Table -> Entry
        //
        if (!this.table_entry_xref.containsKey(child_table)) {
            this.table_entry_xref.put(child_table, new HashSet<Entry>());
        }
        this.table_entry_xref.get(child_table).add(entry);

        //
        // ColumnSet -> AttributeSet
        //
        this.cset_entry_xref.put(cset, entry);

        //
        // Child Table -> Edges
        //
        if (!entry.table_edge_xref.containsKey(child_table)) {
            entry.table_edge_xref.put(child_table, new HashSet<DesignerEdge>());
        }
        entry.table_edge_xref.get(child_table).add(edge);

        //
        // Child Table -> Attributes
        //
        if (entry.table_partition_xref.containsKey(child_table)) {
            LOG.fatal("The AttributeSet for parent table '" + this.parent_table + "' " + "already contains attributes for child table '" + child_table + "'");
            return (false);
        }
        entry.table_partition_xref.put(child_table, cset.findAllForOtherParent(Column.class, this.parent_table));

        return (true);
    }

    public Set<Entry> getMaxWeightAttributes() {
        Set<Entry> ret = new HashSet<Entry>();
        double max_weight = 0;
        for (Entry aset : this) {
            if (aset.weight == max_weight) {
                ret.add(aset);
            } else if (aset.weight > max_weight) {
                ret.clear();
                ret.add(aset);
                max_weight = aset.weight;
            }
        } // FOR
        return (ret);
    }

    /**
     * @throws Exception
     */
    public void generateSubSets() throws Exception {
        //
        // Simple hack for now
        //
        LOG.info("Trying to generate entry subsets");
        System.out.println(this.debug());
        Set<Entry> remove = new HashSet<Entry>();
        for (Entry entry0 : this) {
            for (Entry entry1 : this) {
                if (entry0 == entry1)
                    continue;
                if (entry0.containsAll(entry1) && entry0.size() > entry1.size()) {
                    LOG.info("Merging " + entry0 + " into " + entry1);
                    entry1.merge(entry0);
                    remove.add(entry0);
                    break;
                } else {
                    LOG.debug("entry0: [" + entry0.size() + "] " + entry0);
                    LOG.debug("entry1: [" + entry1.size() + "] " + entry1);
                    LOG.debug("entry0.containsAll(entry1): " + entry0.containsAll(entry1));
                    LOG.debug("entry1.containsAll(entry0): " + entry1.containsAll(entry0));
                }
            } // FOR
            if (!remove.isEmpty())
                break;
        } // FOR
        if (!remove.isEmpty()) {
            this.removeAll(remove);
            LOG.debug(this.debug());
        } else {
            LOG.warn("Failed to find any entries to merge!");
            // if (this.parent_table.getName().equals("CUSTOMER"))
            // System.exit(1);
        }

        return;
    }

    public String debug() {
        String ret = this.getClass().getSimpleName() + ": " + this.parent_table + "\n";
        for (Entry entry : this) {
            ret += entry.debug() + "\n";
        }
        return (ret);
    }

}
TOP

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

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.