Given f
, a function from L
into K
, creates a CMSHasher[L]
whose hash function is equivalent to:
Given f
, a function from L
into K
, creates a CMSHasher[L]
whose hash function is equivalent to:
def hash(a: Int, b: Int, width: Int)(x: L): CMSHasher[L] = CMSHasher[K].hash(a, b, width)(f(x))
Be aware that the use of contramap may come at a cost (e.g. increased time) due to the translation calls between
K
and L
.
The following example creates a CMSHasher for the unsupported type K=Double
:
def f(d: Double): Array[Byte] = { val l: Long = java.lang.Double.doubleToLongBits(d) java.nio.ByteBuffer.allocate(8).putLong(l).array() } implicit val cmsHasherDouble: CMSHasher[Double] = CMSHasherArrayByte.contramap((d: Double) => f(d))
Given f
, a function from L
into K
, creates a CMSHasher[L]
whose hash function is equivalent to:
Given f
, a function from L
into K
, creates a CMSHasher[L]
whose hash function is equivalent to:
def hash(a: Int, b: Int, width: Int)(x: L): CMSHasher[L] = CMSHasher[K].hash(a, b, width)(f(x))
The Count-Min sketch uses
d
(akadepth
) pair-wise independent hash functions drawn from a universal hashing family of the form:h(x) = [a * x + b (mod p)] (mod m)
As a requirement for using CMS you must provide an implicit
CMSHasher[K]
for the typeK
of the items you want to count. Algebird ships with several such implicits for commonly used typesK
such asLong
andBigInt
.If your type
K
is not supported out of the box, you have two options: 1) You provide a "translation" function to convert items of your (unsupported) typeK
to a supported type such as Double, and then use thecontramap
function of CMSHasher to create the requiredCMSHasher[K]
for your type (see the documentation ofcontramap
for an example); 2) You implement aCMSHasher[K]
from scratch, using the existing CMSHasher implementations as a starting point.