@Override
  public Facet reduce(String name, List<Facet> facets) {
    if (facets.size() == 1) {
      return facets.get(0);
    }
    InternalIntTermsFacet first = (InternalIntTermsFacet) facets.get(0);
    TIntIntHashMap aggregated = aggregateCache.get().get();
    aggregated.clear();
    long missing = 0;

    for (Facet facet : facets) {
      InternalIntTermsFacet mFacet = (InternalIntTermsFacet) facet;
      missing += mFacet.missingCount();
      for (IntEntry entry : mFacet.entries) {
        aggregated.adjustOrPutValue(entry.term, entry.count(), entry.count());
      }
    }

    BoundedTreeSet<IntEntry> ordered =
        new BoundedTreeSet<IntEntry>(first.comparatorType.comparator(), first.requiredSize);
    for (TIntIntIterator it = aggregated.iterator(); it.hasNext(); ) {
      it.advance();
      ordered.add(new IntEntry(it.key(), it.value()));
    }
    first.entries = ordered;
    first.missing = missing;
    return first;
  }
 @Override
 public Facet facet() {
   TIntIntHashMap facets = aggregator.facets();
   if (facets.isEmpty()) {
     CacheRecycler.pushIntIntMap(facets);
     return new InternalIntTermsFacet(
         facetName,
         comparatorType,
         size,
         ImmutableList.<InternalIntTermsFacet.IntEntry>of(),
         aggregator.missing());
   } else {
     if (size < EntryPriorityQueue.LIMIT) {
       EntryPriorityQueue ordered = new EntryPriorityQueue(size, comparatorType.comparator());
       for (TIntIntIterator it = facets.iterator(); it.hasNext(); ) {
         it.advance();
         ordered.insertWithOverflow(new InternalIntTermsFacet.IntEntry(it.key(), it.value()));
       }
       InternalIntTermsFacet.IntEntry[] list = new InternalIntTermsFacet.IntEntry[ordered.size()];
       for (int i = ordered.size() - 1; i >= 0; i--) {
         list[i] = (InternalIntTermsFacet.IntEntry) ordered.pop();
       }
       CacheRecycler.pushIntIntMap(facets);
       return new InternalIntTermsFacet(
           facetName, comparatorType, size, Arrays.asList(list), aggregator.missing());
     } else {
       BoundedTreeSet<InternalIntTermsFacet.IntEntry> ordered =
           new BoundedTreeSet<InternalIntTermsFacet.IntEntry>(comparatorType.comparator(), size);
       for (TIntIntIterator it = facets.iterator(); it.hasNext(); ) {
         it.advance();
         ordered.add(new InternalIntTermsFacet.IntEntry(it.key(), it.value()));
       }
       CacheRecycler.pushIntIntMap(facets);
       return new InternalIntTermsFacet(
           facetName, comparatorType, size, ordered, aggregator.missing());
     }
   }
 }
 @Override
 public void onValue(int docId, int value) {
   facets.adjustOrPutValue(value, 1, 1);
 }
 @Override
 public void onValue(int value) {
   facets.putIfAbsent(value, 0);
 }