Package org.openrdf.query.algebra.evaluation.cursors

Source Code of org.openrdf.query.algebra.evaluation.cursors.LeftJoinCursor

/*
* Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2008.
*
* Licensed under the Aduna BSD-style license.
*/
package org.openrdf.query.algebra.evaluation.cursors;

import java.util.Set;

import org.openrdf.cursor.Cursor;
import org.openrdf.cursor.EmptyCursor;
import org.openrdf.query.BindingSet;
import org.openrdf.query.algebra.LeftJoin;
import org.openrdf.query.algebra.evaluation.EvaluationStrategy;
import org.openrdf.query.algebra.evaluation.QueryBindingSet;
import org.openrdf.query.algebra.evaluation.ValueExprEvaluationException;
import org.openrdf.store.StoreException;

public class LeftJoinCursor implements Cursor<BindingSet> {

  /*-----------*
   * Variables *
   *-----------*/

  private final EvaluationStrategy strategy;

  private final LeftJoin leftJoin;

  /**
   * The set of binding names that are "in scope" for the filter. The filter
   * must not include bindings that are (only) included because of the
   * depth-first evaluation strategy in the evaluation of the constraint.
   */
  private final Set<String> scopeBindingNames;

  private final Cursor<BindingSet> leftCursor;

  private volatile Cursor<BindingSet> rightCursor;

  /*--------------*
   * Constructors *
   *--------------*/

  public LeftJoinCursor(EvaluationStrategy strategy, LeftJoin leftJoin, BindingSet bindings)
    throws StoreException
  {
    this.strategy = strategy;
    this.leftJoin = leftJoin;
    this.scopeBindingNames = leftJoin.getBindingNames();

    this.leftCursor = strategy.evaluate(leftJoin.getLeftArg(), bindings);

    // Initialize with empty cursor so that var is never null
    this.rightCursor = EmptyCursor.getInstance();
  }

  /*---------*
   * Methods *
   *---------*/

  public BindingSet next()
    throws StoreException
  {
    BindingSet leftBindings = null;
    BindingSet rightBindings = rightCursor.next();

    while (rightBindings != null || (leftBindings = leftCursor.next()) != null) {
      if (rightBindings == null) {
        // right cursor exhausted
        rightCursor.close();

        // join with next value from left argument, use left arg's bindings
        // in case the join fails
        rightCursor = strategy.evaluate(leftJoin.getRightArg(), leftBindings);
        rightBindings = rightCursor.next();
      }

      if (leftJoin.hasCondition()) {
        // Find a binding for which the join condition holds
        while (rightBindings != null) {
          // Limit the bindings to the ones that are in scope for this
          // filter
          QueryBindingSet scopeBindings = new QueryBindingSet(rightBindings);
          scopeBindings.retainAll(scopeBindingNames);

          try {
            if (strategy.isTrue(leftJoin.getCondition(), scopeBindings)) {
              return rightBindings;
            }
          }
          catch (ValueExprEvaluationException e) {
            // Ignore, condition not evaluated successfully
          }

          rightBindings = rightCursor.next();
        }
      }
      else if (rightBindings != null) {
        // Found bindings and no join condition specified
        return rightBindings;
      }

      if (leftBindings != null) {
        // Join failed, return left arg's bindings
        return leftBindings;
      }
    }

    return null;
  }

  public void close()
    throws StoreException
  {
    leftCursor.close();
    rightCursor.close();
  }

  @Override
  public String toString() {
    String result = "LeftJoin ";

    if (leftJoin.hasCondition()) {
      result += leftJoin.getCondition().toString().trim();
    }

    result += "\n";
    result += leftCursor.toString();

    result += "\n";
    if (rightCursor instanceof EmptyCursor) {
      result += leftJoin.getRightArg().toString();
    }
    else {
      result += rightCursor.toString();
    }

    return result.replace("\n", "\n\t");
  }
}
TOP

Related Classes of org.openrdf.query.algebra.evaluation.cursors.LeftJoinCursor

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.