/**
Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved.
Contact:
SYSTAP, LLC DBA Blazegraph
2501 Calvert ST NW #106
Washington, DC 20008
licenses@blazegraph.com
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* Created on Sep 1, 2011
*/
package com.bigdata.rdf.sparql.ast.optimizers;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import org.apache.log4j.Logger;
import com.bigdata.bop.BOp;
import com.bigdata.bop.BOpUtility;
import com.bigdata.bop.IBindingSet;
import com.bigdata.bop.engine.StaticAnalysisStats;
import com.bigdata.rdf.sparql.ast.IQueryNode;
import com.bigdata.rdf.sparql.ast.QueryNodeWithBindingSet;
import com.bigdata.rdf.sparql.ast.eval.AST2BOpContext;
/**
* An executable list of query optimizers.
*
* @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a>
*/
public class ASTOptimizerList extends LinkedList<IASTOptimizer> implements
IASTOptimizer {
private static final Logger log = Logger.getLogger(ASTOptimizerList.class);
/**
* True iff the {@link #log} level is INFO or less.
*/
final static private boolean INFO = log.isInfoEnabled();
/**
* True iff the {@link #log} level is DEBUG or less.
*/
final static private boolean DEBUG = log.isDebugEnabled();
/**
*
*/
private static final long serialVersionUID = 1L;
public ASTOptimizerList(final Collection<IASTOptimizer> c) {
super(c);
}
public ASTOptimizerList(final IASTOptimizer... optimizers) {
this(Arrays.asList(optimizers));
}
@Override
public boolean add(final IASTOptimizer opt) {
if(opt == null)
throw new IllegalArgumentException();
if(opt == this)
throw new IllegalArgumentException();
return super.add(opt);
}
/**
* Run all the optimizers in the list.
* <p>
* Note: This makes a deep copy of the AST before applying destructive
* modifications.
*/
@Override
public QueryNodeWithBindingSet optimize(
final AST2BOpContext context, final QueryNodeWithBindingSet input) {
final StaticAnalysisStats saStats = context.getStaticAnalysisStats();
final long startLoop = System.nanoTime();
final IQueryNode queryNode = input.getQueryNode();
final IBindingSet[] bindingSets = input.getBindingSets();
if (DEBUG)
log.debug("Original AST:\n" + queryNode);
// Avoid side-effects on the original AST!
QueryNodeWithBindingSet tmp =
new QueryNodeWithBindingSet(
(IQueryNode) BOpUtility.deepCopy((BOp) queryNode), bindingSets);
for (IASTOptimizer opt : this) {
final long startOpt = System.nanoTime();
if (INFO)
log.info("Applying: " + opt);
tmp = opt.optimize(context, tmp);
if (queryNode == null)
throw new AssertionError("Optimized discarded query: " + opt);
if (DEBUG)
log.debug("Rewritten AST:\n" + tmp.getQueryNode());
saStats.registerOptimizerCall(
opt.getClass().getSimpleName(),
System.nanoTime() - startOpt);
}
saStats.registerOptimizerLoopCall(
System.nanoTime() - startLoop);
return tmp;
}
}