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 typeKof the items you want to count. Algebird ships with several such implicits for commonly used typesKsuch asLongandBigInt.If your type
Kis not supported out of the box, you have two options: 1) You provide a "translation" function to convert items of your (unsupported) typeKto a supported type such as Double, and then use thecontramapfunction of CMSHasher to create the requiredCMSHasher[K]for your type (see the documentation ofcontramapfor an example); 2) You implement aCMSHasher[K]from scratch, using the existing CMSHasher implementations as a starting point.