/**
   * Returns the TopGroups for the specified BlockJoinQuery. The groupValue of each GroupDocs will
   * be the parent docID for that group. The number of documents within each group is calculated as
   * minimum of <code>maxDocsPerGroup</code> and number of matched child documents for that group.
   * Returns null if no groups matched.
   *
   * @param query Search query
   * @param withinGroupSort Sort criteria within groups
   * @param offset Parent docs offset
   * @param maxDocsPerGroup Upper bound of documents per group number
   * @param withinGroupOffset Offset within each group of child docs
   * @param fillSortFields Specifies whether to add sort fields or not
   * @return TopGroups for specified query
   * @throws IOException if there is a low-level I/O error
   */
  public TopGroups<Integer> getTopGroups(
      ToParentBlockJoinQuery query,
      Sort withinGroupSort,
      int offset,
      int maxDocsPerGroup,
      int withinGroupOffset,
      boolean fillSortFields)
      throws IOException {

    final Integer _slot = joinQueryID.get(query);
    if (_slot == null && totalHitCount == 0) {
      return null;
    }

    if (sortedGroups == null) {
      if (offset >= queue.size()) {
        return null;
      }
      sortQueue();
    } else if (offset > sortedGroups.length) {
      return null;
    }

    return accumulateGroups(
        _slot == null ? -1 : _slot.intValue(),
        offset,
        maxDocsPerGroup,
        withinGroupOffset,
        withinGroupSort,
        fillSortFields);
  }
 private void sortQueue() {
   sortedGroups = new OneGroup[queue.size()];
   for (int downTo = queue.size() - 1; downTo >= 0; downTo--) {
     sortedGroups[downTo] = queue.pop();
   }
 }