Skip to content

Commit 71bfc77

Browse files
committed
Add compatibility with Cache Index Auto Creation
1 parent 12de4c0 commit 71bfc77

File tree

5 files changed

+49
-8
lines changed

5 files changed

+49
-8
lines changed

firebase-firestore/src/main/java/com/google/firebase/firestore/local/IndexManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ enum IndexType {
7373
* <p>Values for this index are persisted asynchronously. The index will only be used for query
7474
* execution once values are persisted.
7575
*/
76-
void addFieldIndex(FieldIndex index);
76+
void addFieldIndex(@Nullable FieldIndex index);
7777

7878
/** Removes the given field index and deletes all index values. */
7979
void deleteFieldIndex(FieldIndex index);

firebase-firestore/src/main/java/com/google/firebase/firestore/local/MemoryIndexManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public List<ResourcePath> getCollectionParents(String collectionId) {
5151
}
5252

5353
@Override
54-
public void addFieldIndex(FieldIndex index) {
54+
public void addFieldIndex(@Nullable FieldIndex index) {
5555
// Field indices are not supported with memory persistence.
5656
}
5757

firebase-firestore/src/main/java/com/google/firebase/firestore/local/SQLiteIndexManager.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,11 @@ public List<ResourcePath> getCollectionParents(String collectionId) {
201201
}
202202

203203
@Override
204-
public void addFieldIndex(FieldIndex index) {
204+
public void addFieldIndex(@Nullable FieldIndex index) {
205205
hardAssert(started, "IndexManager not started");
206206

207+
if (index == null) return;
208+
207209
int nextIndexId = memoizedMaxIndexId + 1;
208210
index =
209211
FieldIndex.create(

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

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ public TargetIndexMatcher(Target target) {
115115
}
116116
}
117117

118+
public boolean hasMultipleInequality() {
119+
return inequalityFilters.size() > 1;
120+
}
121+
118122
/**
119123
* Returns whether the index can be used to serve the TargetIndexMatcher's target.
120124
*
@@ -139,6 +143,11 @@ public TargetIndexMatcher(Target target) {
139143
public boolean servedByIndex(FieldIndex index) {
140144
hardAssert(index.getCollectionGroup().equals(collectionId), "Collection IDs do not match");
141145

146+
if (hasMultipleInequality()) {
147+
// Only single inequality is supported for now.
148+
return false;
149+
}
150+
142151
// If there is an array element, find a matching filter.
143152
FieldIndex.Segment arraySegment = index.getArraySegment();
144153
if (arraySegment != null && !hasMatchingEqualityFilter(arraySegment)) {
@@ -171,11 +180,6 @@ public boolean servedByIndex(FieldIndex index) {
171180
}
172181

173182
if (inequalityFilters.size() > 0) {
174-
if (this.inequalityFilters.size() > 1) {
175-
// Only single inequality is supported for now.
176-
return false;
177-
}
178-
179183
// Only a single inequality is currently supported. Get the only entry in the set.
180184
FieldFilter inequalityFilter = this.inequalityFilters.first();
181185

@@ -204,7 +208,12 @@ public boolean servedByIndex(FieldIndex index) {
204208
}
205209

206210
/** Returns a full matched field index for this target. */
211+
@Nullable
207212
public FieldIndex buildTargetIndex() {
213+
if (hasMultipleInequality()) {
214+
return null;
215+
}
216+
208217
// We want to make sure only one segment created for one field. For example, in case like
209218
// a == 3 and a > 2, Index: {a ASCENDING} will only be created once.
210219
Set<FieldPath> uniqueFields = new HashSet<>();

firebase-firestore/src/test/java/com/google/firebase/firestore/local/SQLiteLocalStoreTest.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,4 +712,34 @@ public void testIndexAutoCreationWorksWithMutation() {
712712
assertOverlaysRead(/* byKey= */ 1, /* byCollection= */ 1);
713713
assertQueryReturned("coll/a", "coll/f");
714714
}
715+
716+
@Test
717+
public void testIndexAutoCreationDoesnotWorkWithMultipleInequality() {
718+
Query query = query("coll").filter(filter("field1", "<", 5)).filter(filter("field2", "<", 5));
719+
int targetId = allocateQuery(query);
720+
721+
setIndexAutoCreationEnabled(true);
722+
setMinCollectionSizeToAutoCreateIndex(0);
723+
setRelativeIndexReadCostPerDocument(2);
724+
725+
applyRemoteEvent(addedRemoteEvent(doc("coll/a", 10, map("field1", 1, "field2", 2)), targetId));
726+
applyRemoteEvent(addedRemoteEvent(doc("coll/b", 10, map("field1", 8, "field2", 2)), targetId));
727+
applyRemoteEvent(
728+
addedRemoteEvent(doc("coll/c", 10, map("field1", "string", "field2", 2)), targetId));
729+
applyRemoteEvent(addedRemoteEvent(doc("coll/d", 10, map("field1", 2)), targetId));
730+
applyRemoteEvent(addedRemoteEvent(doc("coll/e", 10, map("field1", 4, "field2", 4)), targetId));
731+
732+
// First time query is running without indexes.
733+
// Based on current heuristic, collection document counts (5) > 2 * resultSize (2).
734+
// Full matched index will not be created since FieldIndex does not support multiple inequality.
735+
executeQuery(query);
736+
assertRemoteDocumentsRead(/* byKey= */ 0, /* byCollection= */ 2);
737+
assertQueryReturned("coll/a", "coll/e");
738+
739+
backfillIndexes();
740+
741+
executeQuery(query);
742+
assertRemoteDocumentsRead(/* byKey= */ 0, /* byCollection= */ 2);
743+
assertQueryReturned("coll/a", "coll/e");
744+
}
715745
}

0 commit comments

Comments
 (0)