@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 void writeTo(StreamOutput out) throws IOException {
    out.writeUTF(name);
    out.writeByte(comparatorType.id());
    out.writeVInt(requiredSize);
    out.writeVLong(missing);

    out.writeVInt(entries.size());
    for (IntEntry entry : entries) {
      out.writeInt(entry.term);
      out.writeVInt(entry.count());
    }
  }
 @Override
 public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
   builder.startObject(name);
   builder.field(Fields._TYPE, TermsFacet.TYPE);
   builder.field(Fields.MISSING, missing);
   builder.startArray(Fields.TERMS);
   for (IntEntry entry : entries) {
     builder.startObject();
     builder.field(Fields.TERM, entry.term);
     builder.field(Fields.COUNT, entry.count());
     builder.endObject();
   }
   builder.endArray();
   builder.endObject();
   return builder;
 }