代码的逻辑Guava的可能性

时间:2014-04-14 10:00:58

标签: java operators guava bloom-filter

我正在浏览Guava库的代码,我有兴趣了解mayContain的概率匹配代码。任何人都可以用比特运算符特别解释他们在代码中做了什么。 这是代码......

public <T> boolean mightContain(T object, Funnel<? super T> funnel,
        int numHashFunctions, BitArray bits) {
      long hash64 = Hashing.murmur3_128().newHasher().putObject(object, funnel).hash().asLong();
      int hash1 = (int) hash64;
      int hash2 = (int) (hash64 >>> 32);
      for (int i = 1; i <= numHashFunctions; i++) {
        int nextHash = hash1 + i * hash2;
        if (nextHash < 0) {
          nextHash = ~nextHash;
        }
        // up to here, the code is identical with the previous method
        if (!bits.get(nextHash % bits.size())) {
          return false;
        }

2 个答案:

答案 0 :(得分:3)

假设这是来自Bloomfilter类的代码,逻辑如下:

给定密钥,在该密钥上执行所有选定的哈希值。使用每个哈希值来选择一个位号并检查该位是否已设置。如果在该位置的过滤器中未设置任何位,则无法添加此键。

如果发现所有位都已设置,那么我们只能说过滤器可能已添加该键。这是因为不同的密钥(或许多不同密钥的组合)可能导致所有已检查的位都被设置。

请注意,向过滤器添加一个键的功能几乎完全相同,只是它设置**生成的所有位。

Bloom Filter对象的操作如下。

  1. 选择 number 哈希函数,每个哈希函数将计算过滤器中位的位置。 (有关详细数量的讨论,请参阅Optimal number of hash functions。)
  2. 保持一个任意长度的位模式 - 长度不重要但它应该足够大(有关足够的含义的讨论,请参阅Probability of false positives
  3. 每次将一个密钥添加到过滤器时,都会对密钥执行所有已配置的散列函数,从而导致在模式中设置多个位。
  4. 要检查是否已添加密钥,请执行所有散列函数并检查其中的位。如果发现任何零,则此键当然尚未添加到过滤器
  5. 如果发现所有位都已设置,那么可能已添加此密钥。您需要进行进一步的检查以确认。

答案 1 :(得分:0)

此处只有两个按位运算符:>>>~

>>>是&#34;右移,不带标志位&#34;运营商。在Java中,默认情况下,如果你转移:

1000 1100

右3(使用>>),您将获得:

1111 0001

使用不带符号位的>>>,您将获得:

0001 0001

第二个(~)是按位否定,并且是从负数获得正数的简单方法,看起来他们想要正数(稀疏数组索引可能?)。将此运算符应用于:

1100 1010

这是Java中的否定byte将产生:

0011 0101

这是积极的。

基本上,这段代码的作用是使用快速哈希函数创建对象的哈希值,使用它来遍历BitArray(不知道那是什么 - BloomFilter的内部结构可能),并确保在BitArray

中不存在散列的某一点存在NON

我怀疑每次添加BitArray时都会更新BloomFilter(使用.put().putAll())。