### Question:
Aggregate { public static <K, V> PTable<K, V> top(PTable<K, V> ptable, int limit, boolean maximize) { PTypeFamily ptf = ptable.getTypeFamily(); PTableType<K, V> base = ptable.getPTableType(); PType<Pair<K, V>> pairType = ptf.pairs(base.getKeyType(), base.getValueType()); PTableType<Integer, Pair<K, V>> inter = ptf.tableOf(ptf.ints(), pairType); return ptable.parallelDo("top" + limit + "map", new TopKFn<K, V>(limit, maximize), inter) .groupByKey(1) .combineValues(new TopKCombineFn<K, V>(limit, maximize)) .parallelDo("top" + limit + "reduce", new DoFn<Pair<Integer, Pair<K, V>>, Pair<K, V>>() { public void process(Pair<Integer, Pair<K, V>> input, Emitter<Pair<K, V>> emitter) { emitter.emit(input.second()); } }, base); }  static PTable<S, Long> count(PCollection<S> collect); static PTable<K, V> top(PTable<K, V> ptable, int limit, boolean maximize); static PCollection<S> max(PCollection<S> collect); static PCollection<S> min(PCollection<S> collect); static PTable<K, Collection<V>> collectValues(PTable<K, V> collect);  }### Answer:
@Test public void testTopN() throws Exception { PTableType<String, Integer> ptype = Avros.tableOf(Avros.strings(), Avros.ints()); PTable<String, Integer> counts = MemPipeline.typedTableOf(ptype, "foo", 12, "bar", 17, "baz", 29); PTable<String, Integer> top2 = Aggregate.top(counts, 2, true); assertEquals(ImmutableList.of(Pair.of("baz", 29), Pair.of("bar", 17)), top2.materialize()); PTable<String, Integer> bottom2 = Aggregate.top(counts, 2, false); assertEquals(ImmutableList.of(Pair.of("foo", 12), Pair.of("bar", 17)), bottom2.materialize()); }