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

com.gemstone.gemfire.cache.query.internal.AllGroupJunction 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.*;
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.SelectResults;
import com.gemstone.gemfire.cache.query.TypeMismatchException;
import com.gemstone.gemfire.cache.query.internal.parse.OQLLexerTokenTypes;
import com.gemstone.gemfire.cache.query.internal.types.StructTypeImpl;
import com.gemstone.gemfire.cache.query.types.ObjectType;
import com.gemstone.gemfire.cache.query.types.StructType;

/**
 * An object of this class gets created during the organization of operands in a
 * CompiledJunction. It gets created if there exists multiple filter evaluable
 * conditions in where clause of the query with those conditions dependent on
 * more than one group of independent iterators. Thus presence of more than one
 * region in a query is a prerequisite for the creation of this object. However,
 * actual creation will occur iff there exists more than one GroupJunction or
 * more than one CompositeGroupJunction or a combination of one or more
 * GroupJunctions & one or more CompositeGroupJunctions
 * 
 * @author Asif
 * @author kdeshpan
 */
public class AllGroupJunction extends AbstractCompiledValue implements Filter,
    OQLLexerTokenTypes {

  private List abstractGroupOrRangeJunctions = null;
  private int operator = 0;
  private List iterOperands = null;

  AllGroupJunction(List abstractGroupOrRangeJunctions, int operator, List iterOperands) {
    this.operator = operator;
    this.abstractGroupOrRangeJunctions = abstractGroupOrRangeJunctions;
    if (operator != LITERAL_and) {
      Support.Assert(iterOperands.size() == 0,
          "For OR Junction all operands need to be filterOperands");
    }
    this.iterOperands = iterOperands;
  }

  @Override
  public List getChildren() {
    List children = new ArrayList();
    children.addAll(this.abstractGroupOrRangeJunctions);
    children.addAll(this.iterOperands);
    return children;
  }
  
  public Object evaluate(ExecutionContext context) {
    Support.assertionFailed("Should not have come here");
    return null;
  }

  public int getType() {
    return ALLGROUPJUNCTION;
  }

  @Override
  public SelectResults filterEvaluate(ExecutionContext context,
      SelectResults intermediateResults) throws FunctionDomainException,
      TypeMismatchException, NameResolutionException,
      QueryInvocationTargetException {
    if (this.operator == LITERAL_and) {
      return evaluateAndJunction(context);
    }
    else {
      return evaluateOrJunction(context);
    }
  }

  /**
   * Asif:Evaluates the individual GroupJunctions and CompositeGroupJunctions
   * and does a cartesian of the results so obtained and simultaneously
   * expanding it to the query from clause level as well as evaluating any iter
   * evaluatable conditions. The evaluated result of an AllGroupJunction will
   * always be of the query from clause level which can be ORed or ANDd with
   * filter evaluatable subtree CompiledJunction
   * 
   * @param context ExecutionContext object
   * @return SelectResults
   * @throws FunctionDomainException
   * @throws TypeMismatchException
   * @throws NameResolutionException
   * @throws QueryInvocationTargetException
   */
  // Asif : For doing the Cartesian first evaluate the result of all Group
  // Junction. Doing Cartesian of all the Results together is better than doing
  // in pair
  private SelectResults evaluateAndJunction(ExecutionContext context)
      throws FunctionDomainException, TypeMismatchException,
      NameResolutionException, QueryInvocationTargetException {
    int len = this.abstractGroupOrRangeJunctions.size();
    // Asif : Create an array of SelectResults for each of the GroupJunction
    // For each Group Junction there will be a corresponding array of
    // RuntimeIterators which will map to the fields of the ResultSet obtained
    // from Group Junction.
    SelectResults[] results = new SelectResults[len];
    List finalList = context.getCurrentIterators();
    List expansionList = new LinkedList(finalList);
    RuntimeIterator[][] itrsForResultFields = new RuntimeIterator[len][];
    CompiledValue gj = null;
    Iterator junctionItr = this.abstractGroupOrRangeJunctions.iterator();
    List grpItrs = null;
    int j = 0;
    RuntimeIterator tempItr = null;
    while (junctionItr.hasNext()) {
      gj = (CompiledValue) junctionItr.next();
      SelectResults filterResults = ((Filter) gj).filterEvaluate(context, null);
      Support
          .Assert(filterResults != null, "FilterResults cannot be null here");
      if (filterResults.isEmpty()) {
        if (finalList.size() > 1) {
          StructType type = QueryUtils
              .createStructTypeForRuntimeIterators(finalList);
          return new StructBag((StructTypeImpl)type,
                               context.getCachePerfStats());
        }
        else {
          ObjectType type = ((RuntimeIterator) finalList.iterator().next())
              .getElementType();
          if (type instanceof StructType) {
            return new StructBag((StructTypeImpl)type,
                                 context.getCachePerfStats());
          }
          else {
            return new ResultsBag(type, context.getCachePerfStats());
          }
        }
      }
      else {
        results[j] = filterResults;
        grpItrs = (gj instanceof CompositeGroupJunction) ? QueryUtils
            .getDependentItrChainForIndpndntItrs(((CompositeGroupJunction) gj)
                .getIndependentIteratorsOfCJ(), context)
            : context
                .getCurrScopeDpndntItrsBasedOnSingleIndpndntItr(((AbstractGroupOrRangeJunction) gj)
                    .getIndependentIteratorForGroup()[0]);
        itrsForResultFields[j] = new RuntimeIterator[grpItrs.size()];
        Iterator grpItr = grpItrs.iterator();
        int k = 0;
        while (grpItr.hasNext()) {
          tempItr = (RuntimeIterator) grpItr.next();
          itrsForResultFields[j][k++] = tempItr;
          expansionList.remove(tempItr);
        }
        ++j;
      }
    }
    SelectResults resultsSet = null;
    // Asif : Do the Cartesian of the different group junction results.
    CompiledValue iterOperandsToSend = null;
    if (!iterOperands.isEmpty()) {
      //TODO ASIF : Avoid creation of CompiledJunction by providing
      // functionality in AllGroupJunction for evaluating condition
      int size = iterOperands.size();
      CompiledValue cv[] = new CompiledValue[size];
      for (int k = 0; k < size; ++k) {
        cv[k] = (CompiledValue) this.iterOperands.get(k);
      }
      if (cv.length == 1) {
        iterOperandsToSend = cv[0];
      }
      else {
        iterOperandsToSend = new CompiledJunction(cv, this.operator);
      }
    }
    QueryObserver observer = QueryObserverHolder.getInstance();
    observer
        .beforeCartesianOfGroupJunctionsInAnAllGroupJunctionOfType_AND(results);
    resultsSet = QueryUtils.cartesian(results, itrsForResultFields,
        expansionList, finalList, context, iterOperandsToSend);
    observer.afterCartesianOfGroupJunctionsInAnAllGroupJunctionOfType_AND();
    Support.Assert(resultsSet != null,
        "ResultsSet obtained was NULL in AllGroupJunction");
    return resultsSet;
  }

  /**
   * Evaluates the individual GroupJunctions and CompositeGroupJunctions and
   * expands the individual results so obtained to the query from clause
   * iterator level ( i.e top level iterators). The expanded results so obtained
   * are then merged (union) to get the ORed results.The evaluated result of an
   * AllGroupJunction will always be of the query from clause iterator level 
   * (top level) which can be ORed or ANDd with filter evaluable subtree
   * CompiledJunction.
   * 
   * @param context ExecutionContext object
   * @return SelectResults object
   * @throws FunctionDomainException
   * @throws TypeMismatchException
   * @throws NameResolutionException
   * @throws QueryInvocationTargetException
   */
  private SelectResults evaluateOrJunction(ExecutionContext context)
      throws FunctionDomainException, TypeMismatchException,
      NameResolutionException, QueryInvocationTargetException {
    // int len = this.abstractGroupOrRangeJunctions.size();
    // Asif : Create an array of SelectResults for each of the GroupJunction
    // For each Group Junction there will be a corresponding array of
    // RuntimeIterators which will map to the fields of the ResultSet obtained
    // from Group Junction
    SelectResults[] grpResults = new SelectResults[1];
    List finalList = context.getCurrentIterators();
    RuntimeIterator[][] itrsForResultFields = new RuntimeIterator[1][];
    CompiledValue gj = null;
    Iterator junctionItr = this.abstractGroupOrRangeJunctions.iterator();
    List grpItrs = null;
    RuntimeIterator tempItr = null;
    SelectResults intermediateResults = null;
    while (junctionItr.hasNext()) {
      List expansionList = new LinkedList(finalList);
      gj = (CompiledValue) junctionItr.next();
      grpResults[0] = ((Filter) gj).filterEvaluate(context, null);
      grpItrs = (gj instanceof CompositeGroupJunction) ? QueryUtils
          .getDependentItrChainForIndpndntItrs(((CompositeGroupJunction) gj)
              .getIndependentIteratorsOfCJ(), context) : context
          .getCurrScopeDpndntItrsBasedOnSingleIndpndntItr(((AbstractGroupOrRangeJunction) gj)
              .getIndependentIteratorForGroup()[0]);
      itrsForResultFields[0] = new RuntimeIterator[grpItrs.size()];
      Iterator grpItr = grpItrs.iterator();
      int k = 0;
      while (grpItr.hasNext()) {
        tempItr = (RuntimeIterator) grpItr.next();
        itrsForResultFields[0][k++] = tempItr;
        expansionList.remove(tempItr);
      }
      SelectResults expandedResult = QueryUtils.cartesian(grpResults,
          itrsForResultFields, expansionList, finalList, context, null/*
                                                                       * Iter
                                                                       * oprenad
                                                                       * for OR
                                                                       * Junction
                                                                       * evaluation
                                                                       * should
                                                                       * be null
                                                                       */);
      intermediateResults = (intermediateResults == null) ? expandedResult
          : QueryUtils.union(expandedResult, intermediateResults, context);
    }
    return intermediateResults;
  }

  List getGroupOperands() {
    // return unmodifiable copy
    return Collections.unmodifiableList(this.abstractGroupOrRangeJunctions);
  }

  List getIterOperands() {
    // return unmodifiable copy
    return Collections.unmodifiableList(this.iterOperands);
  }
  
  public int getSizeEstimate(ExecutionContext context)throws FunctionDomainException, TypeMismatchException, NameResolutionException, QueryInvocationTargetException  {
	 return 1;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy