All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gemstone.gemfire.cache.query.internal.GroupJunction Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
 *
 * 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. See accompanying
 * LICENSE file.
 */
/*
 * Created on Oct 25, 2005
 */
package com.gemstone.gemfire.cache.query.internal;

import java.util.ArrayList;
import java.util.List;
import com.gemstone.gemfire.cache.query.FunctionDomainException;
import com.gemstone.gemfire.cache.query.NameResolutionException;
import com.gemstone.gemfire.cache.query.QueryInvocationTargetException;
import com.gemstone.gemfire.cache.query.TypeMismatchException;

/**
 * This structure contains the filter evaluable and iter evaluable
 * conditions which are dependent on a group of iterators derived from a single
 * independent iterator ( an iterator on the region) . The iter evaluatable
 * conditions belonging to other group of iterators can be a part of
 * GroupJunction only if the complete expansion flag is true.
 * 
 * @author EricZ
 * @author asif
 * @author kdeshpan
 * 
 *  
 */
public class GroupJunction extends AbstractGroupOrRangeJunction {
  private List unevaluatedFilterOperands = null; 

  GroupJunction(int operator, RuntimeIterator[] indpndntItr,
      boolean isCompleteExpansion, CompiledValue[] operands) {
    super(operator, indpndntItr,isCompleteExpansion,  operands);
    
  }

  void addUnevaluatedFilterOperands(List unevaluatedFilterOps) {
	this.unevaluatedFilterOperands = unevaluatedFilterOps;  
  }
  
  List getUnevaluatedFilterOperands() {
	return this.unevaluatedFilterOperands;  
  }
  
  private GroupJunction(AbstractGroupOrRangeJunction oldGJ, boolean completeExpansion,
      RuntimeIterator indpnds[], CompiledValue iterOp) {
    super(oldGJ, completeExpansion,indpnds, iterOp);    
  }
  
  @Override
  AbstractGroupOrRangeJunction recreateFromOld( boolean completeExpansion, RuntimeIterator indpnds[], CompiledValue iterOp) {
    return new GroupJunction(this,completeExpansion,indpnds,iterOp);      
  }
  
  @Override
  AbstractGroupOrRangeJunction createNewOfSameType(int operator,
      RuntimeIterator[] indpndntItr, boolean isCompleteExpansion,
      CompiledValue[] operands) {
    return new GroupJunction(operator, indpndntItr, isCompleteExpansion,
        operands);
  }
  
  @Override
  OrganizedOperands organizeOperands(ExecutionContext context)
      throws FunctionDomainException, TypeMismatchException,
      NameResolutionException, QueryInvocationTargetException {
    // get the list of operands to evaluate,
    // and evaluate operands that can use indexes first
    
    //Asif: Customer Hack:
    /*
    The idea is to use only one index in case of AND Junction .
    Ideally the best index to be used should have been decided during the initial phase itself
    when the compiled junction tree is being probed for indexable operands. But there are issues in
    it as we need to tackle comlex cases like detection of those conditions which can actually form
    a closed range or those which belong to different independent runtime iterators ( in case of multi
    region queries). So going for the  quick fix of sorting here. The filter operands present here 
    could be Comaprisn, IN or Range. The priority of sorting will be equality/IN/Range/Inequality    
    */    
    
    List evalOperands = new ArrayList(_operands.length);
    int indexCount = 0;
    boolean foundPreferredCondition = false; 
    if (this.getOperator() == LITERAL_and) {
      Filter currentBestFilter = null;
      int currentBestFilterSize =-1;
      indexCount = 1;

      for (int i = 0; i < _operands.length; i++) {
        // Asif : If we are inside this function this iteslf indicates
        // that there exists atleast on operand which can be evalauted
        // as an auxFilterEvaluate. If any operand even if its flag of
        // evalAsFilter happens to be false, but if it is independently
        // evaluatable, we should attach it with the auxFilterEvaluatable
        // operands irrespective of its value ( either true or false.)
        // This is because if it is true or false, it can always be paired
        // up with other filter operands for AND junction. But for
        // OR junction it can get paired with the filterOperands only
        // if it is false. But we do not have to worry about whether
        // the junction is AND or OR because, if the independent operand's
        // value is true & was under an OR junction , it would not have
        // been filterEvaluated. Instead it would have gone for
        // auxIterEvaluate.
        // We are here itself implies, that any independent operand can be
        // either tru or false for an AND junction but always false for an
        // OR Junction.
        PlanInfo pi = _operands[i].getPlanInfo(context);
        if (pi.evalAsFilter) {
          if(pi.isPreferred) {
            if(currentBestFilter != null) {
              evalOperands.add(currentBestFilter);
            }
            // new best
            currentBestFilter = (Filter)_operands[i];
            currentBestFilterSize = ((Filter)_operands[i]).getSizeEstimate(context);
            foundPreferredCondition = true;
            continue;
          }
          if (currentBestFilter == null) {
            currentBestFilter = (Filter)_operands[i];            
            currentBestFilterSize = ((Filter)_operands[i]).getSizeEstimate(context);
          }
          else if ( foundPreferredCondition ||currentBestFilter.isBetterFilter((Filter)_operands[i], context, currentBestFilterSize)) {
            evalOperands.add(_operands[i]);
          }
          else {
            evalOperands.add(currentBestFilter);
            currentBestFilter = (Filter)_operands[i];
            // TODO:Asif: Avoid this call. Let the function which is doing the
            // comparison return some how the size of comparedTo operand. 
            currentBestFilterSize = ((Filter)_operands[i]).getSizeEstimate(context);

          }
        }
        else if (!_operands[i].isDependentOnCurrentScope(context)) {
          // TODO: Asif :Remove this Assert & else if condition after successful
          // testing of the build
          Support
              .assertionFailed("An independentoperand should not ever be present as operand inside a GroupJunction as it should always be present only in CompiledJunction");
        }
        else {
          evalOperands.add(_operands[i]);
        }
      }
      
      evalOperands.add(0, currentBestFilter);
    }else {
      indexCount =_operands.length ;
      for (int i = 0; i < indexCount; i++) {
        evalOperands.add(_operands[i]);
      }
    }
    
    if(getIterOperands() != null) {
      evalOperands.add(getIterOperands());
    }
    return createOrganizedOperandsObject(indexCount,evalOperands);    
  }
  
  public int getSizeEstimate(ExecutionContext context)throws FunctionDomainException, TypeMismatchException, NameResolutionException, QueryInvocationTargetException  {
	return 1;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy