/** 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 Aug 28, 2015 */ package com.bigdata.rdf.sparql.ast.explainhints; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import com.bigdata.bop.BOp; import com.bigdata.bop.BOpUtility; import com.bigdata.rdf.sparql.ast.ASTBase; import com.bigdata.rdf.sparql.ast.ASTBase.Annotations; import cutthecrap.utils.striterators.Expander; import cutthecrap.utils.striterators.Filter; import cutthecrap.utils.striterators.SingleValueIterator; import cutthecrap.utils.striterators.Striterator; /** * A list of {@link IExplainHint}s, to be attached as an annotation to an * {@link ASTBase} node. See {@link IExplainHint} interface for description * of explain hints. This class is merely a wrapper allowing to add a set * of explain hints to a single node. * * @author <a href="ms@metaphacts.com">Michael Schmidt</a> * @version $Id$ */ public class ExplainHints implements Iterable<IExplainHint> { private final Set<IExplainHint> explainHints; /** * Constructor, setting up an explain hints object containing * a single {@link IExplainHint}. */ public ExplainHints(final IExplainHint explainHint) { explainHints = new HashSet<IExplainHint>(); explainHints.add(explainHint); } /** * Add an explain hint to the set of hints. */ public void addExplainHint(final IExplainHint explainHint) { explainHints.add(explainHint); } /** * Utility function to remove explain hint annotations from a BOp. For * use in test case to ease comparison. Be careful, since this modifies * the argument. * * @param astBase */ public static void removeExplainHintAnnotationsFromBOp(final BOp bop) { final Iterator<BOp> explainHintAnnotatedBOps = ExplainHints.explainHintAnnotatedBOpIterator(bop); // collect explain hint nodesWithExplainHints nodes final List<BOp> nodesWithExplainHints = new ArrayList<BOp>(); while (explainHintAnnotatedBOps.hasNext()) { nodesWithExplainHints.add(explainHintAnnotatedBOps.next()); } for (final BOp nodeWithExplainHint : nodesWithExplainHints) { nodeWithExplainHint.setProperty(Annotations.EXPLAIN_HINTS, null); } } /** * Returns all {@link BOp}s that are annotated with {@link ExplainHints}. * * @param op An operator. * * @return The respective iterator. */ @SuppressWarnings({ "unchecked" }) public static Iterator<BOp> explainHintAnnotatedBOpIterator(final BOp astBase) { return new Striterator( BOpUtility.preOrderIterator(astBase)).addFilter(new Expander() { private static final long serialVersionUID = 1L; @SuppressWarnings("rawtypes") @Override protected Iterator expand(final Object arg0) { final BOp op = (BOp)arg0; // visit the node. final Striterator itr = new Striterator(new SingleValueIterator(op)); // visit the node's operator annotations. final Striterator itr2 = new Striterator( BOpUtility.annotationOpIterator(op)); // expand each operator annotation with a pre-order traversal. itr2.addFilter(new Expander() { private static final long serialVersionUID = 1L; @Override protected Iterator expand(final Object ann) { return explainHintAnnotatedBOpIterator((BOp) ann); } }); // append the pre-order traversal of each annotation. itr.append(itr2); return itr; } }).addFilter(new Filter() { private static final long serialVersionUID = -6488014508516304898L; @Override public boolean isValid(Object obj) { if (obj instanceof BOp) { final BOp bop = (BOp)obj; return bop.getProperty(Annotations.EXPLAIN_HINTS)!=null; } return false; } }); } @Override public String toString() { return explainHints.toString(); } @Override public Iterator<IExplainHint> iterator() { return explainHints.iterator(); } }