private boolean testHash(long hash64) {
    final int hash1 = (int) hash64;
    final int hash2 = (int) (hash64 >>> 32);
    final long[] bits = bitSet.data;

    int firstHash = hash1 + hash2;
    // hashcode should be positive, flip all the bits if it's negative
    if (firstHash < 0) {
      firstHash = ~firstHash;
    }

    // first hash is used to locate start of the block (blockBaseOffset)
    // subsequent K hashes are used to generate K bits within a block of words
    // To avoid branches during probe, a separate masks array is used for each longs/words within a block.
    // data array and masks array are then traversed together and checked for corresponding set bits.
    final int blockIdx = firstHash % totalBlockCount;
    final int blockBaseOffset = blockIdx << DEFAULT_BLOCK_SIZE_BITS;

    // iterate and update masks array
    for (int i = 1; i <= k; i++) {
      int combinedHash = hash1 + ((i + 1)  * hash2);
      // hashcode should be positive, flip all the bits if it's negative
      if (combinedHash < 0) {
        combinedHash = ~combinedHash;
      }
      // LSB 3 bits is used to locate offset within the block
      final int wordOffset = combinedHash & DEFAULT_BLOCK_OFFSET_MASK;
      final int absOffset = blockBaseOffset + wordOffset;
      // Next 6 bits are used to locate offset within a long/word
      final int bitPos = (combinedHash >>> DEFAULT_BLOCK_SIZE_BITS) & DEFAULT_BIT_OFFSET_MASK;
      final long bloomWord = bits[absOffset];
      if (0 == (bloomWord & (1L << bitPos))) {
        return false;
      }
    }

    return true;
  }
A constructor to support rebuilding the BloomFilter from a serialized representation.
@param bits BloomK sketch data in form of array of longs.
@param numFuncs  Number of functions called as K.
storage-api/src/java/org/apache/hive/common/util/BloomKFilter.java