Package lupos.engine.operators.multiinput.join

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

/**
* 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 java.util.Map;

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.optional.OptionalResult;

public abstract class IndexJoin extends Join {
  protected Map<String, QueryResult>[] lba;
  protected QueryResult[] cartesianProduct = { this.createQueryResult(), this.createQueryResult() };

  public IndexJoin() {
    super();
    init();
  }

  @Override
  public void cloneFrom(final BasicOperator op) {
    super.cloneFrom(op);
    init();
  }
 
  /**
   * This method creates a QueryResult object.
   * This method must be overriden by succeeding classes:
   * For joins with internal duplicate elimination, this method returns a QueryResult object with unique bindings, otherwise a normal multi-set QueryResult object.
   * @return a new Queryresult object
   */
  protected abstract QueryResult createQueryResult();
 
  /**
   * Must be overridden by succeeding classes for signaling whether or not duplicate elimination is part of this join.
   * @return true if duplicate elimination is enabled for this join
   */
  protected abstract boolean isDuplicateEliminationEnabled();

  public abstract void init();

  @Override
  public synchronized QueryResult process(final QueryResult bindings, final int operandID) {
    final QueryResult result = this.createQueryResult();

    int otherOperand = 1-operandID;

    final Iterator<Bindings> itbindings = bindings.oneTimeIterator();
    while (itbindings.hasNext()) {

      final Bindings binding = itbindings.next();
      String keyJoin = "";
      final Iterator<Variable> it = this.intersectionVariables.iterator();
      while (it.hasNext()) {
        final Literal literal = binding.get(it.next());
        if (literal == null) {
          boolean added = this.cartesianProduct[operandID].add(binding);
          if(added || !isDuplicateEliminationEnabled()){
            // build the cartesian product
            for (final Bindings b2 : this.cartesianProduct[otherOperand]) {
              joinBindings(result, binding.clone(), b2);
            }
 
            for (final QueryResult qr : this.lba[otherOperand].values()) {
              for (final Bindings b2 : qr) {
                joinBindings(result, binding.clone(), b2);
              }
            }
          }

          keyJoin = null;
          break;
        }
        keyJoin += "|" + literal.getKey();
      }

      if (keyJoin == null)
        continue;

      QueryResult lb = this.lba[operandID].get(keyJoin);
      if (lb == null){
        lb = this.createQueryResult();
      }
      boolean added = lb.add(binding);
      this.lba[operandID].put(keyJoin, lb);

      if(added || !isDuplicateEliminationEnabled()){
        final QueryResult toJoin = this.lba[otherOperand].get(keyJoin);
        if (toJoin != null) {
          final Iterator<Bindings> itb = toJoin.iterator();
          while (itb.hasNext()) {
            final Bindings b2 = itb.next();

            joinBindings(result, binding.clone(), b2);
          }
        }
        // build cartesian product
        for (final Bindings b2 : this.cartesianProduct[otherOperand]) {
          joinBindings(result, binding.clone(), b2);
        }
      }
    }
    if (result.size() == 0)
      return null;
    else {
      if (this.realCardinality < 0)
        this.realCardinality = result.size();
      else
        this.realCardinality += result.size();
      return result;
    }
  }

  @Override
  public synchronized OptionalResult processJoin(final QueryResult bindings,
      final int operandID) {
    // different from process:
    final OptionalResult or = new OptionalResult();
    // different from process:
    final QueryResult joinPartnerFromLeftOperand = this.createQueryResult();
    final QueryResult result = this.createQueryResult();
    int otherOperand = 1-operandID;
    final Iterator<Bindings> itbindings = bindings.oneTimeIterator();
    while (itbindings.hasNext()) {
      final Bindings binding = itbindings.next();
      String keyJoin = "";
      final Iterator<Variable> it = this.intersectionVariables.iterator();
      while (it.hasNext()) {
        final Literal literal = binding.get(it.next());
        if (literal == null) {
          boolean added = this.cartesianProduct[operandID].add(binding);
          if(added || !isDuplicateEliminationEnabled()){
            // build the cartesian product
            for (final Bindings b2 : this.cartesianProduct[otherOperand]) {
              if(joinBindings(result, binding.clone(), b2)){
                if (operandID == 1) {
                  joinPartnerFromLeftOperand.add(b2);
                } else {
                  joinPartnerFromLeftOperand.add(binding);
                }             
              }
            }
 
            for (final QueryResult qr : this.lba[otherOperand].values()) {
              for (final Bindings b2 : qr) {
                if(joinBindings(result, binding.clone(), b2)){
                  if (operandID == 1) {
                    joinPartnerFromLeftOperand.add(b2);
                  } else {
                    joinPartnerFromLeftOperand.add(binding);
                  }               
                }
              }
            }
          }

          keyJoin = null;
          break;
        }
        keyJoin += "|" + literal.getKey();
      }

      if (keyJoin == null)
        continue;
     
      QueryResult lb = this.lba[operandID].get(keyJoin);
      if (lb == null){
        lb = this.createQueryResult();
      }
      boolean added = lb.add(binding);
      if(added || !isDuplicateEliminationEnabled()){
        this.lba[operandID].put(keyJoin, lb);
 
        final QueryResult toJoin = this.lba[otherOperand].get(keyJoin);
        if (toJoin != null) {
 
          final Iterator<Bindings> itb = toJoin.iterator();
          while (itb.hasNext()) {
            final Bindings b2 = itb.next();
 
            // different from process:
            if (joinBindings(result, binding.clone(), b2)) {
              if (operandID == 1) {
                joinPartnerFromLeftOperand.add(b2);
              } else {
                joinPartnerFromLeftOperand.add(binding);
              }
            }
          }
        }
        // build cartesian product
        for (final Bindings b2 : this.cartesianProduct[otherOperand]) {
          if(joinBindings(result, binding.clone(), b2)){
            if (operandID == 1) {
              joinPartnerFromLeftOperand.add(b2);
            } else {
              joinPartnerFromLeftOperand.add(binding);
            }
          }
        }
      }
    }
    // different from process:
    or.setJoinPartnerFromLeftOperand(joinPartnerFromLeftOperand);
    // different from process:
    or.setJoinResult(result);
    // different from process:
    return or;
  }

  public Map<String, QueryResult>[] getLba() {
    return this.lba;
  }

  public QueryResult[] getCartesianProduct() {
    return this.cartesianProduct;
  }

  @Override
  public void deleteAll(final int operandID) {
    this.cartesianProduct[operandID].release();
    this.cartesianProduct[operandID] = this.createQueryResult();
    this.lba[operandID].clear();
  }

  @Override
  public QueryResult deleteQueryResult(final QueryResult queryResult, final int operandID) {
    final QueryResult result = this.createQueryResult();

    int otherOperand;
    if (operandID == 0)
      otherOperand = 1;
    else
      otherOperand = 0;

    final Iterator<Bindings> itbindings = queryResult.oneTimeIterator();
    while (itbindings.hasNext()) {

      final Bindings binding = itbindings.next();
      String keyJoin = "";
      final Iterator<Variable> it = this.intersectionVariables.iterator();
      while (it.hasNext()) {
        final Literal literal = binding.get(it.next());
        if (literal == null) {
          boolean removed = this.cartesianProduct[operandID].remove(binding);
          if(removed || !isDuplicateEliminationEnabled()){
            // build the cartesian product
            for (final Bindings b2 : this.cartesianProduct[otherOperand]) {
              joinBindings(result, binding.clone(), b2);
            }
 
            for (final QueryResult qr : this.lba[otherOperand].values()) {
              for (final Bindings b2 : qr) {
                joinBindings(result, binding.clone(), b2);
              }
            }
          }

          keyJoin = null;
          break;
        }
        keyJoin += "|" + literal.getKey();
      }

      if (keyJoin == null)
        continue;

      final QueryResult lb = this.lba[operandID].get(keyJoin);
      boolean removed = false;
      if (lb != null){
        removed = lb.remove(binding);
      }
      this.lba[operandID].put(keyJoin, lb);

      if(removed || !isDuplicateEliminationEnabled()){
        final QueryResult toJoin = this.lba[otherOperand].get(keyJoin);
        if (toJoin != null) {
 
          final Iterator<Bindings> itb = toJoin.iterator();
          while (itb.hasNext()) {
            final Bindings b2 = itb.next();
 
            joinBindings(result, binding.clone(), b2);
          }
        }

        // build cartesian product
        for (final Bindings b2 : this.cartesianProduct[otherOperand]) {
          joinBindings(result, binding.clone(), b2);
        }
      }
    }
    if (result.size() == 0)
      return null;
    else {
      if (this.realCardinality < 0)
        this.realCardinality = result.size();
      else
        this.realCardinality -= result.size();
      return result;
    }
  }
}
TOP

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

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.