Package edu.brown.designer.partitioners.plan

Examples of edu.brown.designer.partitioners.plan.TableEntry


        assertNotNull(pplan);
        assertEquals(catalogContext.getDataTables().size(), pplan.getTableEntries().size());

        for (Table catalog_tbl : pplan.getTableEntries().keySet()) {
            if (catalog_tbl.getSystable()) continue;
            TableEntry pentry = pplan.getTableEntries().get(catalog_tbl);
            assertNotNull("Null PartitionEntry for " + catalog_tbl, pentry);
            Collection<Column> pkey_columns = CatalogUtil.getPrimaryKeyColumns(catalog_tbl);
            PartitionMethodType expected = (pkey_columns.isEmpty() ? PartitionMethodType.REPLICATION : PartitionMethodType.HASH);
            assertEquals("Invalid PartitionMethodType for " + catalog_tbl, expected, pentry.getMethod());
        } // FOR
        System.err.println(pplan);
    }
View Full Code Here


            public int getRowCount() { return (tables.size()); }
            public Object getValueAt(int row, int col) {
                String ret = null;
               
                Table catalog_tbl = tables.get(row);
                TableEntry entry = plan.getTableEntries().get(catalog_tbl);
                switch (col) {
                    case 0:
                        ret = catalog_tbl.getName();
                        break;
                    case 1:
                        ret = entry.getMethod().toString();
                        break;
                    case 2:
                        ret = (entry.getAttribute() != null ? entry.getAttribute().getName() : "-");
                        break;
                    case 3:
                        ret = (entry.getParent() != null ? entry.getParent().getName() : "-");
                        break;
                    case 4:
                        ret = (entry.getParentAttribute() != null ? entry.getParentAttribute().getName() : "-");
                        break;
                } // SWITCH
                return (ret);
            }
            public boolean isCellEditable(int row, int col) {
View Full Code Here

            LOG.debug("Selecting partitioning Column for " + this.info.catalogContext.database.getTables().size() + " Tables");
        double total_memory_used = 0.0;
        boolean calculate_memory = (hints.force_replication_size_limit != null && hints.max_memory_per_partition != 0);
        for (Table catalog_tbl : CatalogUtil.getDataTables(info.catalogContext.database)) {
            String table_key = CatalogKey.createKey(catalog_tbl);
            TableEntry pentry = null;
            Column col = null;
            Collection<Column> pkey_columns = CatalogUtil.getPrimaryKeyColumns(catalog_tbl);

            TableStatistics ts = info.stats.getTableStatistics(catalog_tbl);
            assert (ts != null) : "Null TableStatistics for " + catalog_tbl;
            double size_ratio = (calculate_memory ? (ts.tuple_size_total / (double) hints.max_memory_per_partition) : 0);

            // Replication
            if (hints.force_replication.contains(table_key) || (calculate_memory && ts.readonly && size_ratio <= hints.force_replication_size_limit) || pkey_columns.isEmpty()) {
                total_memory_used += size_ratio;
                if (debug.val)
                    LOG.debug("Choosing " + catalog_tbl.getName() + " for replication");
                col = ReplicatedColumn.get(catalog_tbl);
                pentry = new TableEntry(PartitionMethodType.REPLICATION, col, null, null);

                // Hash Primary Key
            } else {
                total_memory_used += (size_ratio / (double) info.getNumPartitions());

                if (hints.enable_multi_partitioning == false || pkey_columns.size() == 1) {
                    col = CollectionUtil.first(pkey_columns);
                    pentry = new TableEntry(PartitionMethodType.HASH, col, null, null);
                } else {
                    col = MultiColumn.get(pkey_columns.toArray(new Column[0]));
                    pentry = new TableEntry(PartitionMethodType.HASH, col, null, null);
                }
                assert (pentry.attribute != null) : catalog_tbl;
            }
            if (debug.val)
                LOG.debug(String.format("[%02d] %s", pplan.getTableCount(), col.fullName()));
View Full Code Here

                                // System.exit(1);
                                // }
                            }
                        }

                        TableEntry entry = new TableEntry(method, attribute, parent_table, parent_attribute);
                        partition_plan.getTableEntries().put((Table) element.getCatalogItem(), entry);
                        return;
                    }
                }.traverse(root);
            } // FOR roots
            LOG.info(partition_plan);
            partition_plans.put(ptree, partition_plan);
        } // FOR trees

        //
        // Now for each relation, make a tally for the different ways that it
        // could be partitioned
        // This will then be used to generate the final PartitionMapping
        //
        PartitionPlan pplan = new PartitionPlan();
        for (Table catalog_tbl : info.catalogContext.database.getTables()) {
            //
            // For each table, look at the PartitionPlan entries that we created
            // above and see
            // whether it references our table. If it does, then we need to
            // increase our count
            // by one.
            //
            Map<TableEntry, Double> counts = new HashMap<TableEntry, Double>();
            LOG.debug("Counting PartitionPlan entries for " + catalog_tbl);
            for (PartitionTree ptree : partition_plans.keySet()) {
                PartitionPlan partition_plan = partition_plans.get(ptree);
                // System.out.println("Mapping Tables: " + mapping.keySet());
                //
                // We found a partition plan that references our table, so then
                // we need to grab
                // the entry and include it in our count list. Note that the
                // PartitionPlan.Entry
                // object knows how to properly tell whether it has the same
                // attributes as
                // other entry objects, so the count should be properly updated.
                //
                if (partition_plan.getTableEntries().containsKey(catalog_tbl)) {
                    //
                    // Exclude HASH entries without attributes...
                    //
                    TableEntry entry = partition_plan.getTableEntries().get(catalog_tbl);
                    if (entry.getMethod() == PartitionMethodType.HASH && entry.getAttribute() == null) {
                        LOG.warn("Skipping entry for " + catalog_tbl + " because it does not have any partitioning attributes");
                    } else {
                        LOG.debug("Match: " + partition_plan);
                        //
                        // We need to weight this entry by the weight of the
                        // PartitionTree
                        // that it was derived from
                        //
                        double count = ptree.getWeight();
                        if (counts.containsKey(entry))
                            count += counts.get(entry);
                        counts.put(entry, count);
                    }
                } // FOR
            } // FOR

            //
            // If a table was either hashed or mapped on the same attributes,
            // then
            // always go for map
            //
            Iterator<TableEntry> it = counts.keySet().iterator();
            while (it.hasNext()) {
                TableEntry entry0 = it.next();
                if (entry0.getMethod() == PartitionMethodType.MAP)
                    continue;

                boolean remove = false;
                for (TableEntry entry1 : counts.keySet()) {
                    if (entry0 == entry1)
                        continue;
                    if (entry0.getMethod() == PartitionMethodType.HASH && entry1.getMethod() == PartitionMethodType.MAP && entry0.getAttribute().equals(entry1.getAttribute())) {
                        remove = true;
                    }
                } // FOR
                if (remove) {
                    LOG.info("Removing " + entry0 + " because a duplicate entry for a MAP already exists");
                    it.remove();
                    counts.remove(entry0);
                }
            } // WHILE

            //
            // If our counts for the current table is not empty, then we need to
            // need to pick
            // the one with the greatest count
            //
            if (!counts.isEmpty()) {
                for (TableEntry entry : counts.keySet()) {
                    LOG.debug("[" + counts.get(entry) + "]: " + entry);
                } // FOR
                  //
                  // Loop through and pick the entries with the greatest weight
                  // We use a set to warn about multiple entries that could be
                  // picked (which is another decision problem)
                  //
                Set<TableEntry> picked_entries = new HashSet<TableEntry>();
                double max_cnt = 0;
                for (TableEntry entry : counts.keySet()) {
                    double entry_cnt = counts.get(entry);
                    //
                    // If the entry's weight is the same or equal to the current
                    // max weight, then
                    // add it to our list of possible selections. Note that if
                    // it's greater than the
                    // current max weight, then we need to clear our previous
                    // entries
                    //
                    if (entry_cnt >= max_cnt) {
                        if (entry_cnt > max_cnt)
                            picked_entries.clear();
                        picked_entries.add(entry);
                        max_cnt = entry_cnt;
                    }
                } // FOR
                assert (picked_entries.isEmpty() == false);
                if (picked_entries.size() > 1) {
                    LOG.warn("Multiple entries found with the same count for " + catalog_tbl + ". Picking the first one that has a parent");
                    pplan.getTableEntries().put(catalog_tbl, CollectionUtil.first(picked_entries));
                } else {
                    // Just grab the only one and stick it in the PartitionPlan
                    pplan.getTableEntries().put(catalog_tbl, CollectionUtil.first(picked_entries));
                }
                // System.out.println(catalog_tbl + " => " +
                // final_mapping.get(catalog_tbl).toString());
                //
                // This is bad news all around...
                //
            } else {
                LOG.warn("Failed to find any PartitionPlan entries that reference " + catalog_tbl);
            }
        } // FOR tables

        //
        // HACK: Add in any tables we missed as replicated
        //
        for (Table catalog_tbl : info.catalogContext.database.getTables()) {
            if (pplan.getTableEntries().get(catalog_tbl) == null) {
                pplan.getTableEntries().put(catalog_tbl, new TableEntry(PartitionMethodType.REPLICATION, null, null, null));
            }
        } // FOR

        pplan.initializeDependencies();
        return (pplan);
