Package lupos.engine.operators.multiinput.join

Source Code of lupos.engine.operators.multiinput.join.Join

/**
* 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.multiinput.join;

import java.util.Iterator;

import lupos.datastructures.bindings.Bindings;
import lupos.datastructures.items.Variable;
import lupos.datastructures.items.literal.Literal;
import lupos.datastructures.queryresult.QueryResult;
import lupos.engine.operators.BasicOperator;
import lupos.engine.operators.multiinput.MultiInputOperator;
import lupos.engine.operators.multiinput.optional.Optional;
import lupos.engine.operators.multiinput.optional.OptionalResult;

public class Join extends MultiInputOperator {

  protected double estimatedCardinality = -1.0;
  protected int realCardinality = -1;

  public Join() {
    // no initializations...
  }

  public double getEstimatedCardinality() {
    return this.estimatedCardinality;
  }

  public void setEstimatedCardinality(final double estimatedCardinality) {
    this.estimatedCardinality = estimatedCardinality;
  }

  public int getRealCardinality() {
    return this.realCardinality;
  }

  public void setRealCardinality(final int realCardinality) {
    this.realCardinality = realCardinality;
  }

  /**
   * Adds all bindings of the second bindings object to the first one and
   * returns a new query result object which contains the updated first
   * bindings object.<br>
   * If the second bindings object contains a binding which conflicts with a
   * binding of the first bindings object, <code>null</code> will be returned
   * to indicate this (unsolvable) conflict<br>
   * <br>
   * Note that the first bindings object is first bindings object provided is
   * actually altered if additional bindings were found in the second bindings
   * object.
   *
   * @param bindings1
   *            the first bindings object
   * @param bindings2
   *            the second bindings object
   * @return a query result object which contains the combination of bindings
   *         or <code>null</code> if an unsolvable conflict was detected
   */
  public static QueryResult joinBindings(final Bindings bindings1,
      final Bindings bindings2) {

    // create a new instance of a query result object to take up
    // the combination of the two bindings object
    final QueryResult qResult = QueryResult.createInstance();

    // if the bindings can be combined (they contain no conflicting
    // bindings) return the new query result object. Otherwise
    // return null
    return (joinBindings(qResult, bindings1, bindings2)) ? qResult : null;
    /*
     * // only the keys of the second bindings object have to be // checked
     * since the the first bindings object is updated for (final String
     * b2key : bindings2.getKeySet()) { final Literal literalB2 =
     * bindings2.get(b2key); final Literal literalB1 = bindings1.get(b2key);
     *
     * // if the literal computed from the second bindings conflicts with //
     * the corresponding one located in the first bindings object, // null
     * is returned to indicate an unsolvable conflict if ( (literalB1 !=
     * null) && !literalB1.valueEquals(literalB2) ){ return null; }
     *
     * // otherwise add the new binding of the key and literal to // the
     * first bindings object bindings1.add(b2key, literalB2); }
     *
     * // return a new instance of a query result which contains the // the
     * combination of bindings from the first and the second // bindings
     * object final QueryResult result=QueryResult.createInstance();
     * result.add(bindings1); return result;
     */
  }

  /**
   * Combines the bindings of two bindings objects and adds them to a query
   * result object if no conflicting bindings were found. If the second
   * bindings object contains a binding which conflicts with a binding of the
   * first bindings object, <code>false</code> will be returned to indicate
   * this (unsolvable) conflict<br>
   * <br>
   * Note that the first bindings object provided is actually altered if
   * additional bindings were found in the second bindings object.
   *
   * @param result
   *            the query result object which is to be updated
   * @param bindings1
   *            the first bindings object
   * @param bindings2
   *            the second bindings object
   * @return <code>false</code> if an unsolvable conflict was detected,
   *         <code>true</code> otherwise
   */
  public static boolean joinBindings(final QueryResult result,
      final Bindings bindings1, final Bindings bindings2) {

    // only the keys of the second bindings object have to be
    // checked since the the first bindings object is updated
    for (final Variable b2key : bindings2.getVariableSet()) {

      final Literal literalB2 = bindings2.get(b2key);
      final Literal literalB1 = bindings1.get(b2key);

      // if the literal computed from the second bindings conflicts with
      // the corresponding one located in the first bindings object,
      // null is returned to indicate an unsolvable conflict
      if (literalB1 != null) {
        if (!literalB1.valueEquals(literalB2)) {
          return false;
        }
      }

      // otherwise add the new binding of the key and literal to
      // the first bindings object
      else {
        bindings1.add(b2key, literalB2);
      }

    }

    // return a new instance of a query result which contains the
    // the combination of bindings from the first and the second
    // bindings object
    // final QueryResult result=QueryResult.createInstance();
    bindings1.addAllTriples(bindings2);
    bindings1.addAllPresortingNumbers(bindings2);
    result.add(bindings1);
    return true;
  }

  public static Bindings joinBindingsAndReturnBindings(final Bindings bindings1, final Bindings bindings2) {

    // only the keys of the second bindings object have to be
    // checked since the the first bindings object is updated
    for (final Variable b2key : bindings2.getVariableSet()) {

      final Literal literalB2 = bindings2.get(b2key);
      final Literal literalB1 = bindings1.get(b2key);

      // if the literal computed from the second bindings conflicts with
      // the corresponding one located in the first bindings object,
      // null is returned to indicate an unsolvable conflict
      if (literalB1 != null) {
        if (!literalB1.valueEquals(literalB2)) {
          return null;
        }
      }

      // otherwise add the new binding of the key and literal to
      // the first bindings object
      else {
        bindings1.add(b2key, literalB2);
      }

    }

    bindings1.addAllTriples(bindings2);
    bindings1.addAllPresortingNumbers(bindings2);
    return bindings1;
  }
 
  public static boolean joinBindings_tmp(final QueryResult result,
      final Bindings bindings1, final Bindings bindings2) {

    for (final Variable b2key : bindings2.getVariableSet()) {
      bindings1.add(b2key, bindings2.get(b2key));
    }

    bindings1.addAllTriples(bindings2);
    bindings1.addAllPresortingNumbers(bindings2);
    result.add(bindings1);
    return true;
  }

  /*
   * public static QueryResult joinBindings(final QueryResult bindings) {
   * final Bindings b=Bindings.createNewInstance(); final Iterator<Bindings>
   * ib=bindings.iterator(); while(ib.hasNext()) { final Bindings c=ib.next();
   * final Iterator<String> keys=c.getKeys(); while(keys.hasNext()) { final
   * String k=keys.next(); final Literal value=c.get(k);
   *
   * // join of (k, value) with the rest... final Iterator<Bindings>
   * ib2=bindings.iterator(); while(ib2.hasNext() && !c.equals(ib2.next())) {
   * ; }
   *
   * while(ib2.hasNext()) { final Bindings d=ib2.next(); final Literal
   * value2=d.get(k);
   * //System.out.println("*************"+BindingsArray.getVariables
   * ()+":"+k+"="+value+":"+value2); if((value2==null) ||
   * !value2.valueEquals(value)) { return null; } }
   *
   * b.add(k,value); } } final QueryResult
   * result=QueryResult.createInstance(); result.add(b); return result; }
   */

  public static QueryResult joinBindings(final QueryResult qr) {

    final QueryResult result = QueryResult.createInstance();
    final Iterator<Bindings> ib = qr.iterator();

    if (ib.hasNext()) {
      final Bindings bindings1 = ib.next().clone();
      while (ib.hasNext()) {
        final Bindings bindings2 = ib.next();
        // only the keys of the second bindings object have to be
        // checked since the the first bindings object is updated
        for (final Variable b2key : bindings2.getVariableSet()) {

          final Literal literalB2 = bindings2.get(b2key);
          final Literal literalB1 = bindings1.get(b2key);

          // if the literal computed from the second bindings
          // conflicts with
          // the corresponding one located in the first bindings
          // object,
          // null is returned to indicate an unsolvable conflict
          if (literalB1 != null) {
            if (!literalB1.valueEquals(literalB2)) {
              return null;
            }
          }

          // otherwise add the new binding of the key and literal to
          // the first bindings object
          else {
            bindings1.add(b2key, literalB2);
          }
        }
        bindings1.addAllTriples(bindings2);
        bindings1.addAllPresortingNumbers(bindings2);
      }
      result.add(bindings1);
    }
    if (result.size() > 0)
      return result;
    else
      return null;
  }

  /**
   * This method must be overridden by the specific join algorithms. It
   * supports the reuse of code for the Optional operator.
   */
  @SuppressWarnings("unused")
  public OptionalResult processJoin(final QueryResult bindings, final int operandID) {
    throw (new UnsupportedOperationException("This Operator(" + this
        + ") should have been replaced before being used."));
  }

  public OptionalResult joinBeforeEndOfStream() {
    return null;
  }

  @Override
  public void cloneFrom(final BasicOperator op) {
    super.cloneFrom(op);
    if (op instanceof Join) {
      final Join join = (Join) op;
      this.estimatedCardinality = join.estimatedCardinality;
      this.realCardinality = join.realCardinality;
    } else {
      if (!(op instanceof Optional)) {
        System.err
            .println("Join.java: Join (or subclass of Join) or Optional (subclass of Optional) expected, but got "
                + op);
      }
    }
  }

  @Override
  public String toString() {
    String result = super.toString() + " on " + this.intersectionVariables;
    if (this.realCardinality >= 0) {
      result += "\nCardinality: " + this.realCardinality;
      if (this.estimatedCardinality >= 0)
        result += " (estimated " + this.estimatedCardinality + ")";
    } else if (this.estimatedCardinality >= 0)
      result += "\nEstminated Cardinality:" + this.estimatedCardinality;
    return result;
  }

}
TOP

Related Classes of lupos.engine.operators.multiinput.join.Join

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.