【问题标题】:How to model a bloom filter in Scala如何在 Scala 中建模布隆过滤器
【发布时间】:2019-03-04 06:44:51
【问题描述】:

我正在尝试在 Scala 中为布隆过滤器建模。逻辑本身实际上非常简单,但我正在努力弄清楚如何充分使用 Scala 的数据结构来制作漂亮、惯用和实用的数据结构。

我的问题是:如果我使用案例类,我需要构造函数来生成散列函数和存储实际布隆过滤器数据的位数组。 但是,在像“add”这样会改变位数组内容的方法中,我需要返回一个新的布隆过滤器,而不是改变现有布隆过滤器的内容,以使我的方法具有引用透明性。

不幸的是,我无法构造新的布隆过滤器,因为我不希望新的布隆过滤器重新创建新的位数组和新的哈希函数,而且我也无法将现有的传递给它,因为位数组和散列函数都属于布隆过滤器案例类。

那么我应该如何在 Scala 中建模呢?

【问题讨论】:

  • 我认为您希望将位数组 private 保留到实例中,使用每个 add 创建一个新的,并将散列函数 private 保留到伴随对象。 (但这只是我的想法。)

标签: scala data-structures functional-programming case-class bloom-filter


【解决方案1】:

[修改为使用BitSet,以下评论]

这是它如何工作的概述。

trait HashFunctions[T] {
  def apply(value: T): BitSet
}

object Bloom {
  class BloomFactory[T](hash: HashFunctions[T]) {
    case class Bloom(flags: BitSet) {
      def add(value: T): Bloom =
        Bloom(flags union hash(value))
      def test(value: T): Boolean =
        hash(value).subsetOf(flags)
    }
  }

  def apply[T](): BloomFactory[T]#Bloom = new BloomFactory(DefaultHashFunctions[T]).Bloom(BitSet.empty)
}

请注意,每次添加值时都会创建一个新的Bloom,但这会使类不可变,这是个好主意。散列函数是在伴随对象中创建的,因此每次您 add 过滤器时都不会发生这种情况。

显然,这可以显着提高速度和内存使用效率。

【讨论】:

  • 也许是 BitSet 而不是 Set[Int] ?
  • 在一种天真的方法中,我使用了Array[Boolean],并在我的哈希函数@AlexanderAzarov 给出的索引处切换布尔值。但我查看了其他实现,他们确实在使用 BitSet。使用 BitSet(或 Set[Int])有什么好处?
  • @AlexanderAzarov 谢谢,我已将代码修改为使用BitSet,这对于添加和更新来说可能会更快。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-12
相关资源
最近更新 更多