如何在 Scala 中建模布隆过滤器
How to model a bloom filter in Scala
我正在尝试在 Scala 中为布隆过滤器建模。逻辑本身实际上非常简单,但我正在努力弄清楚如何充分使用 Scala 的数据结构来使它变得漂亮、惯用和实用。
我的问题是:如果我使用案例 class,我需要构造函数来生成哈希函数和存储实际布隆过滤器数据的位数组。
但是,在像 "add" 这样会改变位数组内容的方法中,我需要 return 一个新的布隆过滤器而不是改变现有过滤器的内容,以便我的方法是引用透明。
不幸的是,我无法构建新的布隆过滤器,因为我不想让新过滤器重新创建新的位数组和新的哈希函数,而且我也无法将现有的传递给它,因为位数组和哈希函数都不是布隆过滤器案例的一部分 class.
那么我应该如何在 Scala 中对此进行建模?
[修改为使用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
,但这会使 class 不可变,这是个好主意。哈希函数是在伴随对象中创建的,因此每次您 add
过滤器时都不会发生这种情况。
显然,这可以显着提高速度和内存使用效率。
我正在尝试在 Scala 中为布隆过滤器建模。逻辑本身实际上非常简单,但我正在努力弄清楚如何充分使用 Scala 的数据结构来使它变得漂亮、惯用和实用。
我的问题是:如果我使用案例 class,我需要构造函数来生成哈希函数和存储实际布隆过滤器数据的位数组。 但是,在像 "add" 这样会改变位数组内容的方法中,我需要 return 一个新的布隆过滤器而不是改变现有过滤器的内容,以便我的方法是引用透明。
不幸的是,我无法构建新的布隆过滤器,因为我不想让新过滤器重新创建新的位数组和新的哈希函数,而且我也无法将现有的传递给它,因为位数组和哈希函数都不是布隆过滤器案例的一部分 class.
那么我应该如何在 Scala 中对此进行建模?
[修改为使用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
,但这会使 class 不可变,这是个好主意。哈希函数是在伴随对象中创建的,因此每次您 add
过滤器时都不会发生这种情况。
显然,这可以显着提高速度和内存使用效率。