7

Scala 2.10ではMurmurHash、何らかの理由で、今すぐ使用する必要があると言って非推奨になってMurmurHash3います。MurmurHash3ただし、APIは異なり、 ->失敗に役立つ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これは高速な操作である必要があり、できれば割り当てなしである必要があるため、、、、または私Seqに提供されていると思われるものを構築したくありません。Array[Byte]MurmurHash3

4

2 に答える 2

7

MurmurHash3アルゴリズムは、紛らわしいことに、それ自体のソルト(本質的に(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

于 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)
}

または、(ほぼ)1行で:

import util.hashing.MurmurHash3._
override def hashCode = finalizeHash(mix(mix(symmetricSeed, id), path ##), 2)
于 2013-02-10T12:20:44.180 に答える