* (non-Javadoc)
* @see edu.brown.designer.indexselectors.AbstractIndexSelector#generate()
*/
@Override
public IndexPlan generate(PartitionPlan plan) throws Exception {
IndexPlan indexPlan = new IndexPlan(info.catalogContext.database);
//
// Go through and count up all the attribute sets that aren't used for
// partitioning
//
PartitionTree ptree = null; // FIXME designer.getPartitionTree();
for (Procedure catalog_proc : info.catalogContext.database.getProcedures()) {
AccessGraph agraph = designer.getAccessGraph(catalog_proc);
if (agraph == null)
continue;
for (DesignerEdge edge : agraph.getEdges()) {
ArrayList<DesignerVertex> vertices = new ArrayList<DesignerVertex>();
vertices.addAll(agraph.getIncidentVertices(edge));
// FIXME
if (true || !(ptree.getPath(vertices.get(0), vertices.get(1)).isEmpty() && ptree.getPath(vertices.get(1), vertices.get(0)).isEmpty())) {
PredicatePairs cset = (PredicatePairs) (edge.getAttribute(AccessGraph.EdgeAttributes.COLUMNSET.name()));
for (DesignerVertex vertex : vertices) {
Table catalog_tbl = vertex.getCatalogItem();
Collection<Column> edge_columns = cset.findAllForParent(Column.class, catalog_tbl);
//
// Exclusion: Check whether this table is already
// partitioned on these columns
//
PartitionEntry pentry = plan.getTableEntries().get(catalog_tbl);
if (pentry == null) {
LOG.warn("PartitionEntry is null for " + catalog_tbl);
continue;
// } else if (pentry.getMethod() !=
// PartitionMethodType.REPLICATION &&
// pentry.getAttributes().equals(edge_columns)) {
// LOG.info(catalog_tbl +
// " is already partitioned on " + edge_columns +
// ". Skipping...");
// continue;
}
//
// Exclusion: Check whether this is the table's primary
// key
//
Collection<Column> pkeys = CatalogUtil.getPrimaryKeyColumns(catalog_tbl);
if (pkeys.containsAll(edge_columns) && edge_columns.containsAll(pkeys)) {
LOG.info(catalog_tbl + "'s primary key already contains " + edge_columns + ". Skipping...");
continue;
}
//
// Exclusion: These columns are only used in INSERTS
//
Map<QueryType, Integer> query_counts = cset.getQueryCounts();
if (query_counts.get(QueryType.SELECT) == 0 && query_counts.get(QueryType.UPDATE) == 0 && query_counts.get(QueryType.DELETE) == 0) {
LOG.info("The columns " + edge_columns + " are only used in INSERT operations on " + catalog_tbl + ". Skipping...");
continue;
}
//
// Check whether we already have a candidate index for
// this set of columns
//
IndexPlan.Entry found = null;
for (IndexPlan.Entry index : indexPlan.get(catalog_tbl)) {
if (index.getColumns().containsAll(edge_columns) && edge_columns.containsAll(index.getColumns())) {
found = index;
break;
}
} // FOR
//
// We have a match, so we need to add this edge's weight
// to it
//
Double weight = (Double) edge.getAttribute(Members.WEIGHTS.name());
if (found != null) {
weight += found.getWeight();
} else {
found = indexPlan.new Entry(catalog_tbl);
found.getColumns().addAll(edge_columns);
}
found.setWeight(weight);
found.getProcedures().add(catalog_proc);
indexPlan.get(catalog_tbl).add(found);
} // FOR
} // IF
} // FOR
} // FOR
//
// We now need to consolidate overlapping indexes for each table if they
// are
// used in the same procedure
//
for (Table catalog_tbl : indexPlan.keySet()) {
Iterator<IndexPlan.Entry> it0 = indexPlan.get(catalog_tbl).iterator();
while (it0.hasNext()) {
IndexPlan.Entry index0 = it0.next();
//
// Look for another index that has all our columns
//
for (IndexPlan.Entry index1 : indexPlan.get(catalog_tbl)) {
if (index0 == index1)
continue;
if (index1.getColumns().containsAll(index0.getColumns())
&& (index1.getProcedures().containsAll(index0.getProcedures()) || index0.getProcedures().containsAll(index1.getProcedures()))) {
//