Package lupos.optimizations.logical.rules

Source Code of lupos.optimizations.logical.rules.Rule

/**
* 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.optimizations.logical.rules;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import lupos.engine.operators.BasicOperator;
import lupos.engine.operators.OperatorIDTuple;
import lupos.engine.operators.messages.BoundVariablesMessage;
import lupos.misc.BitVector;
import lupos.misc.Tuple;
import lupos.optimizations.logical.rules.findsubgraph.FindSubGraph;

public abstract class Rule {

  protected BasicOperator startNode;
  protected Map<BasicOperator, String> subGraphMap;
  protected Map<String, BasicOperator> transformation;
  protected boolean findall = false;
  protected Set<BasicOperator> alreadyAppliedTo = new HashSet<BasicOperator>();

  public Rule() {
    this.init();
  }

  public String getName() {
    return this.getClass().getSimpleName();
  }

  public String getDescription() {
    String s = this.getName();
    if (s == null) {
      return null;
    }
    s = s.replaceAll(" ", "");
    s = s.toLowerCase();
    return s + "Rule";
  }

  public Rule[] getRulesToApply(final RuleEngine ruleEngine) {
    return null;
  }

  protected boolean apply(
      final BasicOperator op,
      final Map<Class<? extends BasicOperator>, Set<BasicOperator>> mapStartNodes) {

    final Set<BasicOperator> startNodesToCheck = mapStartNodes
        .get(this.startNode.getClass());
    if (startNodesToCheck != null) {
      for (final BasicOperator startNodeToCheck : startNodesToCheck) {
        final Map<String, BasicOperator> mso = FindSubGraph
            .checkSubGraph(startNodeToCheck, this.subGraphMap, this.startNode);
        if (mso != null) {
          if (!this.alreadyAppliedTo.contains(mso.get(this.subGraphMap
              .get(this.startNode)))
              && this.checkPrecondition(mso)) {
            this.alreadyAppliedTo.add(mso
                .get(this.subGraphMap.get(this.startNode)));
            final Tuple<Collection<BasicOperator>, Collection<BasicOperator>> updateMap = this.transformOperatorGraph(
                mso, op);
            if (updateMap != null) {
              for (final BasicOperator toDelete : updateMap
                  .getSecond()) {
                RuleEngine.deleteFromNodeMap(toDelete,
                    mapStartNodes);
              }
              for (final BasicOperator toAdd : updateMap
                  .getFirst()) {
                RuleEngine.addToNodeMap(toAdd, mapStartNodes);
              }
            }
            return true;
          }
        }
      }
    }
    return false;
  }

  protected boolean applyDebug(
      final BasicOperator op,
      final Map<Class<? extends BasicOperator>, Set<BasicOperator>> mapStartNodes) {

    final Set<BasicOperator> startNodesToCheck = mapStartNodes
        .get(this.startNode.getClass());
    if (startNodesToCheck != null) {
      for (final BasicOperator startNodeToCheck : startNodesToCheck) {
        final Map<String, BasicOperator> mso = FindSubGraph
            .checkSubGraph(startNodeToCheck, this.subGraphMap, this.startNode);
        if (mso != null) {
          if (!this.alreadyAppliedTo.contains(mso.get(this.subGraphMap
              .get(this.startNode)))
              && this.checkPrecondition(mso)) {
            this.alreadyAppliedTo.add(mso
                .get(this.subGraphMap.get(this.startNode)));
            System.out
                .println("Transform operator graph according rule "
                    + this.getClass().getSimpleName()
                    + " with name " + this.getName());
            final Tuple<Collection<BasicOperator>, Collection<BasicOperator>> updateMap = this.transformOperatorGraph(
                mso, op);
            if (updateMap != null) {
              for (final BasicOperator toDelete : updateMap
                  .getSecond()) {
                RuleEngine.deleteFromNodeMap(toDelete,
                    mapStartNodes);
              }
              for (final BasicOperator toAdd : updateMap
                  .getFirst()) {
                RuleEngine.addToNodeMap(toAdd, mapStartNodes);
              }
            }
            return true;
          }
        }
      }
    }
    return false;
  }

  protected abstract void init();

  protected abstract boolean checkPrecondition(Map<String, BasicOperator> mso);

  private boolean inSubgraph(final Map<String, BasicOperator> mso,
      final OperatorIDTuple opid) {
    for (final BasicOperator op : mso.values()) {
      if (opid.getOperator() == op) {
        return true;
      }
    }
    return false;
  }

  protected Tuple<Collection<BasicOperator>, Collection<BasicOperator>> transformOperatorGraph(
      final Map<String, BasicOperator> mso,
      final BasicOperator rootOperator) {
    final Collection<BasicOperator> deleted = new LinkedList<BasicOperator>();
    final Collection<BasicOperator> added = new LinkedList<BasicOperator>();
    final Map<BasicOperator, BasicOperator> operators = new HashMap<BasicOperator, BasicOperator>();

    // myRule.transformBasicOperatorGraph(mso,rootOperator);
    for (final String label : this.transformation.keySet()) {
      if (mso.containsKey(label)) {
        final BasicOperator op1 = this.transformation.get(label);
        final BasicOperator op2 = mso.get(label);
        final List<OperatorIDTuple> succs = op2
            .getSucceedingOperators();
        for (int i = succs.size() - 1; i >= 0; i--) {
          final OperatorIDTuple opID = succs.get(i);
          if (this.inSubgraph(mso, opID)) {
            succs.remove(i);
            opID.getOperator().removePrecedingOperator(op2);
            if (opID.getOperator().getPrecedingOperators().size() == 0) {
              deleted.add(opID.getOperator());
            }
          }
        }
        op2.addSucceedingOperators(op1.getSucceedingOperators());
        operators.put(op1, op2);
      } else {
        final BasicOperator toAdd = this.transformation.get(label).clone();
        added.add(toAdd);
        operators.put(this.transformation.get(label), toAdd);
      }
    }
    for (final BasicOperator op : operators.keySet()) {
      final BasicOperator realOp = operators.get(op);
      for (int i = 0; i < realOp.getSucceedingOperators().size(); i++) {
        final OperatorIDTuple succ = realOp.getSucceedingOperators()
            .get(i);
        if (operators.containsKey(succ.getOperator())) {
          realOp.getSucceedingOperators().set(
              i,
              new OperatorIDTuple(operators.get(succ
                  .getOperator()), succ.getId()));
          operators.get(succ.getOperator()).addPrecedingOperator(
              realOp);
        }
      }
    }
    rootOperator.deleteParents();
    rootOperator.setParents();
    rootOperator.detectCycles();
    rootOperator.sendMessage(new BoundVariablesMessage());
    if (deleted.size() > 0 || added.size() > 0) {
      return new Tuple<Collection<BasicOperator>, Collection<BasicOperator>>(
          added, deleted);
    } else {
      return null;
    }
  }

  protected BasicOperator setSucc(final BasicOperator op,
      final OperatorIDTuple... succ) {
    op.setSucceedingOperators(new LinkedList<OperatorIDTuple>());
    for (final OperatorIDTuple opid : succ) {
      op.addSucceedingOperator(opid);
    }
    return op;
  }

  /**
   * This method performs the actual check to see if a rule needs to be
   * reapplied after another rule made changes to the operator graph. This
   * method is not intended to be called directly, instead it is called by the
   * different subclasses of {@link lupos.optimizations.logical.rules.Rule}
   * passing the individual comparison vector of the respective subclass as a
   * paramater. This method exists to keep the logic for the reapplication
   * check in one place, rather than having it implemented in each and every
   * subclass.
   *
   * @see lupos.optimizations.logical.rules.Rule#isReapplicationNecessary(BitVector)
   * @param comparisonVector
   *            bit vector containtin all operators whose modification inside
   *            the operator graph leads to a reapplication of the rule in
   *            question
   * @param vectorOfChanges
   *            bit vector containing operators that were changed inside the
   *            operator graph
   * @return true if reapplication is necessary
   */
  protected static boolean performCheckForReapplication(
      final BitVector comparisonVector, final BitVector vectorOfChanges) {
    return vectorOfChanges.oneBitInCommon(comparisonVector);
  }

  protected static HashMap<Class<? extends BasicOperator>, Integer> putToClassToPosMap(
      HashMap<Class<? extends BasicOperator>, Integer> classToPosMap,
      final Integer pos, final Class<? extends BasicOperator>... classes) {
    if (classToPosMap == null) {
      classToPosMap = new HashMap<Class<? extends BasicOperator>, Integer>();
    }
    for (final Class<? extends BasicOperator> classToPut : classes) {
      classToPosMap.put(classToPut, pos);
    }
    return classToPosMap;
  }
}
TOP

Related Classes of lupos.optimizations.logical.rules.Rule

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.