【问题标题】:Migrate from MurmurHash to MurmurHash3从 MurmurHash 迁移到 MurmurHash3
【发布时间】:2013-01-25 16:34:43
【问题描述】:

在 Scala 2.10 中,MurmurHash 出于某种原因已被弃用,说我现在应该使用 MurmurHash3。但是 API 不同,对于 MurmurHash3 没有有用的 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 似乎提供给我的东西。

【问题讨论】:

    标签: scala hash murmurhash


    【解决方案1】:

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

    【讨论】:

    • 谢谢,雷克斯。种子生成是有道理的。所以Product 这可能是stringHash(productPrefix)。
    • @0__ - 这是一个合理的值。它真的归结为可能具有相同内容但不同身份的东西。如果不存在这样的东西(或者你不介意与它/他们碰撞),那么你可以在那里放任何东西或什么也不放。 “只与名称和内容相同的东西(也是Product,并使用相同的明显方法选择种子)发生冲突”是一个非常合理的策略。
    【解决方案2】:

    查看 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)
    

    【讨论】:

    • 看起来不错。我想我会使用productSeed,因为我的原始代码是基于 arity 2 的产品哈希生成器。
    猜你喜欢
    • 1970-01-01
    • 2012-12-04
    • 2011-04-26
    • 2015-07-23
    • 2020-05-31
    • 2010-10-26
    • 2022-01-14
    • 2016-09-27
    • 2011-04-29
    相关资源
    最近更新 更多