diff --git a/android/guava/src/com/google/common/hash/BloomFilter.java b/android/guava/src/com/google/common/hash/BloomFilter.java index 557d05593ad0..2f4adeaf5dd9 100644 --- a/android/guava/src/com/google/common/hash/BloomFilter.java +++ b/android/guava/src/com/google/common/hash/BloomFilter.java @@ -214,7 +214,7 @@ public long approximateElementCount() { /** Returns the number of bits in the underlying bit array. */ @VisibleForTesting - long bitSize() { + public long bitSize() { return bits.bitSize(); } diff --git a/guava/src/com/google/common/hash/BloomFilter.java b/guava/src/com/google/common/hash/BloomFilter.java index fb0542f899ed..28aa76b00f11 100644 --- a/guava/src/com/google/common/hash/BloomFilter.java +++ b/guava/src/com/google/common/hash/BloomFilter.java @@ -41,26 +41,43 @@ import org.checkerframework.checker.nullness.qual.Nullable; /** - * A Bloom filter for instances of {@code T}. A Bloom filter offers an approximate containment test - * with one-sided error: if it claims that an element is contained in it, this might be in error, - * but if it claims that an element is not contained in it, then this is definitely true. + * A Bloom filter for instances of {@code T}. A Bloom filter offers an + * approximate containment test + * with one-sided error: if it claims that an element is contained in it, this + * might be in error, + * but if it claims that an element is not contained in it, then this is + * definitely true. * - *

If you are unfamiliar with Bloom filters, this nice tutorial may help you understand how + *

+ * If you are unfamiliar with Bloom filters, this nice tutorial may help + * you understand how * they work. * - *

The false positive probability ({@code FPP}) of a Bloom filter is defined as the probability - * that {@linkplain #mightContain(Object)} will erroneously return {@code true} for an object that + *

+ * The false positive probability ({@code FPP}) of a Bloom filter is defined as + * the probability + * that {@linkplain #mightContain(Object)} will erroneously return {@code true} + * for an object that * has not actually been put in the {@code BloomFilter}. * - *

Bloom filters are serializable. They also support a more compact serial representation via the - * {@link #writeTo} and {@link #readFrom} methods. Both serialized forms will continue to be - * supported by future versions of this library. However, serial forms generated by newer versions - * of the code may not be readable by older versions of the code (e.g., a serialized Bloom filter - * generated today may not be readable by a binary that was compiled 6 months ago). + *

+ * Bloom filters are serializable. They also support a more compact serial + * representation via the + * {@link #writeTo} and {@link #readFrom} methods. Both serialized forms will + * continue to be + * supported by future versions of this library. However, serial forms generated + * by newer versions + * of the code may not be readable by older versions of the code (e.g., a + * serialized Bloom filter + * generated today may not be readable by a binary that was compiled 6 + * months ago). * - *

As of Guava 23.0, this class is thread-safe and lock-free. It internally uses atomics and - * compare-and-swap to ensure correctness when multiple threads are used to access it. + *

+ * As of Guava 23.0, this class is thread-safe and lock-free. It internally uses + * atomics and + * compare-and-swap to ensure correctness when multiple threads are used to + * access it. * * @param the type of instances that the {@code BloomFilter} accepts * @author Dimitris Andreou @@ -73,14 +90,17 @@ public final class BloomFilter implements Predicate< /** * A strategy to translate T instances, to {@code numHashFunctions} bit indexes. * - *

Implementations should be collections of pure functions (i.e. stateless). + *

+ * Implementations should be collections of pure functions (i.e. stateless). */ interface Strategy extends java.io.Serializable { /** - * Sets {@code numHashFunctions} bits of the given bit array, by hashing a user element. + * Sets {@code numHashFunctions} bits of the given bit array, by hashing a user + * element. * - *

Returns whether any bits changed as a result of this operation. + *

+ * Returns whether any bits changed as a result of this operation. */ boolean put( @ParametricNullness T object, @@ -89,7 +109,8 @@ interface Strategy extends java.io.Serializable { LockFreeBitArray bits); /** - * Queries {@code numHashFunctions} bits of the given bit array, by hashing a user element; + * Queries {@code numHashFunctions} bits of the given bit array, by hashing a + * user element; * returns {@code true} if and only if all selected bits are set. */ boolean mightContain( @@ -99,10 +120,14 @@ interface Strategy extends java.io.Serializable { LockFreeBitArray bits); /** - * Identifier used to encode this strategy, when marshalled as part of a BloomFilter. Only - * values in the [-128, 127] range are valid for the compact serial form. Non-negative values - * are reserved for enums defined in BloomFilterStrategies; negative values are reserved for any - * custom, stateful strategy we may define (e.g. any kind of strategy that would depend on user + * Identifier used to encode this strategy, when marshalled as part of a + * BloomFilter. Only + * values in the [-128, 127] range are valid for the compact serial form. + * Non-negative values + * are reserved for enums defined in BloomFilterStrategies; negative values are + * reserved for any + * custom, stateful strategy we may define (e.g. any kind of strategy that would + * depend on user * input). */ int ordinal(); @@ -117,7 +142,10 @@ interface Strategy extends java.io.Serializable { /** The funnel to translate Ts to bytes */ private final Funnel funnel; - /** The strategy we employ to map an element T to {@code numHashFunctions} bit indexes. */ + /** + * The strategy we employ to map an element T to {@code numHashFunctions} bit + * indexes. + */ private final Strategy strategy; /** Creates a BloomFilter. */ @@ -133,7 +161,8 @@ private BloomFilter( } /** - * Creates a new {@code BloomFilter} that's a copy of this instance. The new instance is equal to + * Creates a new {@code BloomFilter} that's a copy of this instance. The new + * instance is equal to * this instance but shares no mutable state. * * @since 12.0 @@ -143,7 +172,8 @@ public BloomFilter copy() { } /** - * Returns {@code true} if the element might have been put in this Bloom filter, {@code + * Returns {@code true} if the element might have been put in this Bloom + * filter, {@code * false} if this is definitely not the case. */ public boolean mightContain(@ParametricNullness T object) { @@ -151,8 +181,9 @@ public boolean mightContain(@ParametricNullness T object) { } /** - * @deprecated Provided only to satisfy the {@link Predicate} interface; use {@link #mightContain} - * instead. + * @deprecated Provided only to satisfy the {@link Predicate} interface; use + * {@link #mightContain} + * instead. */ @Deprecated @Override @@ -161,14 +192,20 @@ public boolean apply(@ParametricNullness T input) { } /** - * Puts an element into this {@code BloomFilter}. Ensures that subsequent invocations of {@link + * Puts an element into this {@code BloomFilter}. Ensures that subsequent + * invocations of {@link * #mightContain(Object)} with the same element will always return {@code true}. * - * @return true if the Bloom filter's bits changed as a result of this operation. If the bits - * changed, this is definitely the first time {@code object} has been added to the - * filter. If the bits haven't changed, this might be the first time {@code object} has - * been added to the filter. Note that {@code put(t)} always returns the opposite - * result to what {@code mightContain(t)} would have returned at the time it is called. + * @return true if the Bloom filter's bits changed as a result of this + * operation. If the bits + * changed, this is definitely the first time {@code object} has + * been added to the + * filter. If the bits haven't changed, this might be the first + * time {@code object} has + * been added to the filter. Note that {@code put(t)} always returns the + * opposite + * result to what {@code mightContain(t)} would have returned at the + * time it is called. * @since 12.0 (present in 11.0 with {@code void} return type}) */ @CanIgnoreReturnValue @@ -177,12 +214,18 @@ public boolean put(@ParametricNullness T object) { } /** - * 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}. - * - *

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}, + * 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}. + * + *

+ * 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()) @@ -192,8 +235,10 @@ public double expectedFpp() { } /** - * Returns an estimate for the total number of distinct elements that have been added to this - * Bloom filter. This approximation is reasonably accurate if it does not exceed the value of + * Returns an estimate for the total number of distinct elements that have been + * added to this + * Bloom filter. This approximation is reasonably accurate if it does not exceed + * the value of * {@code expectedInsertions} that was used when constructing the filter. * * @since 22.0 @@ -204,8 +249,10 @@ public long approximateElementCount() { /** * Each insertion is expected to reduce the # of clear bits by a factor of - * `numHashFunctions/bitSize`. So, after n insertions, expected bitCount is `bitSize * (1 - (1 - - * numHashFunctions/bitSize)^n)`. Solving that for n, and approximating `ln x` as `x - 1` when x + * `numHashFunctions/bitSize`. So, after n insertions, expected bitCount is + * `bitSize * (1 - (1 - + * numHashFunctions/bitSize)^n)`. Solving that for n, and approximating `ln x` + * as `x - 1` when x * is close to 1 (why?), gives the following formula. */ double fractionOfBitsSet = (double) bitCount / bitSize; @@ -215,20 +262,21 @@ public long approximateElementCount() { /** Returns the number of bits in the underlying bit array. */ @VisibleForTesting - long bitSize() { + Public long bitSize() { return bits.bitSize(); } /** - * Determines whether a given Bloom filter is compatible with this Bloom filter. For two Bloom + * Determines whether a given Bloom filter is compatible with this Bloom filter. + * For two Bloom * filters to be compatible, they must: * *

* * @param that The Bloom filter to check for compatibility. @@ -244,11 +292,14 @@ public boolean isCompatible(BloomFilter that) { } /** - * Combines this Bloom filter with another Bloom filter by performing a bitwise OR of the - * underlying data. The mutations happen to this instance. Callers must ensure the Bloom + * Combines this Bloom filter with another Bloom filter by performing a bitwise + * OR of the + * underlying data. The mutations happen to this 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. + * @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 */ @@ -299,24 +350,36 @@ public int hashCode() { } /** - * Returns a {@code Collector} expecting the specified number of insertions, and yielding a {@link + * Returns a {@code Collector} expecting the specified number of insertions, and + * yielding a {@link * BloomFilter} with false positive probability 3%. * - *

Note that if the {@code Collector} receives significantly more elements than specified, the - * resulting {@code BloomFilter} will suffer a sharp deterioration of its false positive + *

+ * Note that if the {@code Collector} receives significantly more elements than + * specified, the + * resulting {@code BloomFilter} will suffer a sharp deterioration of its false + * positive * probability. * - *

The constructed {@code BloomFilter} will be serializable if the provided {@code Funnel} + *

+ * The constructed {@code BloomFilter} will be serializable if the provided + * {@code Funnel} * is. * - *

It is recommended that the funnel be implemented as a Java enum. This has the benefit of - * ensuring proper serialization and deserialization, which is important since {@link #equals} + *

+ * It is recommended that the funnel be implemented as a Java enum. This has the + * benefit of + * ensuring proper serialization and deserialization, which is important since + * {@link #equals} * also relies on object identity of funnels. * - * @param funnel the funnel of T's that the constructed {@code BloomFilter} will use - * @param expectedInsertions the number of expected insertions to the constructed {@code - * BloomFilter}; must be positive - * @return a {@code Collector} generating a {@code BloomFilter} of the received elements + * @param funnel the funnel of T's that the constructed + * {@code BloomFilter} will use + * @param expectedInsertions the number of expected insertions to the + * constructed {@code + * BloomFilter} ; must be positive + * @return a {@code Collector} generating a {@code BloomFilter} of the received + * elements * @since 23.0 */ public static Collector> toBloomFilter( @@ -325,25 +388,38 @@ public int hashCode() { } /** - * Returns a {@code Collector} expecting the specified number of insertions, and yielding a {@link + * Returns a {@code Collector} expecting the specified number of insertions, and + * yielding a {@link * BloomFilter} with the specified expected false positive probability. * - *

Note that if the {@code Collector} receives significantly more elements than specified, the - * resulting {@code BloomFilter} will suffer a sharp deterioration of its false positive + *

+ * Note that if the {@code Collector} receives significantly more elements than + * specified, the + * resulting {@code BloomFilter} will suffer a sharp deterioration of its false + * positive * probability. * - *

The constructed {@code BloomFilter} will be serializable if the provided {@code Funnel} + *

+ * The constructed {@code BloomFilter} will be serializable if the provided + * {@code Funnel} * is. * - *

It is recommended that the funnel be implemented as a Java enum. This has the benefit of - * ensuring proper serialization and deserialization, which is important since {@link #equals} + *

+ * It is recommended that the funnel be implemented as a Java enum. This has the + * benefit of + * ensuring proper serialization and deserialization, which is important since + * {@link #equals} * also relies on object identity of funnels. * - * @param funnel the funnel of T's that the constructed {@code BloomFilter} will use - * @param expectedInsertions the number of expected insertions to the constructed {@code - * BloomFilter}; must be positive - * @param fpp the desired false positive probability (must be positive and less than 1.0) - * @return a {@code Collector} generating a {@code BloomFilter} of the received elements + * @param funnel the funnel of T's that the constructed + * {@code BloomFilter} will use + * @param expectedInsertions the number of expected insertions to the + * constructed {@code + * BloomFilter} ; must be positive + * @param fpp the desired false positive probability (must be + * positive and less than 1.0) + * @return a {@code Collector} generating a {@code BloomFilter} of the received + * elements * @since 23.0 */ public static Collector> toBloomFilter( @@ -365,23 +441,35 @@ public int hashCode() { } /** - * Creates a {@link BloomFilter} with the expected number of insertions and expected false + * Creates a {@link BloomFilter} with the expected number of insertions and + * expected false * positive probability. * - *

Note that overflowing a {@code BloomFilter} with significantly more elements than specified, - * will result in its saturation, and a sharp deterioration of its false positive probability. + *

+ * Note that overflowing a {@code BloomFilter} with significantly more elements + * than specified, + * will result in its saturation, and a sharp deterioration of its false + * positive probability. * - *

The constructed {@code BloomFilter} will be serializable if the provided {@code Funnel} + *

+ * The constructed {@code BloomFilter} will be serializable if the provided + * {@code Funnel} * is. * - *

It is recommended that the funnel be implemented as a Java enum. This has the benefit of - * ensuring proper serialization and deserialization, which is important since {@link #equals} + *

+ * It is recommended that the funnel be implemented as a Java enum. This has the + * benefit of + * ensuring proper serialization and deserialization, which is important since + * {@link #equals} * also relies on object identity of funnels. * - * @param funnel the funnel of T's that the constructed {@code BloomFilter} will use - * @param expectedInsertions the number of expected insertions to the constructed {@code - * BloomFilter}; must be positive - * @param fpp the desired false positive probability (must be positive and less than 1.0) + * @param funnel the funnel of T's that the constructed + * {@code BloomFilter} will use + * @param expectedInsertions the number of expected insertions to the + * constructed {@code + * BloomFilter} ; must be positive + * @param fpp the desired false positive probability (must be + * positive and less than 1.0) * @return a {@code BloomFilter} */ public static BloomFilter create( @@ -390,23 +478,35 @@ public int hashCode() { } /** - * Creates a {@link BloomFilter} with the expected number of insertions and expected false + * Creates a {@link BloomFilter} with the expected number of insertions and + * expected false * positive probability. * - *

Note that overflowing a {@code BloomFilter} with significantly more elements than specified, - * will result in its saturation, and a sharp deterioration of its false positive probability. + *

+ * Note that overflowing a {@code BloomFilter} with significantly more elements + * than specified, + * will result in its saturation, and a sharp deterioration of its false + * positive probability. * - *

The constructed {@code BloomFilter} will be serializable if the provided {@code Funnel} + *

+ * The constructed {@code BloomFilter} will be serializable if the provided + * {@code Funnel} * is. * - *

It is recommended that the funnel be implemented as a Java enum. This has the benefit of - * ensuring proper serialization and deserialization, which is important since {@link #equals} + *

+ * It is recommended that the funnel be implemented as a Java enum. This has the + * benefit of + * ensuring proper serialization and deserialization, which is important since + * {@link #equals} * also relies on object identity of funnels. * - * @param funnel the funnel of T's that the constructed {@code BloomFilter} will use - * @param expectedInsertions the number of expected insertions to the constructed {@code - * BloomFilter}; must be positive - * @param fpp the desired false positive probability (must be positive and less than 1.0) + * @param funnel the funnel of T's that the constructed + * {@code BloomFilter} will use + * @param expectedInsertions the number of expected insertions to the + * constructed {@code + * BloomFilter} ; must be positive + * @param fpp the desired false positive probability (must be + * positive and less than 1.0) * @return a {@code BloomFilter} * @since 19.0 */ @@ -429,9 +529,11 @@ public int hashCode() { expectedInsertions = 1; } /* - * TODO(user): Put a warning in the javadoc about tiny fpp values, since the resulting size + * 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! + * optimalM(1000, 0.0000000000000001) = 76680 which is less than 10kb. Who + * cares! */ long numBits = optimalNumOfBits(expectedInsertions, fpp); int numHashFunctions = optimalNumOfHashFunctions(expectedInsertions, numBits); @@ -443,22 +545,33 @@ public int hashCode() { } /** - * Creates a {@link BloomFilter} with the expected number of insertions and a default expected + * Creates a {@link BloomFilter} with the expected number of insertions and a + * default expected * false positive probability of 3%. * - *

Note that overflowing a {@code BloomFilter} with significantly more elements than specified, - * will result in its saturation, and a sharp deterioration of its false positive probability. + *

+ * Note that overflowing a {@code BloomFilter} with significantly more elements + * than specified, + * will result in its saturation, and a sharp deterioration of its false + * positive probability. * - *

The constructed {@code BloomFilter} will be serializable if the provided {@code Funnel} + *

+ * The constructed {@code BloomFilter} will be serializable if the provided + * {@code Funnel} * is. * - *

It is recommended that the funnel be implemented as a Java enum. This has the benefit of - * ensuring proper serialization and deserialization, which is important since {@link #equals} + *

+ * It is recommended that the funnel be implemented as a Java enum. This has the + * benefit of + * ensuring proper serialization and deserialization, which is important since + * {@link #equals} * also relies on object identity of funnels. * - * @param funnel the funnel of T's that the constructed {@code BloomFilter} will use - * @param expectedInsertions the number of expected insertions to the constructed {@code - * BloomFilter}; must be positive + * @param funnel the funnel of T's that the constructed + * {@code BloomFilter} will use + * @param expectedInsertions the number of expected insertions to the + * constructed {@code + * BloomFilter} ; must be positive * @return a {@code BloomFilter} */ public static BloomFilter create( @@ -467,22 +580,33 @@ public int hashCode() { } /** - * Creates a {@link BloomFilter} with the expected number of insertions and a default expected + * Creates a {@link BloomFilter} with the expected number of insertions and a + * default expected * false positive probability of 3%. * - *

Note that overflowing a {@code BloomFilter} with significantly more elements than specified, - * will result in its saturation, and a sharp deterioration of its false positive probability. + *

+ * Note that overflowing a {@code BloomFilter} with significantly more elements + * than specified, + * will result in its saturation, and a sharp deterioration of its false + * positive probability. * - *

The constructed {@code BloomFilter} will be serializable if the provided {@code Funnel} + *

+ * The constructed {@code BloomFilter} will be serializable if the provided + * {@code Funnel} * is. * - *

It is recommended that the funnel be implemented as a Java enum. This has the benefit of - * ensuring proper serialization and deserialization, which is important since {@link #equals} + *

+ * It is recommended that the funnel be implemented as a Java enum. This has the + * benefit of + * ensuring proper serialization and deserialization, which is important since + * {@link #equals} * also relies on object identity of funnels. * - * @param funnel the funnel of T's that the constructed {@code BloomFilter} will use - * @param expectedInsertions the number of expected insertions to the constructed {@code - * BloomFilter}; must be positive + * @param funnel the funnel of T's that the constructed + * {@code BloomFilter} will use + * @param expectedInsertions the number of expected insertions to the + * constructed {@code + * BloomFilter} ; must be positive * @return a {@code BloomFilter} * @since 19.0 */ @@ -504,10 +628,13 @@ public int hashCode() { // 4) For optimal k: m = -nlnp / ((ln2) ^ 2) /** - * Computes the optimal k (number of hashes per element inserted in Bloom filter), given the + * Computes the optimal k (number of hashes per element inserted in Bloom + * filter), given the * expected insertions and total number of bits in the Bloom filter. * - *

See http://en.wikipedia.org/wiki/File:Bloom_filter_fp_probability.svg for the formula. + *

+ * See http://en.wikipedia.org/wiki/File:Bloom_filter_fp_probability.svg for the + * formula. * * @param n expected insertions (must be positive) * @param m total number of bits in Bloom filter (must be positive) @@ -519,10 +646,13 @@ static int optimalNumOfHashFunctions(long n, long m) { } /** - * Computes m (total bits of Bloom filter) which is expected to achieve, for the specified + * Computes m (total bits of Bloom filter) which is expected to achieve, for the + * specified * expected insertions, the required false positive probability. * - *

See http://en.wikipedia.org/wiki/Bloom_filter#Probability_of_false_positives for the + *

+ * See http://en.wikipedia.org/wiki/Bloom_filter#Probability_of_false_positives + * for the * formula. * * @param n expected insertions (must be positive) @@ -565,11 +695,15 @@ Object readResolve() { } /** - * Writes this {@code BloomFilter} to an output stream, with a custom format (not Java - * serialization). This has been measured to save at least 400 bytes compared to regular + * Writes this {@code BloomFilter} to an output stream, with a custom format + * (not Java + * serialization). This has been measured to save at least 400 bytes compared to + * regular * serialization. * - *

Use {@linkplain #readFrom(InputStream, Funnel)} to reconstruct the written BloomFilter. + *

+ * Use {@linkplain #readFrom(InputStream, Funnel)} to reconstruct the written + * BloomFilter. */ public void writeTo(OutputStream out) throws IOException { // Serial form: @@ -587,15 +721,21 @@ public void writeTo(OutputStream out) throws IOException { } /** - * Reads a byte stream, which was written by {@linkplain #writeTo(OutputStream)}, into a {@code + * Reads a byte stream, which was written by + * {@linkplain #writeTo(OutputStream)}, into a {@code * BloomFilter}. * - *

The {@code Funnel} to be used is not encoded in the stream, so it must be provided here. - * Warning: the funnel provided must behave identically to the one used to populate + *

+ * The {@code Funnel} to be used is not encoded in the stream, so it must be + * provided here. + * Warning: the funnel provided must behave identically to the one + * used to populate * the original Bloom filter! * - * @throws IOException if the InputStream throws an {@code IOException}, or if its data does not - * appear to be a BloomFilter serialized using the {@linkplain #writeTo(OutputStream)} method. + * @throws IOException if the InputStream throws an {@code IOException}, or if + * its data does not + * appear to be a BloomFilter serialized using the + * {@linkplain #writeTo(OutputStream)} method. */ @SuppressWarnings("CatchingUnchecked") // sneaky checked exception public static BloomFilter readFrom( @@ -607,7 +747,8 @@ public void writeTo(OutputStream out) throws IOException { int dataLength = -1; try { DataInputStream din = new DataInputStream(in); - // currently this assumes there is no negative ordinal; will have to be updated if we + // currently this assumes there is no negative ordinal; will have to be updated + // if we // add non-stateless strategies (for which we've reserved negative ordinals; see // Strategy.ordinal()). strategyOrdinal = din.readByte(); @@ -625,14 +766,13 @@ public void writeTo(OutputStream out) throws IOException { } catch (IOException e) { throw e; } catch (Exception e) { // sneaky checked exception - String message = - "Unable to deserialize BloomFilter from InputStream." - + " strategyOrdinal: " - + strategyOrdinal - + " numHashFunctions: " - + numHashFunctions - + " dataLength: " - + dataLength; + String message = "Unable to deserialize BloomFilter from InputStream." + + " strategyOrdinal: " + + strategyOrdinal + + " numHashFunctions: " + + numHashFunctions + + " dataLength: " + + dataLength; throw new IOException(message, e); } }