in algebird-core/src/main/scala/com/twitter/algebird/AdaptiveVector.scala [81:116]
private def withSparse[V](v: AdaptiveVector[V], sv: V): AdaptiveVector[V] =
if (v.sparseValue == sv) v
else fromVector(toVector(v), sv)
private class AVSemigroup[V: Semigroup] extends Semigroup[AdaptiveVector[V]] {
private def valueIsNonZero(v: V): Boolean = implicitly[Semigroup[V]] match {
case m: Monoid[_] => m.isNonZero(v)
case _ => true
}
override def plus(left: AdaptiveVector[V], right: AdaptiveVector[V]): AdaptiveVector[V] =
if (left.sparseValue != right.sparseValue) {
if (left.denseCount > right.denseCount)
plus(withSparse(left, right.sparseValue), right)
else plus(left, withSparse(right, left.sparseValue))
} else {
// they have the same sparse value
val maxSize = Ordering[Int].max(left.size, right.size)
(left, right) match {
case (DenseVector(lv, ls, _), DenseVector(rv, _, _)) =>
val vec = Semigroup.plus[IndexedSeq[V]](lv, rv) match {
case v: Vector[_] => v.asInstanceOf[Vector[V]]
case notV => Vector.from(notV)
}
fromVector(vec, ls)
case _ if valueIsNonZero(left.sparseValue) =>
fromVector(
Vector.from(Semigroup.plus(toVector(left): IndexedSeq[V], toVector(right): IndexedSeq[V])),
left.sparseValue
)
case _ => // sparse is zero:
fromMap(Semigroup.plus(toMap(left), toMap(right)), left.sparseValue, maxSize)
}
}
}