/*******************************************************************************
* Copyright (c) 2004, 2007 IBM Corporation and Cambridge Semantics Incorporated.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* File: $Source: /cvsroot/slrp/glitter/com.ibm.adtech.glitter/src/com/ibm/adtech/glitter/query/planning/SimpleCostModel.java,v $
* Created by: Lee Feigenbaum (<a href="mailto:feigenbl@us.ibm.com">feigenbl@us.ibm.com</a>)
* Created on: 10/23/06
* Revision: $Id: SimpleCostModel.java 164 2007-07-31 14:11:09Z mroy $
*
* Contributors: IBM Corporation - initial API and implementation
* Cambridge Semantics Incorporated - Fork to Anzo
*******************************************************************************/
package org.openanzo.glitter.query.planning;
import org.openanzo.glitter.query.FunctionalPredicate;
import org.openanzo.glitter.query.NodeCostModel;
import org.openanzo.glitter.syntax.abstrakt.BGP;
import org.openanzo.glitter.syntax.abstrakt.Graph;
import org.openanzo.glitter.syntax.abstrakt.Subquery;
import org.openanzo.glitter.syntax.abstrakt.TreeNode;
import org.openanzo.glitter.syntax.abstrakt.TriplePatternNode;
import org.openanzo.rdf.TriplePattern;
import org.openanzo.rdf.TriplePatternComponent;
import org.openanzo.rdf.Variable;
/**
* The SimpleCostModel is a very simple model of costs for a SPARQL query. It penalizes triple patterns with variables and GRAPH clauses with variables. As
* such, it prioritizes ground triple patterns and GRAPH clauses that target specific named graphs. All other node costs simply sum the costs of their children.
*
* The values used are purely arbitrary. TODO - tweak values to get reasonable results.
*
* This simple mode could also be supplemented with base costs for the various node types, such that, e.g., a FILTER might be cheaper (because more selective?)
* than an unfiltered GROUP.
*
* @author Lee
*
*/
class SimpleCostModel implements NodeCostModel {
static private final double TRIPLE_BASE_COST = 1;
static private final double TRIPLE_VARIABLE_COST = 3;
static private final double GRAPH_VARIABLE_PENALTY = 20;
/**
* Default constructor.
*/
public SimpleCostModel() {
}
public double computeCost(TreeNode node) {
if (node == null)
return 0;
FunctionalPredicate fp = null;
if (node instanceof BGP && (fp = ((BGP) node).getFunctionalPredicate()) != null) {
return fp.getCost(this);
} else if (node instanceof TriplePatternNode) {
TriplePattern tp = ((TriplePatternNode) node).getTriplePattern();
int variableCount = 0;
if (tp.getSubject() instanceof Variable)
variableCount++;
if (tp.getPredicate() instanceof Variable)
variableCount++;
if (tp.getObject() instanceof Variable)
variableCount++;
return TRIPLE_BASE_COST + variableCount * TRIPLE_VARIABLE_COST;
} else if (node instanceof Graph) {
TriplePatternComponent context = ((Graph) node).getGraphContext();
double factor = context instanceof Variable ? GRAPH_VARIABLE_PENALTY : 1;
return factor * computeCost(((Graph) node).getGraphPattern());
} else if (node instanceof Subquery) {
return 1 * ((Subquery) node).getBindableVariables().size();
} else {
double cost = 0;
for (TreeNode it : node.getChildren()) {
cost += computeCost(it);
}
return cost;
}
}
}