Skip to content

Commit 44e03bf

Browse files
committed
resolve comments
1 parent 66bfff9 commit 44e03bf

File tree

8 files changed

+78
-56
lines changed

8 files changed

+78
-56
lines changed

firebase-firestore/src/main/java/com/google/firebase/firestore/model/DatabaseId.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,6 @@ public String getDatabaseId() {
6060
return databaseId;
6161
}
6262

63-
public String canonicalString() {
64-
return "projects/" + projectId + "/databases/" + databaseId;
65-
}
66-
6763
@Override
6864
public String toString() {
6965
return "DatabaseId(" + projectId + ", " + databaseId + ")";

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,10 @@ private static long getLongLittleEndian(@NonNull byte[] bytes, int offset) {
122122
*/
123123
private int getBitIndex(long hash1, long hash2, int hashIndex) {
124124
// Calculate hashed value h(i) = h1 + (i * h2).
125-
// Even though we are interpreting hash1 and hash2 as unsigned, the addition and multiplication
126-
// operators still perform the correct operation and give the desired overflow behavior.
125+
// Even though we are interpreting hash1 and hash2 as unsigned, the addition and
126+
// multiplication
127+
// operators still perform the correct operation and give the desired overflow
128+
// behavior.
127129
long combinedHash = hash1 + (hash2 * hashIndex);
128130
long modulo = unsignedRemainder(combinedHash, this.bitCount);
129131
return (int) modulo;
@@ -132,8 +134,8 @@ private int getBitIndex(long hash1, long hash2, int hashIndex) {
132134
/**
133135
* Calculate modulo, where the dividend and divisor are treated as unsigned 64-bit longs.
134136
*
135-
* <p>The implementation is taken from <a
136-
* href="https://github.com/google/guava/blob/553037486901cc60820ab7dcb38a25b6f34eba43/android/guava/src/com/google/common/primitives/UnsignedLongs.java">Guava</a>,
137+
* <p>The implementation is taken from <a href=
138+
* "https://github.com/google/guava/blob/553037486901cc60820ab7dcb38a25b6f34eba43/android/guava/src/com/google/common/primitives/UnsignedLongs.java">Guava</a>,
137139
* simplified to our needs.
138140
*
139141
* <p>

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

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

1717
import androidx.annotation.NonNull;
1818

19-
public class BloomFilterException extends Exception {
19+
public class BloomFilterException extends RuntimeException {
2020
public BloomFilterException(@NonNull String detailMessage) {
2121
super(detailMessage);
2222
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public ExistenceFilter(int count) {
2626
this.count = count;
2727
}
2828

29-
public ExistenceFilter(int count, BloomFilter unchangedNames) {
29+
public ExistenceFilter(int count, @Nullable BloomFilter unchangedNames) {
3030
this.count = count;
3131
this.unchangedNames = unchangedNames;
3232
}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -945,7 +945,6 @@ public WatchChange decodeWatchChange(ListenResponse protoChange) {
945945
break;
946946
case FILTER:
947947
com.google.firestore.v1.ExistenceFilter protoFilter = protoChange.getFilter();
948-
// TODO: implement existence filter parsing (see b/33076578)
949948
ExistenceFilter filter =
950949
new ExistenceFilter(protoFilter.getCount(), protoFilter.getUnchangedNames());
951950
int targetId = protoFilter.getTargetId();

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -235,12 +235,9 @@ private boolean applyBloomFilter(ExistenceFilterWatchChange watchChange, int cur
235235
bloomFilter =
236236
new BloomFilter(
237237
bitmap, unchangedNames.getBits().getPadding(), unchangedNames.getHashCount());
238-
} catch (Exception e) {
238+
} catch (BloomFilterException e) {
239239
if (e instanceof BloomFilterException) {
240240
Logger.warn("Firestore", "BloomFilter error: %s", e);
241-
242-
} else {
243-
Logger.warn("Firestore", "Applying bloom filter failed: %s", e);
244241
}
245242
return false;
246243
}
@@ -259,8 +256,12 @@ private int filterRemovedDocuments(BloomFilter bloomFilter, int targetId) {
259256
targetMetadataProvider.getRemoteKeysForTarget(targetId);
260257
int removalCount = 0;
261258
for (DocumentKey key : existingKeys) {
259+
DatabaseId databaseId = targetMetadataProvider.getDatabaseId();
262260
String documentPath =
263-
targetMetadataProvider.getDatabaseId().canonicalString()
261+
"projects/"
262+
+ databaseId.getProjectId()
263+
+ "/databases/"
264+
+ databaseId.getDatabaseId()
264265
+ "/documents/"
265266
+ key.getPath().canonicalString();
266267
if (!bloomFilter.mightContain(documentPath)) {

firebase-firestore/src/test/java/com/google/firebase/firestore/remote/BloomFilterTest.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ public class BloomFilterTest {
4141
"src/test/resources/bloom_filter_golden_test_data/";
4242

4343
@Test
44-
public void instantiateEmptyBloomFilter() throws BloomFilterException {
44+
public void instantiateEmptyBloomFilter() {
4545
BloomFilter bloomFilter = new BloomFilter(new byte[0], 0, 0);
4646
assertEquals(bloomFilter.getBitCount(), 0);
4747
}
4848

4949
@Test
50-
public void instantiateNonEmptyBloomFilter() throws BloomFilterException {
50+
public void instantiateNonEmptyBloomFilter() {
5151
{
5252
BloomFilter bloomFilter1 = new BloomFilter(new byte[] {1}, 0, 1);
5353
assertEquals(bloomFilter1.getBitCount(), 8);
@@ -124,23 +124,22 @@ public void constructorShouldThrowBFEIfPaddingIsTooLarge() {
124124
}
125125

126126
@Test
127-
public void mightContainCanProcessNonStandardCharacters() throws BloomFilterException {
127+
public void mightContainCanProcessNonStandardCharacters() {
128128
// A non-empty BloomFilter object with 1 insertion : "ÀÒ∑"
129129
BloomFilter bloomFilter = new BloomFilter(new byte[] {(byte) 237, 5}, 5, 8);
130130
assertTrue(bloomFilter.mightContain("ÀÒ∑"));
131131
assertFalse(bloomFilter.mightContain("Ò∑À"));
132132
}
133133

134134
@Test
135-
public void mightContainOnEmptyBloomFilterShouldReturnFalse() throws BloomFilterException {
135+
public void mightContainOnEmptyBloomFilterShouldReturnFalse() {
136136
BloomFilter bloomFilter = new BloomFilter(new byte[0], 0, 0);
137137
assertFalse(bloomFilter.mightContain(""));
138138
assertFalse(bloomFilter.mightContain("a"));
139139
}
140140

141141
@Test
142-
public void mightContainWithEmptyStringMightReturnFalsePositiveResult()
143-
throws BloomFilterException {
142+
public void mightContainWithEmptyStringMightReturnFalsePositiveResult() {
144143
{
145144
BloomFilter bloomFilter1 = new BloomFilter(new byte[] {1}, 1, 1);
146145
assertFalse(bloomFilter1.mightContain(""));
@@ -152,7 +151,7 @@ public void mightContainWithEmptyStringMightReturnFalsePositiveResult()
152151
}
153152

154153
@Test
155-
public void bloomFilterToString() throws BloomFilterException {
154+
public void bloomFilterToString() {
156155
{
157156
BloomFilter emptyBloomFilter = new BloomFilter(new byte[0], 0, 0);
158157
assertEquals(emptyBloomFilter.toString(), "BloomFilter{hashCount=0, size=0, bitmap=\"\"}");

firebase-firestore/src/test/java/com/google/firebase/firestore/spec/SpecTestCase.java

Lines changed: 58 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -143,18 +143,27 @@ public abstract class SpecTestCase implements RemoteStoreCallback {
143143
// this tag and they'll all be run (but all others won't).
144144
private static final String EXCLUSIVE_TAG = "exclusive";
145145

146-
// The name of a Java system property ({@link System#getProperty(String)}) whose value is a filter
147-
// that specifies which tests to execute. The value of this property is a regular expression that
148-
// is matched against the name of each test. Using this property is an alternative to setting the
149-
// {@link #EXCLUSIVE_TAG} tag, which requires modifying the JSON file. To use this property,
150-
// specify -DspecTestFilter=<Regex> to the Java runtime, replacing <Regex> with a regular
151-
// expression; a test will be executed if and only if its name matches this regular expression.
152-
// In this context, a test's "name" is the result of appending its "itName" to its "describeName",
146+
// The name of a Java system property ({@link System#getProperty(String)}) whose
147+
// value is a filter
148+
// that specifies which tests to execute. The value of this property is a
149+
// regular expression that
150+
// is matched against the name of each test. Using this property is an
151+
// alternative to setting the
152+
// {@link #EXCLUSIVE_TAG} tag, which requires modifying the JSON file. To use
153+
// this property,
154+
// specify -DspecTestFilter=<Regex> to the Java runtime, replacing <Regex> with
155+
// a regular
156+
// expression; a test will be executed if and only if its name matches this
157+
// regular expression.
158+
// In this context, a test's "name" is the result of appending its "itName" to
159+
// its "describeName",
153160
// separated by a space character.
154161
private static final String TEST_FILTER_PROPERTY = "specTestFilter";
155162

156-
// Tags on tests that should be excluded from execution, useful to allow the platforms to
157-
// temporarily diverge or for features that are designed to be platform specific (such as
163+
// Tags on tests that should be excluded from execution, useful to allow the
164+
// platforms to
165+
// temporarily diverge or for features that are designed to be platform specific
166+
// (such as
158167
// 'multi-client').
159168
private static final Set<String> DISABLED_TAGS =
160169
RUN_BENCHMARK_TESTS
@@ -233,7 +242,8 @@ public abstract class SpecTestCase implements RemoteStoreCallback {
233242

234243
public static void info(String line) {
235244
if (DEBUG) {
236-
// Print log information out directly to cut down on logger-related cruft like the extra
245+
// Print log information out directly to cut down on logger-related cruft like
246+
// the extra
237247
// line for the date and class method which are always SpecTestCase+info
238248
System.err.println(line);
239249
} else {
@@ -632,7 +642,8 @@ private void doWatchRemove(JSONObject watchRemoveSpec) throws Exception {
632642
new WatchTargetChange(
633643
WatchTargetChangeType.Removed, targetIds, WatchStream.EMPTY_RESUME_TOKEN, error);
634644
writeWatchChange(change, SnapshotVersion.NONE);
635-
// Unlike web, the MockDatastore detects a watch removal with cause and will remove active
645+
// Unlike web, the MockDatastore detects a watch removal with cause and will
646+
// remove active
636647
// targets
637648
}
638649

@@ -675,14 +686,12 @@ private void doWatchEntity(JSONObject watchEntity) throws Exception {
675686
}
676687

677688
private void doWatchFilter(JSONObject watchFilter) throws Exception {
678-
List<Integer> targets =
679-
watchFilter.has("targetIds")
680-
? parseIntList(watchFilter.getJSONArray("targetIds"))
681-
: Collections.emptyList();
689+
List<Integer> targets = parseIntList(watchFilter.getJSONArray("targetIds"));
690+
682691
Assert.hardAssert(
683692
targets.size() == 1, "ExistenceFilters currently support exactly one target only.");
684693

685-
int keyCount = watchFilter.has("keys") ? watchFilter.getJSONArray("keys").length() : 0;
694+
int keyCount = watchFilter.getJSONArray("keys").length();
686695
BloomFilter bloomFilterProto =
687696
watchFilter.has("bloomFilter")
688697
? parseBloomFilter(watchFilter.getJSONObject("bloomFilter"))
@@ -701,7 +710,8 @@ private void doWatchReset(JSONArray targetIds) throws Exception {
701710
}
702711

703712
private void doWatchSnapshot(JSONObject watchSnapshot) throws Exception {
704-
// The client will only respond to watchSnapshots if they are on a target change with an empty
713+
// The client will only respond to watchSnapshots if they are on a target change
714+
// with an empty
705715
// set of target IDs.
706716
List<Integer> targets =
707717
watchSnapshot.has("targetIds")
@@ -724,7 +734,8 @@ private void doWatchStreamClose(JSONObject spec) throws Exception {
724734
Status status =
725735
Status.fromCodeValue(error.getInt("code")).withDescription(error.getString("message"));
726736
queue.runSync(() -> datastore.failWatchStream(status));
727-
// Unlike web, stream should re-open synchronously (if we have active listeners).
737+
// Unlike web, stream should re-open synchronously (if we have active
738+
// listeners).
728739
if (!this.queryListeners.isEmpty()) {
729740
assertTrue("Watch stream is open", datastore.isWatchStreamOpen());
730741
}
@@ -740,7 +751,7 @@ private void doWriteAck(JSONObject writeAckSpec) throws Exception {
740751
validateNextWriteSent(write.first);
741752

742753
MutationResult mutationResult =
743-
new MutationResult(version(version), /*transformResults=*/ Collections.emptyList());
754+
new MutationResult(version(version), /* transformResults= */ Collections.emptyList());
744755
queue.runSync(() -> datastore.ackWrite(version(version), singletonList(mutationResult)));
745756
}
746757

@@ -865,7 +876,8 @@ private void doStep(JSONObject step) throws Exception {
865876
} else if (step.has("watchStreamClose")) {
866877
doWatchStreamClose(step.getJSONObject("watchStreamClose"));
867878
} else if (step.has("watchProto")) {
868-
// watchProto isn't yet used, and it's unclear how to create arbitrary protos from JSON.
879+
// watchProto isn't yet used, and it's unclear how to create arbitrary protos
880+
// from JSON.
869881
throw Assert.fail("watchProto is not yet supported.");
870882
} else if (step.has("writeAck")) {
871883
doWriteAck(step.getJSONObject("writeAck"));
@@ -882,9 +894,12 @@ private void doStep(JSONObject step) throws Exception {
882894
doDisableNetwork();
883895
}
884896
} else if (step.has("changeUser")) {
885-
// NOTE: JSONObject.getString("foo") where "foo" is mapped to null will return "null".
886-
// Explicitly testing for isNull here allows the null value to be preserved. This is important
887-
// because the unauthenticated user is represented as having a null uid as a value for
897+
// NOTE: JSONObject.getString("foo") where "foo" is mapped to null will return
898+
// "null".
899+
// Explicitly testing for isNull here allows the null value to be preserved.
900+
// This is important
901+
// because the unauthenticated user is represented as having a null uid as a
902+
// value for
888903
// "changeUser".
889904
String uid = step.isNull("changeUser") ? null : step.getString("changeUser");
890905
doChangeUser(uid);
@@ -1027,8 +1042,10 @@ private void validateExpectedState(@Nullable JSONObject expectedState) throws JS
10271042
expectedActiveTargets.put(targetId, new ArrayList<>());
10281043
for (int i = 0; i < queryArrayJson.length(); i++) {
10291044
Query query = parseQuery(queryArrayJson.getJSONObject(i));
1030-
// TODO: populate the purpose of the target once it's possible to encode that in the
1031-
// spec tests. For now, hard-code that it's a listen despite the fact that it's not
1045+
// TODO: populate the purpose of the target once it's possible to encode that in
1046+
// the
1047+
// spec tests. For now, hard-code that it's a listen despite the fact that it's
1048+
// not
10321049
// always the right value.
10331050
TargetData targetData =
10341051
new TargetData(
@@ -1058,7 +1075,8 @@ private void validateExpectedState(@Nullable JSONObject expectedState) throws JS
10581075
// Always validate that the expected limbo docs match the actual limbo docs.
10591076
validateActiveLimboDocs();
10601077
validateEnqueuedLimboDocs();
1061-
// Always validate that the expected active targets match the actual active targets.
1078+
// Always validate that the expected active targets match the actual active
1079+
// targets.
10621080
validateActiveTargets();
10631081
}
10641082

@@ -1097,7 +1115,8 @@ private void validateUserCallbacks(@Nullable JSONObject expected) throws JSONExc
10971115
}
10981116

10991117
private void validateActiveLimboDocs() {
1100-
// Make a copy so it can modified while checking against the expected limbo docs.
1118+
// Make a copy so it can modified while checking against the expected limbo
1119+
// docs.
11011120
@SuppressWarnings("VisibleForTests")
11021121
Map<DocumentKey, Integer> actualLimboDocs =
11031122
new HashMap<>(syncEngine.getActiveLimboDocumentResolutions());
@@ -1174,7 +1193,8 @@ private void validateActiveTargets() {
11741193
TargetData expectedTarget = expectedQueries.get(0);
11751194
TargetData actualTarget = actualTargets.get(expected.getKey());
11761195

1177-
// TODO: validate the purpose of the target once it's possible to encode that in the
1196+
// TODO: validate the purpose of the target once it's possible to encode that in
1197+
// the
11781198
// spec tests. For now, only validate properties that can be validated.
11791199
// assertEquals(expectedTarget, actualTarget);
11801200
assertEquals(expectedTarget.getTarget(), actualTarget.getTarget());
@@ -1233,10 +1253,14 @@ private void runSteps(JSONArray steps, JSONObject config) throws Exception {
12331253
} catch (Exception e) {
12341254
throw Assert.fail("Spec test failed with %s", e);
12351255
} finally {
1236-
// Ensure that Persistence is torn down even if the test is failing due to a thrown exception
1237-
// so that any open databases are closed. This is important when the LocalStore is backed by
1238-
// SQLite because SQLite opens databases in exclusive mode. If tearDownForSpec were not called
1239-
// after an exception then subsequent attempts to open the SQLite database will fail, making
1256+
// Ensure that Persistence is torn down even if the test is failing due to a
1257+
// thrown exception
1258+
// so that any open databases are closed. This is important when the LocalStore
1259+
// is backed by
1260+
// SQLite because SQLite opens databases in exclusive mode. If tearDownForSpec
1261+
// were not called
1262+
// after an exception then subsequent attempts to open the SQLite database will
1263+
// fail, making
12401264
// it harder to zero in on the spec tests as a culprit.
12411265
specTearDown();
12421266
}
@@ -1286,7 +1310,8 @@ public void testSpecTests() throws Exception {
12861310
String fileName = parsedSpecFile.first;
12871311
JSONObject fileJSON = parsedSpecFile.second;
12881312

1289-
// Print the names of the files and tests regardless of whether verbose logging is enabled.
1313+
// Print the names of the files and tests regardless of whether verbose logging
1314+
// is enabled.
12901315
info("Spec test file: " + fileName);
12911316

12921317
// Iterate over the tests in the file and run them.

0 commit comments

Comments
 (0)