Skip to content

Commit 8e8d2d4

Browse files
committed
Random improvements.
1 parent 2573baa commit 8e8d2d4

File tree

6 files changed

+160
-107
lines changed

6 files changed

+160
-107
lines changed

firebase-firestore/src/androidTest/java/com/google/firebase/firestore/QueryTest.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
import java.util.Map;
5151
import java.util.concurrent.Semaphore;
5252
import java.util.concurrent.atomic.AtomicReference;
53-
5453
import org.junit.After;
5554
import org.junit.Test;
5655
import org.junit.runner.RunWith;
@@ -1092,11 +1091,11 @@ public void resumingAQueryShouldUseBloomFilterToAvoidFullRequery() throws Except
10921091
// bloom filter, and it was used to avert a full requery.
10931092
AtomicReference<QuerySnapshot> snapshot2Ref = new AtomicReference<>();
10941093
ArrayList<ExistenceFilterMismatchInfo> existenceFilterMismatches =
1095-
captureExistenceFilterMismatches(
1096-
() -> {
1097-
QuerySnapshot querySnapshot = waitFor(collection.get());
1098-
snapshot2Ref.set(querySnapshot);
1099-
});
1094+
captureExistenceFilterMismatches(
1095+
() -> {
1096+
QuerySnapshot querySnapshot = waitFor(collection.get());
1097+
snapshot2Ref.set(querySnapshot);
1098+
});
11001099
QuerySnapshot snapshot2 = snapshot2Ref.get();
11011100

11021101
// Verify that the snapshot from the resumed query contains the expected documents; that is,
@@ -1132,8 +1131,8 @@ public void resumingAQueryShouldUseBloomFilterToAvoidFullRequery() throws Except
11321131
// Verify that Watch sent an existence filter with the correct counts when the query was
11331132
// resumed.
11341133
assertWithMessage("Watch should have sent exactly 1 existence filter")
1135-
.that(existenceFilterMismatches)
1136-
.hasSize(1);
1134+
.that(existenceFilterMismatches)
1135+
.hasSize(1);
11371136
ExistenceFilterMismatchInfo existenceFilterMismatchInfo = existenceFilterMismatches.get(0);
11381137
assertWithMessage("localCacheCount")
11391138
.that(existenceFilterMismatchInfo.localCacheCount())

firebase-firestore/src/androidTest/java/com/google/firebase/firestore/remote/TestingHooksUtil.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
import androidx.annotation.NonNull;
1818
import androidx.annotation.Nullable;
19-
2019
import com.google.firebase.firestore.ListenerRegistration;
2120
import java.util.ArrayList;
2221

firebase-firestore/src/main/java/com/google/firebase/firestore/remote/BloomFilter.java

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,42 +17,82 @@
1717
import android.util.Base64;
1818
import androidx.annotation.NonNull;
1919
import androidx.annotation.VisibleForTesting;
20+
import com.google.protobuf.ByteString;
2021
import java.nio.charset.StandardCharsets;
2122
import java.security.MessageDigest;
2223
import java.security.NoSuchAlgorithmException;
2324