View Full Code Here

                    return;
                }

                @Override
                protected void callback(DesignerVertex element) {
                    TableEntry entry = PartitionPlanTreeGenerator.this.pplan.getTableEntries().get((Table) element.getCatalogItem());
                    // Bad Mojo!
                    if (entry == null) {
                        LOG.warn("ERROR: No PartitionPlan entry for '" + element + "'");
                        // Non-Root
                    } else if (entry.getParent() != null) {
                        LOG.debug("Trying to create: " + entry.getParent() + "->" + element);
                        DesignerVertex parent = info.dgraph.getVertex(entry.getParent());

                        element.setAttribute(ptree, PartitionTree.VertexAttributes.ATTRIBUTE.name(), entry.getAttribute());
                        element.setAttribute(ptree, PartitionTree.VertexAttributes.METHOD.name(), entry.getMethod());

                        if (parent != null && !ptree.containsVertex(element)) {
                            if (!ptree.containsVertex(parent))
                                ptree.addVertex(parent);
                            // System.out.println("FINAL GRAPH: " + parent +
                            // "->" + element);
                            DesignerEdge edge = new DesignerEdge(ptree);
                            ptree.addEdge(edge, parent, element, EdgeType.DIRECTED);
                            element.setAttribute(ptree, PartitionTree.VertexAttributes.PARENT_ATTRIBUTE.name(), entry.getParentAttribute());
                        }
                        // Root
                    } else if (!ptree.containsVertex(element)) {
                        ptree.addVertex(element);
                        element.setAttribute(ptree, PartitionTree.VertexAttributes.ATTRIBUTE.name(), entry.getAttribute());
                        element.setAttribute(ptree, PartitionTree.VertexAttributes.METHOD.name(), entry.getMethod());
                    }
                }
            }.traverse(root);
        } // FOR
        return;
