在Scala 2.10中,MurmurHash
由于某种原因被弃用,说我现在应该使用MurmurHash3
。但API不同,MurmurHash3
- >没有有用的标量。失败。
例如,当前代码:
trait Foo {
type Bar
def id: Int
def path: Bar
override def hashCode = {
import util.MurmurHash._
var h = startHash(2)
val c = startMagicA
val k = startMagicB
h = extendHash(h, id, c, k)
h = extendHash(h, path.##, nextMagicA(c), nextMagicB(k))
finalizeHash(h)
}
}
我如何使用MurmurHash3
代替?这需要是一个快速的操作,最好没有分配,所以我不想构建一个Product
,Seq
,Array[Byte]
或者MurmurHash3
似乎在提供给我。
答案 0 :(得分:7)
MurmurHash3 algorithm被混淆地从一个混合在自己的盐中的算法(基本上是c
和k
)改变为只进行更多比特混合的算法。基本操作现在是mix
,你应该折叠你的所有值,之后你应该finalizeHash
(Int
长度的参数也是为了方便,以帮助区分集合不同的长度)。如果您希望将mix
替换为mixLast
,则会更快一些,并使用finalizeHash
删除冗余。如果您需要花费太长时间才能检测到最后一个混音,只需mix
。
通常,对于一个集合,您需要混合一个额外的值来指示它是什么类型的集合。
你最低限度
override def hashCode = finalizeHash(mixLast(id, path.##), 0)
和“通常”你
// Pick any string or number that suits you, put in companion object
val fooSeed = MurmurHash3.stringHash("classOf[Foo]")
// I guess "id" plus "path" is two things?
override def hashCode = finalizeHash(mixLast( mix(fooSeed,id), path.## ), 2)
请注意,长度字段不是为了提供混合在该数字中的高质量哈希。所有重要哈希值的混合都应该使用mix
。
答案 1 :(得分:4)
看看MurmurHash3的source code建议如下:
override def hashCode = {
import util.hashing.MurmurHash3._
val h = symmetricSeed // I'm not sure which seed to use here
val h1 = mix(h, id)
val h2 = mixLast(h1, path ##)
finalizeHash(h2, 2)
}
或,(几乎)一行:
import util.hashing.MurmurHash3._
override def hashCode = finalizeHash(mix(mix(symmetricSeed, id), path ##), 2)