private void trimToSize(
      AggregationFunction aggregationFunction,
      Map<String, Serializable> aggregationGroupByResult,
      int trimSize) {
    PriorityQueue priorityQueue =
        getPriorityQueue(aggregationFunction, aggregationGroupByResult.values().iterator().next());
    if (priorityQueue == null) {
      return;
    }
    for (String groupedKey : aggregationGroupByResult.keySet()) {
      priorityQueue.enqueue(new Pair(aggregationGroupByResult.get(groupedKey), groupedKey));
      if (priorityQueue.size() == (_groupByTopN + 1)) {
        priorityQueue.dequeue();
      }
    }

    for (int i = 0; i < (priorityQueue.size() - trimSize); ++i) {
      Pair res = (Pair) priorityQueue.dequeue();
      aggregationGroupByResult.remove(res.getSecond());
    }
  }
  public List<JSONObject> renderGroupByOperators(
      List<Map<String, Serializable>> finalAggregationResult) {
    try {
      if (finalAggregationResult == null
          || finalAggregationResult.size() != _aggregationFunctionList.size()) {
        return null;
      }
      List<JSONObject> retJsonResultList = new ArrayList<JSONObject>();
      for (int i = 0; i < _aggregationFunctionList.size(); ++i) {
        JSONArray groupByResultsArray = new JSONArray();

        int groupSize = _groupByColumns.size();
        Map<String, Serializable> reducedGroupByResult = finalAggregationResult.get(i);
        if (!reducedGroupByResult.isEmpty()) {

          PriorityQueue priorityQueue =
              getPriorityQueue(
                  _aggregationFunctionList.get(i), reducedGroupByResult.values().iterator().next());
          if (priorityQueue != null) {
            for (String groupedKey : reducedGroupByResult.keySet()) {
              priorityQueue.enqueue(new Pair(reducedGroupByResult.get(groupedKey), groupedKey));
              if (priorityQueue.size() == (_groupByTopN + 1)) {
                priorityQueue.dequeue();
              }
            }

            int realGroupSize = _groupByTopN;
            if (priorityQueue.size() < _groupByTopN) {
              realGroupSize = priorityQueue.size();
            }
            for (int j = 0; j < realGroupSize; ++j) {
              JSONObject groupByResultObject = new JSONObject();
              Pair res = (Pair) priorityQueue.dequeue();
              groupByResultObject.put(
                  "group",
                  new JSONArray(
                      ((String) res.getSecond())
                          .split(
                              GroupByConstants.GroupByDelimiter.groupByMultiDelimeter.toString(),
                              groupSize)));
              //          if (res.getFirst() instanceof Number) {
              //            groupByResultObject.put("value", df.format(res.getFirst()));
              //          } else {
              //            groupByResultObject.put("value", res.getFirst());
              //          }
              //          groupByResultsArray.put(realGroupSize - 1 - j, groupByResultObject);
              groupByResultObject.put(
                  "value",
                  _aggregationFunctionList
                      .get(i)
                      .render((Serializable) res.getFirst())
                      .get("value"));
              groupByResultsArray.put(realGroupSize - 1 - j, groupByResultObject);
            }
          }
        }

        JSONObject result = new JSONObject();
        result.put("function", _aggregationFunctionList.get(i).getFunctionName());
        result.put("groupByResult", groupByResultsArray);
        result.put("groupByColumns", new JSONArray(_groupByColumns));
        retJsonResultList.add(result);
      }
      return retJsonResultList;
    } catch (JSONException e) {
      LOGGER.error("Caught exception while processing group by aggregation", e);
      Utils.rethrowException(e);
      throw new AssertionError("Should not reach this");
    }
  }