in algebird-core/src/main/scala/com/twitter/algebird/TopKMonoid.scala [55:78]
def build(t: T): TopK[T] = TopK(1, List(t), Some(t))
def build(ts: Iterable[T]): TopK[T] = ts.foldLeft(zero)((acc, t) => plus(acc, build(t)))
override def plus(left: TopK[T], right: TopK[T]): TopK[T] = {
val (bigger, smaller) =
if (left.size >= right.size) (left, right) else (right, left)
if (smaller.size == 0) {
bigger
} else if (bigger.size == k) {
// See if we can just return the bigger:
val biggerWins =
for {
biggest <- bigger.max
smallest <- smaller.items.headOption
} yield ord.lteq(biggest, smallest)
if (biggerWins.getOrElse(true)) { // smaller is small, or empty
bigger
} else {
merge(bigger, smaller)
}
} else {
merge(bigger, smaller)
}
}