7

在 Scala 2.10 中,MurmurHash由于某种原因已弃用,说我MurmurHash3现在应该使用。MurmurHash3但是 API 不同,对于-> fail没有有用的 scaladocs 。

例如,当前代码:

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,SeqArray[Byte]任何MurmurHash3似乎提供给我的东西。

4

2 回答 2

7

令人困惑的是, MurmurHash3 算法从一种混合了自己的盐(本质上是 (ck) 的算法)变成了一种只进行更多位混合的算法。基本操作现在是mix,您应该折叠所有值,之后应该折叠finalizeHashInt长度参数也是为了方便,以帮助区分不同长度的集合)。如果你想用 替换你的最后一个mixmixLast它会更快一点,并用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.

于 2013-02-10T12:56:21.337 回答
4

查看MurmurHash3的源代码建议如下:

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)
于 2013-02-10T12:20:44.180 回答