Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Scala中建模bloom过滤器_Scala_Data Structures_Functional Programming_Case Class_Bloom Filter - Fatal编程技术网

如何在Scala中建模bloom过滤器

如何在Scala中建模bloom过滤器,scala,data-structures,functional-programming,case-class,bloom-filter,Scala,Data Structures,Functional Programming,Case Class,Bloom Filter,我正在尝试在Scala中模拟bloom过滤器。逻辑本身实际上非常简单,但我正在努力弄清楚如何充分使用Scala的数据结构,使其具有良好的、惯用的和功能性的特性 我的问题是:如果我使用case类,我需要构造函数来生成散列函数和将存储实际bloom过滤器数据的位数组。 但是,在像“add”这样会更改位数组内容的方法中,我需要返回一个新的bloom过滤器,而不是改变现有过滤器的内容,以使我的方法具有引用透明性 不幸的是,我不能构造一个新的bloom筛选器,因为我不希望新的筛选器重新创建一个新的位数组和

我正在尝试在Scala中模拟bloom过滤器。逻辑本身实际上非常简单,但我正在努力弄清楚如何充分使用Scala的数据结构,使其具有良好的、惯用的和功能性的特性

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

不幸的是,我不能构造一个新的bloom筛选器,因为我不希望新的筛选器重新创建一个新的位数组和新的哈希函数,而且我也不能将其传递给现有的筛选器,因为位数组和哈希函数都不是bloom筛选器case类的一部分


那么,我应该如何在Scala中对此进行建模呢?

[修改为使用
位集,注释如下]

这是它可能如何工作的概述

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
,但这会使类不可变,这是一个好主意。散列函数是在伴随对象中创建的,因此每次将
添加到过滤器时都不会发生这种情况


显然,这在速度和内存使用方面都可以显著提高效率。

[修改为使用
位集,注释如下]

这是它可能如何工作的概述

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
,并将哈希函数
private
保留在伴随对象中。(但这只是我的想法。)我认为您应该将位数组
私有
保留到实例中,使用每个
add
创建一个新的,并将哈希函数
private
保留到伴随对象中。(但这只是我的想法。)也许不是用
Set[Int]
?我用了一个
Array[Boolean]
,而是用我的hash函数@AlexanderAzarov给出的索引切换布尔值。但我看过其他的实现,它们确实在使用位集。使用位集(或Set[Int])有什么好处?@AlexanderAzarov谢谢,我已经修改为使用
位集
,这对于添加和更新都可能更快。也许我使用了
数组[Boolean]
,而不是
集[Int]
,这是一种天真的方法,我在我的hash函数@AlexanderAzarov给出的索引处切换布尔值。但我看过其他的实现,它们确实在使用位集。使用位集(或Set[Int])有什么好处?@AlexanderAzarov谢谢,我已经修改为使用
BitSet
,这对于添加和更新都可能更快。