code: private Pair<Integer, Integer> findLeafCombineDegreeAndNumBuffers(
        ByteBuffer combineBuffer,
        int requiredMinimumBufferCapacity,
        int numAvailableThreads,
        int numLeafNodes
    )
    {
      for (int leafCombineDegree = MINIMUM_LEAF_COMBINE_DEGREE; leafCombineDegree <= numLeafNodes; leafCombineDegree++) {
        final int requiredBufferNum = computeRequiredBufferNum(numLeafNodes, leafCombineDegree);
        if (requiredBufferNum <= numAvailableThreads) {
          final int expectedSliceSize = combineBuffer.capacity() / requiredBufferNum;
          if (expectedSliceSize >= requiredMinimumBufferCapacity) {
            return Pair.of(leafCombineDegree, requiredBufferNum);
          }
        }
      }
  
      throw new ISE(
          "Cannot find a proper leaf combine degree for the combining tree. "
          + "Each node of the combining tree requires a buffer of [%d] bytes. "
          + "Try increasing druid.processing.buffer.sizeBytes (currently [%d] bytes) for larger buffer or "
          + "druid.query.groupBy.intermediateCombineDegree for a smaller tree",
          requiredMinimumBufferCapacity,
          combineBuffer.capacity()
      );
    }
docs: Find a minimum size of the buffer slice and corresponding leafCombineDegree and number of slices.  Note that each
  node in the combining tree is executed by different threads.  This method assumes that combining the leaf nodes
  requires threads as many as possible, while combining intermediate nodes is not.  See the comment on
  {@link #MINIMUM_LEAF_COMBINE_DEGREE} for more details.
  
  @param combineBuffer                 entire buffer used for combining tree
  @param requiredMinimumBufferCapacity minimum buffer capacity for {@link StreamingMergeSortedGrouper}
  @param numAvailableThreads           number of available threads
  @param numLeafNodes                  number of leaf nodes of combining tree
  
  @return a pair of leafCombineDegree and number of buffers if found.