View Full Code Here

            Collection<Column> forced_columns = hints.getForcedTablePartitionCandidates(catalog_tbl);
            TableStatistics ts = info.stats.getTableStatistics(catalog_tbl);
            assert (ts != null) : "Null TableStatistics for " + catalog_tbl;
            double partition_size = (calculate_memory ? (ts.tuple_size_total / (double) info.getNumPartitions()) : 0);
            double partition_ratio = (calculate_memory ? (ts.tuple_size_total / (double) hints.max_memory_per_partition) : 0);
            TableEntry pentry = null;

            if (debug.val) {
                Map<String, Object> m = new ListOrderedMap<String, Object>();
                m.put("Read Only", ts.readonly);
                m.put("Table Size", StringUtil.formatSize(ts.tuple_size_total));
                m.put("Table Partition Size", StringUtil.formatSize((long)partition_size));
                m.put("Table Partition Ratio", String.format("%.02f", partition_ratio));
                m.put("Total Partition Size", String.format("%s / %s", StringUtil.formatSize(total_partitionSize), StringUtil.formatSize(hints.max_memory_per_partition)));
                m.put("Total Partition Ratio", String.format("%.02f", total_partitionRatio));
                LOG.debug(String.format("%s\n%s", catalog_tbl.getName(), StringUtil.formatMaps(m)));
            }

            // -------------------------------
            // Replication
            // -------------------------------
            if (hints.force_replication.contains(table_key) || (calculate_memory && ts.readonly && hints.enable_replication_readonly && partition_ratio <= hints.force_replication_size_limit)) {
                total_partitionRatio += partition_ratio;
                total_partitionSize += ts.tuple_size_total;
                Column catalog_col = ReplicatedColumn.get(catalog_tbl);
                pentry = new TableEntry(PartitionMethodType.REPLICATION, catalog_col);
                if (debug.val)
                    LOG.debug(String.format("Replicating %s at all partitions [%s]", catalog_tbl.getName(), catalog_col.fullName()));

                // -------------------------------
                // Forced Selection
                // -------------------------------
            } else if (forced_columns.isEmpty() == false) {
                // Assume there is only one candidate
                assert (forced_columns.size() == 1) : "Unexpected number of forced columns: " + forced_columns;
                Column catalog_col = CollectionUtil.first(forced_columns);
                pentry = new TableEntry(PartitionMethodType.HASH, catalog_col);
                total_partitionRatio += partition_size / (double) hints.max_memory_per_partition;
                total_partitionSize += partition_size;
                if (debug.val)
                    LOG.debug(String.format("Forcing %s to be partitioned by specific column [%s]", catalog_tbl.getName(), catalog_col.fullName()));

                // -------------------------------
                // Select Most Popular
                // -------------------------------
            } else {
                // If there are no edges, then we'll just randomly pick a column
                // since it doesn't matter
                final Collection<DesignerEdge> edges = agraph.getIncidentEdges(v);
                if (edges.isEmpty())
                    continue;
                if (trace.val)
                    LOG.trace(catalog_tbl + " has " + edges.size() + " edges in AccessGraph");

                ObjectHistogram<Column> column_histogram = null;
                ObjectHistogram<Column> join_column_histogram = new ObjectHistogram<Column>();
                ObjectHistogram<Column> self_column_histogram = new ObjectHistogram<Column>();
                // Map<Column, Double> unsorted = new HashMap<Column, Double>();
                for (DesignerEdge e : edges) {
                    Collection<DesignerVertex> vertices = agraph.getIncidentVertices(e);
                    DesignerVertex v0 = CollectionUtil.get(vertices, 0);
                    DesignerVertex v1 = CollectionUtil.get(vertices, 1);
                    boolean self = (v0.equals(v) && v1.equals(v));
                    column_histogram = (self ? self_column_histogram : join_column_histogram);

                    double edge_weight = e.getTotalWeight();
                    PredicatePairs cset = e.getAttribute(AccessGraph.EdgeAttributes.COLUMNSET);
                    if (trace.val)
                        LOG.trace("Examining ColumnSet for " + e.toString(true));

                    Histogram<Column> cset_histogram = cset.buildHistogramForType(Column.class);
                    Collection<Column> columns = cset_histogram.values();
                    if (trace.val)
                        LOG.trace("Constructed Histogram for " + catalog_tbl + " from ColumnSet:\n"
                                + cset_histogram.setDebugLabels(CatalogUtil.getHistogramLabels(cset_histogram.values())).toString(100, 50));
                    for (Column catalog_col : columns) {
                        if (!catalog_col.getParent().equals(catalog_tbl))
                            continue;
                        if (catalog_col.getNullable())
                            continue;
                        long cnt = cset_histogram.get(catalog_col);
                        if (trace.val)
                            LOG.trace("Found Match: " + catalog_col.fullName() + " [cnt=" + cnt + "]");
                        column_histogram.put(catalog_col, Math.round(cnt * edge_weight));
                    } // FOR
                    // System.err.println(cset.debug());
                    // LOG.info("[" + e.getTotalWeight() + "]: " + cset);
                } // FOR

                // If there were no join columns, then use the self-reference
                // histogram
                column_histogram = (join_column_histogram.isEmpty() ? self_column_histogram : join_column_histogram);
                if (column_histogram.isEmpty()) {
                    EventObserver<DesignerVertex> observer = new EventObserver<DesignerVertex>() {
                        @Override
                        public void update(EventObservable<DesignerVertex> o, DesignerVertex v) {
                            for (DesignerEdge e : agraph.getIncidentEdges(v)) {
                                LOG.info(e.getAttribute(AccessGraph.EdgeAttributes.COLUMNSET));
                            }
                            LOG.info(StringUtil.repeat("-", 100));
                        }
                    };
                    LOG.info("Edges: " + edges);
                    GraphVisualizationPanel.createFrame(agraph, observer).setVisible(true);
                    // ThreadUtil.sleep(10000);
                }

                // We might not find anything if we are calculating the lower
                // bounds using only one transaction
                // if (column_histogram.isEmpty()) {
                // if (trace.val)
                // LOG.trace("Failed to find any ColumnSets for " +
                // catalog_tbl);
                // continue;
                // }
                assert (!column_histogram.isEmpty()) : "Failed to find any ColumnSets for " + catalog_tbl;
                if (trace.val)
                    LOG.trace("Column Histogram:\n" + column_histogram);

                Column catalog_col = CollectionUtil.first(column_histogram.getMaxCountValues());
                pentry = new TableEntry(PartitionMethodType.HASH, catalog_col, null, null);
                total_partitionRatio += partition_size / (double) hints.max_memory_per_partition;
                total_partitionSize += partition_size;

                if (debug.val)
                    LOG.debug(String.format("Selected %s's most popular column for partitioning [%s]", catalog_tbl.getName(), catalog_col.fullName()));
            }
            pplan.table_entries.put(catalog_tbl, pentry);

            if (debug.val)
                LOG.debug(String.format("Current Partition Size: %s", StringUtil.formatSize(total_partitionSize), StringUtil.formatSize(hints.max_memory_per_partition)));
            assert (total_partitionRatio <= 1) : String.format("Too much memory per partition: %s / %s", StringUtil.formatSize(total_partitionSize),
                    StringUtil.formatSize(hints.max_memory_per_partition));
        } // FOR

        for (Table catalog_tbl : info.catalogContext.database.getTables()) {
            if (pplan.getTableEntry(catalog_tbl) == null) {
                Column catalog_col = CollectionUtil.random(catalog_tbl.getColumns());
                assert (catalog_col != null) : "Failed to randomly pick column for " + catalog_tbl;
                pplan.table_entries.put(catalog_tbl, new TableEntry(PartitionMethodType.HASH, catalog_col, null, null));
                if (debug.val)
                    LOG.debug(String.format("No partitioning column selected for %s. Choosing a random attribute [%s]", catalog_tbl, catalog_col.fullName()));
            }
        } // FOR

View Full Code Here

TOP

Related Classes of edu.brown.designer.partitioners.plan.TableEntry

Copyright © 2018 www.massapicom. 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.