private static int getBestNextFactor(
          RelMetadataQuery mq,
          HiveLoptMultiJoin multiJoin,
          BitSet factorsToAdd,
          BitSet factorsAdded,
          HiveLoptSemiJoinOptimizer semiJoinOpt,
          @Nullable HiveLoptJoinTree joinTree,
          List<RexNode> filtersToAdd) {
    // iterate through the remaining factors and determine the
    // best one to add next
    int nextFactor = -1;
    int bestWeight = 0;
    Double bestCardinality = null;
    int [][] factorWeights = multiJoin.getFactorWeights();
    for (int factor : BitSets.toIter(factorsToAdd)) {
      // if the factor corresponds to a dimension table whose
      // join we can remove, make sure the corresponding fact
      // table is in the current join tree
      Integer factIdx = multiJoin.getJoinRemovalFactor(factor);
      if (factIdx != null) {
        if (!factorsAdded.get(factIdx)) {
          continue;
        }
      }

      // can't add a null-generating factor if its dependent,
      // non-null generating factors haven't been added yet
      if (multiJoin.isNullGenerating(factor)
              && !BitSets.contains(factorsAdded,
              multiJoin.getOuterJoinFactors(factor))) {
        continue;
      }

      // determine the best weight between the current factor
      // under consideration and the factors that have already
      // been added to the tree
      int dimWeight = 0;
      for (int prevFactor : BitSets.toIter(factorsAdded)) {
        int[] factorWeight = requireNonNull(factorWeights, "factorWeights")[prevFactor];
        if (factorWeight[factor] > dimWeight) {
          dimWeight = factorWeight[factor];
        }
      }

      // only compute the join cardinality if we know that
      // this factor joins with some part of the current join
      // tree and is potentially better than other factors
      // already considered
      Double cardinality = null;
      if ((dimWeight > 0)
              && ((dimWeight > bestWeight) || (dimWeight == bestWeight))) {
        cardinality =
                computeJoinCardinality(
                        mq,
                        multiJoin,
                        semiJoinOpt,
                        requireNonNull(joinTree, "joinTree"),
                        filtersToAdd,
                        factor);
      }

      // if two factors have the same weight, pick the one
      // with the higher cardinality join key, relative to
      // the join being considered
      if ((dimWeight > bestWeight)
              || ((dimWeight == bestWeight)
              && ((bestCardinality == null)
              || ((cardinality != null)
              && (cardinality > bestCardinality))))) {
        nextFactor = factor;
        bestWeight = dimWeight;
        bestCardinality = cardinality;
      }
    }

    return nextFactor;
  }
Determines the best factor to be added next into a join tree.

@param multiJoin join factors being optimized
@param factorsToAdd factors to choose from to add next
@param factorsAdded factors that have already been added to the join tree
@param semiJoinOpt optimal semijoins for each factor
@param joinTree join tree constructed thus far
@param filtersToAdd remaining filters that need to be added

@return index of the best factor to add next
ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveLoptOptimizeJoinRule.java