Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple Fix of SketchMap's non-commutative (issue-1122) #1123

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package com.twitter.algebird

import algebra.CommutativeMonoid
import com.twitter.algebird.matrix.AdaptiveMatrix
import com.twitter.algebird.matrix.DenseMatrix

/**
* A Sketch Map is a generalized version of the Count-Min Sketch that is an approximation of Map[K, V] that
Expand Down Expand Up @@ -50,7 +51,10 @@ class SketchMapMonoid[K, V](val params: SketchMapParams[K])(implicit
SketchMap(AdaptiveMatrix.fill(params.depth, params.width)(monoid.zero), Nil, monoid.zero)

override def plus(left: SketchMap[K, V], right: SketchMap[K, V]): SketchMap[K, V] = {
val newValuesTable = Monoid.plus(left.valuesTable, right.valuesTable)
val newValuesTable = right.valuesTable match {
case DenseMatrix(_, _, _) => Monoid.plus(right.valuesTable, left.valuesTable)
case _ => Monoid.plus(left.valuesTable, right.valuesTable)
}
Comment on lines +54 to +57
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
val newValuesTable = right.valuesTable match {
case DenseMatrix(_, _, _) => Monoid.plus(right.valuesTable, left.valuesTable)
case _ => Monoid.plus(left.valuesTable, right.valuesTable)
}
val newValuesTable = right.valuesTable match {
case _: DenseMatrix[V] => Monoid.plus(right.valuesTable, left.valuesTable)
case _ => Monoid.plus(left.valuesTable, right.valuesTable)
}

Also, perhaps it would make more sense to address this here

override def plus(a: AdaptiveMatrix[V], b: AdaptiveMatrix[V]): AdaptiveMatrix[V] =

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, perhaps it would make more sense to address this here

yeah, pretty much agreed.
I was afraid to touch AdaptiveMatrix due to unfamiliarity of it, but will try to see if I can fix that directly.

val newHeavyHitters = left.heavyHitterKeys.toSet ++ right.heavyHitterKeys

SketchMap(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.twitter.algebird

import com.twitter.algebird.matrix.DenseMatrix
import com.twitter.algebird.matrix.SparseColumnMatrix
import org.scalacheck.{Arbitrary, Gen}
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec
Expand Down Expand Up @@ -53,6 +55,38 @@ class SketchMapTest extends AnyWordSpec with Matchers {
assert(sm.totalValue == totalCount)
}

"plus should work commutatively" in {
implicit val m = Monoid.longMonoid
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is not required

val valueTableLeft =
DenseMatrix(
PARAMS.width,
PARAMS.depth,
rowsByColumns = IndexedSeq(10L) ++ (1 until PARAMS.width * PARAMS.depth).map(_ => 0L)
)
val testLeft = SketchMap[Int, Long](
valuesTable = valueTableLeft,
heavyHitterKeys = List(1),
totalValue = 10
)

val valueTableRight = SparseColumnMatrix(rowsByColumns =
IndexedSeq(
SparseVector(
map = Map(1 -> 1L),
sparseValue = 1L,
length = PARAMS.width * PARAMS.depth
)
)
)
val testRight = SketchMap[Int, Long](
valuesTable = valueTableRight,
heavyHitterKeys = List(1),
totalValue = 1
)

assert(MONOID.plus(testLeft, testRight) == MONOID.plus(testRight, testLeft))
}

"exactly compute frequencies in a small stream" in {
val one = MONOID.create((1, 1L))
val two = MONOID.create((2, 1L))
Expand Down