Package com.orientechnologies.orient.core.sql.filter

Source Code of com.orientechnologies.orient.core.sql.filter.OFilterOptimizer

/*
  *
  *  *  Copyright 2014 Orient Technologies LTD (info(at)orientechnologies.com)
  *  *
  *  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  *  you may not use this file except in compliance with the License.
  *  *  You may obtain a copy of the License at
  *  *
  *  *       http://www.apache.org/licenses/LICENSE-2.0
  *  *
  *  *  Unless required by applicable law or agreed to in writing, software
  *  *  distributed under the License is distributed on an "AS IS" BASIS,
  *  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  *  *  See the License for the specific language governing permissions and
  *  *  limitations under the License.
  *  *
  *  * For more information: http://www.orientechnologies.com
  *
  */

package com.orientechnologies.orient.core.sql.filter;

import java.util.Map;

import com.orientechnologies.orient.core.sql.OIndexSearchResult;
import com.orientechnologies.orient.core.sql.OSQLHelper;
import com.orientechnologies.orient.core.sql.operator.OIndexReuseType;
import com.orientechnologies.orient.core.sql.operator.OQueryOperator;
import com.orientechnologies.orient.core.sql.operator.OQueryOperatorEquals;

/**
* @author <a href="mailto:enisher@gmail.com">Artem Orobets</a>
*/
public class OFilterOptimizer {
  public void optimize(OSQLFilter filter, OIndexSearchResult indexMatch) {
    filter.setRootCondition(optimize(filter.getRootCondition(), indexMatch));
  }

  private OSQLFilterCondition optimize(OSQLFilterCondition condition, OIndexSearchResult indexMatch) {
    OQueryOperator operator = condition.getOperator();
    while (operator == null) {
      if (condition.getRight() == null && condition.getLeft() instanceof OSQLFilterCondition) {
        condition = (OSQLFilterCondition) condition.getLeft();
        operator = condition.getOperator();
      } else {
        return condition;
      }
    }

    final OIndexReuseType reuseType = operator.getIndexReuseType(condition.getLeft(), condition.getRight());
    switch (reuseType) {
    case INDEX_METHOD:
      if (isCovered(indexMatch, operator, condition.getLeft(), condition.getRight())
          || isCovered(indexMatch, operator, condition.getRight(), condition.getLeft())) {
        return null;
      }
      return condition;

    case INDEX_INTERSECTION:
      if (condition.getLeft() instanceof OSQLFilterCondition)
        condition.setLeft(optimize((OSQLFilterCondition) condition.getLeft(), indexMatch));

      if (condition.getRight() instanceof OSQLFilterCondition)
        condition.setRight(optimize((OSQLFilterCondition) condition.getRight(), indexMatch));

      if (condition.getLeft() == null)
        return (OSQLFilterCondition) condition.getRight();
      if (condition.getRight() == null)
        return (OSQLFilterCondition) condition.getLeft();
      return condition;

    default:
      return condition;
    }
  }

  private boolean isCovered(OIndexSearchResult indexMatch, OQueryOperator operator, Object fieldCandidate, Object valueCandidate) {
    if (fieldCandidate instanceof OSQLFilterItemField) {
      final OSQLFilterItemField field = (OSQLFilterItemField) fieldCandidate;
      if (operator instanceof OQueryOperatorEquals)
        for (Map.Entry<String, Object> e : indexMatch.fieldValuePairs.entrySet()) {
          if (isSameField(field, e.getKey()) && isSameValue(valueCandidate, e.getValue()))
            return true;
        }

      return operator.equals(indexMatch.lastOperator) && isSameField(field, indexMatch.lastField)
          && isSameValue(valueCandidate, indexMatch.lastValue);
    }
    return false;
  }

  private boolean isSameValue(Object valueCandidate, Object lastValue) {
    if (lastValue == null || valueCandidate == null)
      return lastValue == null && valueCandidate == null;

    return lastValue.equals(valueCandidate) || lastValue.equals(OSQLHelper.getValue(valueCandidate));
  }

  private boolean isSameField(OSQLFilterItemField field, OSQLFilterItemField.FieldChain fieldChain) {
    return fieldChain.belongsTo(field);
  }

  private boolean isSameField(OSQLFilterItemField field, String fieldName) {
    return !field.hasChainOperators() && fieldName.equals(field.name);
  }
}
TOP

Related Classes of com.orientechnologies.orient.core.sql.filter.OFilterOptimizer

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.