Package lupos.engine.operators.singleinput

Source Code of lupos.engine.operators.singleinput.AddComputedBinding

/**
* Copyright (c) 2013, Institute of Information Systems (Sven Groppe and contributors of LUPOSDATE), University of Luebeck
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
* following conditions are met:
*
*   - Redistributions of source code must retain the above copyright notice, this list of conditions and the following
*     disclaimer.
*   - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
*     following disclaimer in the documentation and/or other materials provided with the distribution.
*   - Neither the name of the University of Luebeck nor the names of its contributors may be used to endorse or promote
*     products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package lupos.engine.operators.singleinput;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import lupos.datastructures.bindings.Bindings;
import lupos.datastructures.bindings.BindingsFactory;
import lupos.datastructures.items.Variable;
import lupos.datastructures.queryresult.QueryResult;
import lupos.datastructures.queryresult.QueryResultDebug;
import lupos.engine.operators.Operator;
import lupos.engine.operators.OperatorIDTuple;
import lupos.engine.operators.messages.BindingsFactoryMessage;
import lupos.engine.operators.messages.BoundVariablesMessage;
import lupos.engine.operators.messages.ComputeIntermediateResultMessage;
import lupos.engine.operators.messages.EndOfEvaluationMessage;
import lupos.engine.operators.messages.Message;
import lupos.engine.operators.singleinput.filter.Filter;
import lupos.engine.operators.singleinput.filter.expressionevaluation.Helper;
import lupos.misc.debug.DebugStep;
import lupos.misc.util.ImmutableIterator;
import lupos.sparql1_1.ASTAggregation;
import lupos.sparql1_1.Node;

public class AddComputedBinding extends SingleInputOperator {

  /**
   *
   */
  private static final long serialVersionUID = -7826058701554340200L;

  public final Map<Variable, Filter> projections = new HashMap<Variable, Filter>();
  protected QueryResult queryResult = null;
  private boolean pipelineBreaker = false;

  private BindingsFactory bindingsFactory = null;

  public void addProjectionElement(final Variable var, final Node constraint) {
    final Filter filter = new Filter(constraint);
    this.projections.put(var, filter);
    if (filter.isPipelineBreaker()) {
      this.pipelineBreaker = true;
    }
  }

  @Override
  public Message preProcessMessage(final BoundVariablesMessage msg) {
    for (final Map.Entry<Variable, Filter> entry : this.projections.entrySet()) {
      msg.getVariables().add(entry.getKey());
    }
    this.intersectionVariables = new LinkedList<Variable>();
    this.intersectionVariables.addAll(msg.getVariables());
    this.unionVariables = new LinkedList<Variable>();
    this.unionVariables.addAll(this.intersectionVariables);
    return msg;
  }

  @Override
  public QueryResult process(final QueryResult bindings, final int operandID) {
    boolean aggregationFunctions = false;
    for (final Filter filter : this.projections.values()) {
      if (filter.isPipelineBreaker()) {
        aggregationFunctions = true;
        break;
      }
    }
    if (!aggregationFunctions) {
      final Iterator<Bindings> resultIterator = new ImmutableIterator<Bindings>() {
        final Iterator<Bindings> bindIt = bindings.oneTimeIterator();
        Bindings next = this.computeNext();

        @Override
        public boolean hasNext() {
          return (this.next != null);
        }

        @Override
        public Bindings next() {
          final Bindings zNext = this.next;
          this.next = this.computeNext();
          return zNext;
        }

        private Bindings computeNext() {
          while (this.bindIt.hasNext()) {
            final Bindings bind = this.bindIt.next();
            try {
              if (bind != null) {
                for (final Map.Entry<Variable, Filter> entry: AddComputedBinding.this.projections.entrySet()) {
                  bind.add(entry.getKey(), Helper
                      .getLiteral(Filter.staticEvalTree(
                          bind, entry.getValue()
                              .getNodePointer(),
                          null)));
                }
                return bind;
              }
            } catch (final NotBoundException nbe) {
              return bind;
            } catch (final TypeErrorException tee) {
              return bind;
            }
          }
          return null;
        }
      };

      if (resultIterator.hasNext()) {
        return QueryResult.createInstance(resultIterator);
      } else {
        return null;
      }
    } else {
      if (this.queryResult == null) {
        bindings.materialize();
        this.queryResult = bindings;
      } else {
        this.queryResult.addAll(bindings);
      }
      return null;
    }
  }

  protected QueryResult getQueryResultForAggregatedFilter(QueryResult queryResultParameter) {
    if(queryResultParameter==null){
      queryResultParameter = QueryResult.createInstance();
    }
    final List<HashMap<lupos.sparql1_1.Node, Object>> resultsOfAggregationFunctionsList = new LinkedList<HashMap<lupos.sparql1_1.Node, Object>>();
    for (final Map.Entry<Variable, Filter> entry: this.projections.entrySet()) {
      final HashMap<lupos.sparql1_1.Node, Object> resultsOfAggregationFunctions = new HashMap<lupos.sparql1_1.Node, Object>();
      Filter.computeAggregationFunctions(queryResultParameter, entry.getValue().aggregationFunctions, resultsOfAggregationFunctions, entry.getValue().getUsedEvaluationVisitor());
      resultsOfAggregationFunctionsList.add(resultsOfAggregationFunctions);
    }
    if(queryResultParameter.isEmpty()){
      // workaround: count = 0 should occur in the result for an empty query result as input...
      for(final HashMap<lupos.sparql1_1.Node, Object> entry: resultsOfAggregationFunctionsList){
        boolean breakFor=false;
        for(final lupos.sparql1_1.Node node: entry.keySet()){
          if(node instanceof ASTAggregation){
            if(((ASTAggregation)node).getTYPE()==ASTAggregation.TYPE.COUNT){
              queryResultParameter.add(this.bindingsFactory.createInstance());
              breakFor=true;
              break;
            }
          }
        }
        if(breakFor){
          break;
        }
      }
    }
    final QueryResult finalQueryResult = queryResultParameter;
    final Iterator<Bindings> resultIterator = new ImmutableIterator<Bindings>() {
      final Iterator<Bindings> bindIt = finalQueryResult.oneTimeIterator();

      Bindings next = this.computeNext();

      @Override
      public boolean hasNext() {
        return (this.next != null);
      }

      @Override
      public Bindings next() {
        final Bindings zNext = this.next;
        this.next = this.computeNext();
        return zNext;
      }

      private Bindings computeNext() {
        while (this.bindIt.hasNext()) {
          final Bindings bind = this.bindIt.next();
          try {
            if (bind != null) {
              final Bindings bindNew = bind.clone();
              final Iterator<HashMap<lupos.sparql1_1.Node, Object>> resultsOfAggregationFunctionsIterator = resultsOfAggregationFunctionsList.iterator();
              for (final Map.Entry<Variable, Filter> entry: AddComputedBinding.this.projections
                  .entrySet()) {
                final HashMap<lupos.sparql1_1.Node, Object> resultsOfAggregationFunctions = resultsOfAggregationFunctionsIterator.next();
                bindNew.add(entry.getKey(),
                    Helper.getLiteral(Filter.staticEvalTree(
                        bind,
                        entry.getValue().getNodePointer(),
                        resultsOfAggregationFunctions, entry.getValue().getUsedEvaluationVisitor())));
              }
              return bindNew;
            }
          } catch (final NotBoundException nbe) {
            return bind;
          } catch (final TypeErrorException tee) {
            return bind;
          }
        }
        return null;
      }
    };

    if (resultIterator.hasNext()) {
      return QueryResult.createInstance(resultIterator);
    }

    return null;
  }

  @Override
  public Message preProcessMessage(final EndOfEvaluationMessage msg) {
    final QueryResult qr = this.getQueryResultForAggregatedFilter(this.queryResult);
    if (qr != null) {
      if (this.succeedingOperators.size() > 1) {
        qr.materialize();
      }
      for (final OperatorIDTuple opId: this.succeedingOperators) {
        opId.processAll(qr);
      }
    }
    return msg;
  }

  @Override
  public Message preProcessMessage(final BindingsFactoryMessage msg) {
    this.bindingsFactory  = msg.getBindingsFactory();
    return msg;
  }


  @Override
  public Message preProcessMessage(final ComputeIntermediateResultMessage msg) {
    this.deleteAllAtSucceedingOperators();
    this.preProcessMessage(new EndOfEvaluationMessage());
    return msg;
  }

  @Override
  public QueryResult deleteQueryResult(final QueryResult queryResultToDelete, final int operandID) {
    if (this.queryResult != null) {
      this.queryResult.removeAll(queryResultToDelete);
    }
    return queryResultToDelete;
  }

  @Override
  public void deleteQueryResult(final int operandID) {
    if (this.queryResult != null) {
      this.queryResult.release();
    }
    this.queryResult = null;
  }

  @Override
  public String toString() {
    String s = super.toString();
    boolean comma = false;
    for (final Map.Entry<Variable, Filter> entry: this.projections.entrySet()) {
      if (comma) {
        s += ",";
      }
      comma = true;
      s += " " + entry.getKey() + "=" + entry.getValue().toString();
    }
    return s;
  }

  @Override
  public String toString(final lupos.rdf.Prefix prefixInstance) {
    String s = super.toString();
    boolean comma = false;
    for (final Map.Entry<Variable, Filter> entry: this.projections.entrySet()) {
      if (comma) {
        s += ",";
      }
      comma = true;
      s += " " + entry.getKey() + "="
          + entry.getValue().toString(prefixInstance);
    }
    return s;
  }

  public Map<Variable, Filter> getProjections() {
    return this.projections;
  }

  @Override
  public boolean isPipelineBreaker() {
    return this.pipelineBreaker;
  }

  @Override
  public Message preProcessMessageDebug(
      final ComputeIntermediateResultMessage msg,
      final DebugStep debugstep) {
    this.deleteAllDebugAtSucceedingOperators(debugstep);
    this.preProcessMessageDebug(new EndOfEvaluationMessage(), debugstep);
    return msg;
  }

  @Override
  public Message preProcessMessageDebug(final EndOfEvaluationMessage msg,
      final DebugStep debugstep) {
    final QueryResult qr = this.getQueryResultForAggregatedFilter(this.queryResult);
    if (qr != null) {
      if (this.succeedingOperators.size() > 1) {
        qr.materialize();
      }
      for (final OperatorIDTuple opId : this.succeedingOperators) {
        final QueryResultDebug qrDebug = new QueryResultDebug(qr,
            debugstep, this, opId.getOperator(), true);
        ((Operator) opId.getOperator()).processAllDebug(qrDebug, opId
            .getId(), debugstep);
      }
    }
    return msg;
  }
}
TOP

Related Classes of lupos.engine.operators.singleinput.AddComputedBinding

TOP
Copyright © 2018 www.massapi.com. 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.