/** * Returns the probability that {@linkplain #mightContain(Object)} will erroneously return * {@code true} for an object that has not actually been put in the {@code BloomFilter}. * * <p>Ideally, this number should be close to the {@code fpp} parameter * passed in {@linkplain #create(Funnel, int, double)}, or smaller. If it is * significantly higher, it is usually the case that too many elements (more than * expected) have been put in the {@code BloomFilter}, degenerating it. * * @since 14.0 (since 11.0 as expectedFalsePositiveProbability()) */ public double expectedFpp() { // You down with FPP? (Yeah you know me!) Who's down with FPP? (Every last homie!) return Math.pow((double) bits.bitCount() / bits.size(), numHashFunctions); }
@Override public <T> boolean mightContain(T object, Funnel<? super T> funnel, int numHashFunctions, BitArray bits) { long hash64 = Hashing.murmur3_128().hashObject(object, funnel).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; } if (!bits.get(nextHash % bits.size())) { return false; } } return true; } };
@Override public <T> boolean put(T object, Funnel<? super T> funnel, int numHashFunctions, BitArray bits) { long hash64 = Hashing.murmur3_128().hashObject(object, funnel).asLong(); int hash1 = (int) hash64; int hash2 = (int) (hash64 >>> 32); boolean bitsChanged = false; for (int i = 1; i <= numHashFunctions; i++) { int nextHash = hash1 + i * hash2; if (nextHash < 0) { nextHash = ~nextHash; } bitsChanged |= bits.set(nextHash % bits.size()); } return bitsChanged; }