24-
public class BloomFilter {
25+
public final class BloomFilter {
2526
private final int bitCount;
26-
private final byte[] bitmap;
27+
private final ByteString bitmap;
2728
private final int hashCount;
2829
private final MessageDigest md5HashMessageDigest;
2930

30-
public BloomFilter(@NonNull byte[] bitmap, int padding, int hashCount) {
31-
if (bitmap == null) {
32-
throw new NullPointerException("Bitmap cannot be null.");
33-
}
31+
/**
32+
* Creates a new {@link BloomFilter} with the given parameters.
33+
*
34+
* @param bitmap the bitmap of the bloom filter; must not be null.
35+
* @param padding the padding, in bits, of the last byte of the bloom filter; must be between 0
36+
* (zero) and 7, inclusive; must be 0 (zero) if {@code bitmap.length==0}.
37+
* @param hashCount The number of hash functions to use; must be strictly greater than zero; may
38+
* be 0 (zero) if and only if {@code bitmap.length==0}.
39+
*/
40+
public BloomFilter(@NonNull ByteString bitmap, int padding, int hashCount) {
3441
if (padding < 0 || padding >= 8) {
35-
throw new BloomFilterException("Invalid padding: " + padding);
42+
throw new IllegalArgumentException("Invalid padding: " + padding);
3643
}
3744
if (hashCount < 0) {
38-
throw new BloomFilterException("Invalid hash count: " + hashCount);
45+
throw new IllegalArgumentException("Invalid hash count: " + hashCount);
3946
}
40-
if (bitmap.length > 0 && hashCount == 0) {
47+
if (bitmap.size() > 0 && hashCount == 0) {
4148
// Only empty bloom filter can have 0 hash count.
42-
throw new BloomFilterException("Invalid hash count: " + hashCount);
49+
throw new IllegalArgumentException("Invalid hash count: " + hashCount);
4350
}
44-
if (bitmap.length == 0 && padding != 0) {
51+
if (bitmap.size() == 0 && padding != 0) {
4552
// Empty bloom filter should have 0 padding.
46-
throw new BloomFilterException(
53+
throw new IllegalArgumentException(
4754
"Expected padding of 0 when bitmap length is 0, but got " + padding);
4855
}
4956

5057
this.bitmap = bitmap;
5158
this.hashCount = hashCount;
52-
this.bitCount = bitmap.length * 8 - padding;
59+
this.bitCount = bitmap.size() * 8 - padding;
5360
this.md5HashMessageDigest = createMd5HashMessageDigest();
5461
}
5562

63+
/**
64+
* Creates an instance of {@link BloomFilter} with the given arguments, throwing a well-defined
65+
* exception if the given arguments do not satisfy the requirements documented in the {@link
66+
* BloomFilter} constructor.
67+
*/
68+
public static BloomFilter create(@NonNull ByteString bitmap, int padding, int hashCount)
69+
throws BloomFilterCreateException {
70+
if (padding < 0 || padding >= 8) {
71+
throw new BloomFilterCreateException("Invalid padding: " + padding);
72+
}
73+
if (hashCount < 0) {
74+
throw new BloomFilterCreateException("Invalid hash count: " + hashCount);
75+
}
76+
if (bitmap.size() > 0 && hashCount == 0) {
77+
// Only empty bloom filter can have 0 hash count.
78+
throw new BloomFilterCreateException("Invalid hash count: " + hashCount);
79+
}
80+
if (bitmap.size() == 0 && padding != 0) {
81+
// Empty bloom filter should have 0 padding.
82+
throw new BloomFilterCreateException(
83+
"Expected padding of 0 when bitmap length is 0, but got " + padding);
84+
}
85+
86+
return new BloomFilter(bitmap, padding, hashCount);
87+
}
88+
89+
/** Exception thrown by {@link #create} if the given arguments are not valid. */
90+
public static final class BloomFilterCreateException extends Exception {
91+
public BloomFilterCreateException(String message) {
92+
super(message);
93+
}
94+
}
95+
5696
@VisibleForTesting
5797
int getBitCount() {
5898
return this.bitCount;
@@ -146,7 +186,7 @@ private static long unsignedRemainder(long dividend, long divisor) {
146186
/** Return whether the bit at the given index in the bitmap is set to 1. */
147187
private boolean isBitSet(int index) {
148188
// To retrieve bit n, calculate: (bitmap[n / 8] & (0x01 << (n % 8))).
149-
byte byteAtIndex = this.bitmap[index / 8];
189+
byte byteAtIndex = this.bitmap.byteAt(index / 8);
150190
int offset = index % 8;
151191
return (byteAtIndex & (0x01 << offset)) != 0;
152192
}
@@ -159,7 +199,7 @@ public String toString() {
159199
+ ", size="
160200
+ bitCount
161201
+ ", bitmap=\""
162-
+ Base64.encodeToString(bitmap, Base64.NO_WRAP)
202+
+ Base64.encodeToString(bitmap.toByteArray(), Base64.NO_WRAP)
163203
+ "\"}";
164204
}
165205
}

firebase-firestore/src/main/java/com/google/firebase/firestore/remote/BloomFilterException.java

Lines changed: 0 additions & 23 deletions
This file was deleted.

firebase-firestore/src/main/java/com/google/firebase/firestore/remote/WatchChangeAggregator.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.google.firebase.firestore.remote.WatchChange.ExistenceFilterWatchChange;
3232
import com.google.firebase.firestore.remote.WatchChange.WatchTargetChange;
3333
import com.google.firebase.firestore.util.Logger;
34+
import com.google.protobuf.ByteString;
3435
import java.util.ArrayList;
3536
import java.util.Collection;
3637
import java.util.Collections;
@@ -252,14 +253,14 @@ private BloomFilterApplicationStatus applyBloomFilter(
252253
return BloomFilterApplicationStatus.SKIPPED;
253254
}
254255

255-
byte[] bitmap = unchangedNames.getBits().getBitmap().toByteArray();
256+
ByteString bitmap = unchangedNames.getBits().getBitmap();
256257
BloomFilter bloomFilter;
257258

258259
try {
259260
bloomFilter =
260-
new BloomFilter(
261+
BloomFilter.create(
261262
bitmap, unchangedNames.getBits().getPadding(), unchangedNames.getHashCount());
262-
} catch (BloomFilterException e) {
263+
} catch (BloomFilter.BloomFilterCreateException e) {
263264
Logger.warn(
264265
LOG_TAG,
265266
"Applying bloom filter failed: ("

0 commit comments

Comments
 (0)