int numHashFunctions = optimalNumOfHashFunctions(expectedInsertions, numBits); try { return new BloomFilter<T>(new BitArray(numBits), numHashFunctions, funnel, BloomFilterStrategies.MURMUR128_MITZ_32); } catch (IllegalArgumentException e) {
/** * 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() / bitSize(), numHashFunctions); }
@Override public boolean equals(@Nullable Object object) { if (object == this) { return true; } if (object instanceof BloomFilter) { BloomFilter<?> that = (BloomFilter<?>) object; return this.numHashFunctions == that.numHashFunctions && this.funnel.equals(that.funnel) && this.bits.equals(that.bits) && this.strategy.equals(that.strategy); } return false; }
int numHashFunctions = optimalNumOfHashFunctions(expectedInsertions, numBits); try { return new BloomFilter<T>(new BitArray(numBits), numHashFunctions, funnel, BloomFilterStrategies.MURMUR128_MITZ_32); } catch (IllegalArgumentException e) {
int numHashFunctions = optimalNumOfHashFunctions(expectedInsertions, numBits); try { return new BloomFilter<T>(new BitArray(numBits), numHashFunctions, funnel, BloomFilterStrategies.MURMUR128_MITZ_32); } catch (IllegalArgumentException e) {
int numHashFunctions = optimalNumOfHashFunctions(expectedInsertions, numBits); try { return new BloomFilter<T>(new BitArray(numBits), numHashFunctions, funnel, BloomFilterStrategies.MURMUR128_MITZ_32); } catch (IllegalArgumentException e) {
int numHashFunctions = optimalNumOfHashFunctions(expectedInsertions, numBits); try { return new BloomFilter<T>(new BitArray(numBits), numHashFunctions, funnel, BloomFilterStrategies.MURMUR128_MITZ_32); } catch (IllegalArgumentException e) {
int numHashFunctions = optimalNumOfHashFunctions(expectedInsertions, numBits); try { return new BloomFilter<T>(new BitArray(numBits), numHashFunctions, funnel, BloomFilterStrategies.MURMUR128_MITZ_32); } catch (IllegalArgumentException e) {
/** * Combines this bloom filter with another bloom filter by performing a bitwise OR of the * underlying data. The mutations happen to <b>this</b> instance. Callers must ensure the * bloom filters are appropriately sized to avoid saturating them. * * @param that The bloom filter to combine this bloom filter with. It is not mutated. * @throws IllegalArgumentException if {@code isCompatible(that) == false} * * @since 15.0 */ public void putAll(BloomFilter<T> that) { checkNotNull(that); checkArgument(this != that, "Cannot combine a BloomFilter with itself."); checkArgument(this.numHashFunctions == that.numHashFunctions, "BloomFilters must have the same number of hash functions (%s != %s)", this.numHashFunctions, that.numHashFunctions); checkArgument(this.bitSize() == that.bitSize(), "BloomFilters must have the same size underlying bit arrays (%s != %s)", this.bitSize(), that.bitSize()); checkArgument(this.strategy.equals(that.strategy), "BloomFilters must have equal strategies (%s != %s)", this.strategy, that.strategy); checkArgument(this.funnel.equals(that.funnel), "BloomFilters must have equal funnels (%s != %s)", this.funnel, that.funnel); this.bits.putAll(that.bits); }
/** * Combines this bloom filter with another bloom filter by performing a bitwise OR of the * underlying data. The mutations happen to <b>this</b> instance. Callers must ensure the * bloom filters are appropriately sized to avoid saturating them. * * @param that The bloom filter to combine this bloom filter with. It is not mutated. * @throws IllegalArgumentException if {@code isCompatible(that) == false} * * @since 15.0 */ public void putAll(BloomFilter<T> that) { checkNotNull(that); checkArgument(this != that, "Cannot combine a BloomFilter with itself."); checkArgument(this.numHashFunctions == that.numHashFunctions, "BloomFilters must have the same number of hash functions (%s != %s)", this.numHashFunctions, that.numHashFunctions); checkArgument(this.bitSize() == that.bitSize(), "BloomFilters must have the same size underlying bit arrays (%s != %s)", this.bitSize(), that.bitSize()); checkArgument(this.strategy.equals(that.strategy), "BloomFilters must have equal strategies (%s != %s)", this.strategy, that.strategy); checkArgument(this.funnel.equals(that.funnel), "BloomFilters must have equal funnels (%s != %s)", this.funnel, that.funnel); this.bits.putAll(that.bits); }
/** * Combines this bloom filter with another bloom filter by performing a bitwise OR of the * underlying data. The mutations happen to <b>this</b> instance. Callers must ensure the * bloom filters are appropriately sized to avoid saturating them. * * @param that The bloom filter to combine this bloom filter with. It is not mutated. * @throws IllegalArgumentException if {@code isCompatible(that) == false} * * @since 15.0 */ public void putAll(BloomFilter<T> that) { checkNotNull(that); checkArgument(this != that, "Cannot combine a BloomFilter with itself."); checkArgument(this.numHashFunctions == that.numHashFunctions, "BloomFilters must have the same number of hash functions (%s != %s)", this.numHashFunctions, that.numHashFunctions); checkArgument(this.bitSize() == that.bitSize(), "BloomFilters must have the same size underlying bit arrays (%s != %s)", this.bitSize(), that.bitSize()); checkArgument(this.strategy.equals(that.strategy), "BloomFilters must have equal strategies (%s != %s)", this.strategy, that.strategy); checkArgument(this.funnel.equals(that.funnel), "BloomFilters must have equal funnels (%s != %s)", this.funnel, that.funnel); this.bits.putAll(that.bits); }
/** * Combines this bloom filter with another bloom filter by performing a bitwise OR of the * underlying data. The mutations happen to <b>this</b> instance. Callers must ensure the * bloom filters are appropriately sized to avoid saturating them. * * @param that The bloom filter to combine this bloom filter with. It is not mutated. * @throws IllegalArgumentException if {@code isCompatible(that) == false} * * @since 15.0 */ public void putAll(BloomFilter<T> that) { checkNotNull(that); checkArgument(this != that, "Cannot combine a BloomFilter with itself."); checkArgument(this.numHashFunctions == that.numHashFunctions, "BloomFilters must have the same number of hash functions (%s != %s)", this.numHashFunctions, that.numHashFunctions); checkArgument(this.bitSize() == that.bitSize(), "BloomFilters must have the same size underlying bit arrays (%s != %s)", this.bitSize(), that.bitSize()); checkArgument(this.strategy.equals(that.strategy), "BloomFilters must have equal strategies (%s != %s)", this.strategy, that.strategy); checkArgument(this.funnel.equals(that.funnel), "BloomFilters must have equal funnels (%s != %s)", this.funnel, that.funnel); this.bits.putAll(that.bits); }
/** * Combines this bloom filter with another bloom filter by performing a bitwise OR of the * underlying data. The mutations happen to <b>this</b> instance. Callers must ensure the * bloom filters are appropriately sized to avoid saturating them. * * @param that The bloom filter to combine this bloom filter with. It is not mutated. * @throws IllegalArgumentException if {@code isCompatible(that) == false} * * @since 15.0 */ public void putAll(BloomFilter<T> that) { checkNotNull(that); checkArgument(this != that, "Cannot combine a BloomFilter with itself."); checkArgument(this.numHashFunctions == that.numHashFunctions, "BloomFilters must have the same number of hash functions (%s != %s)", this.numHashFunctions, that.numHashFunctions); checkArgument(this.bitSize() == that.bitSize(), "BloomFilters must have the same size underlying bit arrays (%s != %s)", this.bitSize(), that.bitSize()); checkArgument(this.strategy.equals(that.strategy), "BloomFilters must have equal strategies (%s != %s)", this.strategy, that.strategy); checkArgument(this.funnel.equals(that.funnel), "BloomFilters must have equal funnels (%s != %s)", this.funnel, that.funnel); this.bits.putAll(that.bits); }
/** * Combines this bloom filter with another bloom filter by performing a bitwise OR of the * underlying data. The mutations happen to <b>this</b> instance. Callers must ensure the * bloom filters are appropriately sized to avoid saturating them. * * @param that The bloom filter to combine this bloom filter with. It is not mutated. * @throws IllegalArgumentException if {@code isCompatible(that) == false} * * @since 15.0 */ public void putAll(BloomFilter<T> that) { checkNotNull(that); checkArgument(this != that, "Cannot combine a BloomFilter with itself."); checkArgument(this.numHashFunctions == that.numHashFunctions, "BloomFilters must have the same number of hash functions (%s != %s)", this.numHashFunctions, that.numHashFunctions); checkArgument(this.bitSize() == that.bitSize(), "BloomFilters must have the same size underlying bit arrays (%s != %s)", this.bitSize(), that.bitSize()); checkArgument(this.strategy.equals(that.strategy), "BloomFilters must have equal strategies (%s != %s)", this.strategy, that.strategy); checkArgument(this.funnel.equals(that.funnel), "BloomFilters must have equal funnels (%s != %s)", this.funnel, that.funnel); this.bits.putAll(that.bits); }
@VisibleForTesting static <T> BloomFilter<T> create( Funnel<T> funnel, int expectedInsertions /* n */, double fpp, Strategy strategy) { checkNotNull(funnel); checkArgument(expectedInsertions >= 0, "Expected insertions (%s) must be >= 0", expectedInsertions); checkArgument(fpp > 0.0, "False positive probability (%s) must be > 0.0", fpp); checkArgument(fpp < 1.0, "False positive probability (%s) must be < 1.0", fpp); checkNotNull(strategy); if (expectedInsertions == 0) { expectedInsertions = 1; } /* * TODO(user): Put a warning in the javadoc about tiny fpp values, * since the resulting size is proportional to -log(p), but there is not * much of a point after all, e.g. optimalM(1000, 0.0000000000000001) = 76680 * which is less than 10kb. Who cares! */ long numBits = optimalNumOfBits(expectedInsertions, fpp); int numHashFunctions = optimalNumOfHashFunctions(expectedInsertions, numBits); try { return new BloomFilter<T>(new BitArray(numBits), numHashFunctions, funnel, strategy); } catch (IllegalArgumentException e) { throw new IllegalArgumentException("Could not create BloomFilter of " + numBits + " bits", e); } }
@Override public <T> boolean mightContain(T object, Funnel<? super T> funnel, int numHashFunctions, BitArray bits) { long bitSize = bits.bitSize(); 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 combinedHash = hash1 + (i * hash2); // Flip all the bits if it's negative (guaranteed positive number) if (combinedHash < 0) { combinedHash = ~combinedHash; } if (!bits.get(combinedHash % bitSize)) { return false; } } return true; } },
@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.bitSize())) { return false; } } return true; } };
@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 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.bitSize())) { return false; } } return true; } };
@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.bitSize())) { return false; } } return true; } };