Skip to content

Commit 39756f4

Browse files
committed
add configurable min documents to create indexes
1 parent 14a6a71 commit 39756f4

File tree

4 files changed

+60
-0
lines changed

4 files changed

+60
-0
lines changed

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

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

1717
import static com.google.firebase.firestore.util.Assert.hardAssert;
1818

19+
import androidx.annotation.VisibleForTesting;
1920
import com.google.firebase.database.collection.ImmutableSortedMap;
2021
import com.google.firebase.database.collection.ImmutableSortedSet;
2122
import com.google.firebase.firestore.core.Query;
@@ -60,13 +61,17 @@
6061
*/
6162
public class QueryEngine {
6263
private static final String LOG_TAG = "QueryEngine";
64+
private static final int MIN_COLLECTION_SIZE_TO_AUTO_CREATE_INDEX = 100;
6365

6466
private LocalDocumentsView localDocumentsView;
6567
private IndexManager indexManager;
6668
private boolean initialized;
6769

6870
private boolean automaticIndexingEnabled = false;
6971

72+
/** SDK only decides whether it should create index when collection size is larger than this. */
73+
private int minCollectionSizeToAutoCreateIndex = MIN_COLLECTION_SIZE_TO_AUTO_CREATE_INDEX;
74+
7075
public void initialize(LocalDocumentsView localDocumentsView, IndexManager indexManager) {
7176
this.localDocumentsView = localDocumentsView;
7277
this.indexManager = indexManager;
@@ -111,6 +116,15 @@ public ImmutableSortedMap<DocumentKey, Document> getDocumentsMatchingQuery(
111116
*/
112117
// TODO(csi): Auto experiment data.
113118
private void CreateCacheIndexes(Query query, QueryContext context, int resultSize) {
119+
if (context.getDocumentReadCount() < minCollectionSizeToAutoCreateIndex) {
120+
Logger.debug(
121+
LOG_TAG,
122+
"SDK will only creates cache indexes for collection contains more than or equal to "
123+
+ "%s documents.",
124+
minCollectionSizeToAutoCreateIndex);
125+
return;
126+
}
127+
114128
String decisionStr = "";
115129
// If evaluation is updated, please update tests in SQLiteLocalStoreTest.java
116130
if (context.getDocumentReadCount() > 2 * resultSize) {
@@ -305,4 +319,9 @@ private ImmutableSortedMap<DocumentKey, Document> appendRemainingResults(
305319
}
306320
return remainingResults;
307321
}
322+
323+
@VisibleForTesting
324+
void setMinCollectionSizeToAutoCreateIndex(int newMin) {
325+
minCollectionSizeToAutoCreateIndex = newMin;
326+
}
308327
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ public void disableIndexAutoCreation() {
9797
queryEngine.disableIndexAutoCreation();
9898
}
9999

100+
@Override
101+
public void setMinCollectionSizeToAutoCreateIndex(int newMin) {
102+
queryEngine.setMinCollectionSizeToAutoCreateIndex(newMin);
103+
}
104+
100105
/**
101106
* Returns the number of documents returned by the RemoteDocumentCache's `getAll()` API (since the
102107
* last call to `resetCounts()`)

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,10 @@ protected void disableIndexAutoCreation() {
232232
queryEngine.disableIndexAutoCreation();
233233
}
234234

235+
protected void setMinCollectionSizeToAutoCreateIndex(int newMin) {
236+
queryEngine.setMinCollectionSizeToAutoCreateIndex(newMin);
237+
}
238+
235239
private void releaseTarget(int targetId) {
236240
localStore.releaseTarget(targetId);
237241
}

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ public void testIndexAutoCreationWorks() {
373373
int targetId = allocateQuery(query);
374374

375375
enableIndexAutoCreation();
376+
setMinCollectionSizeToAutoCreateIndex(0);
376377

377378
applyRemoteEvent(addedRemoteEvent(doc("coll/a", 10, map("matches", true)), targetId));
378379
applyRemoteEvent(addedRemoteEvent(doc("coll/b", 10, map("matches", false)), targetId));
@@ -396,12 +397,40 @@ public void testIndexAutoCreationWorks() {
396397
assertQueryReturned("coll/a", "coll/e", "coll/f");
397398
}
398399

400+
@Test
401+
public void testIndexAutoCreationDoesNotWorkWhenCollectionSizeIsTooSmall() {
402+
Query query = query("coll").filter(filter("matches", "==", true));
403+
int targetId = allocateQuery(query);
404+
405+
enableIndexAutoCreation();
406+
407+
applyRemoteEvent(addedRemoteEvent(doc("coll/a", 10, map("matches", true)), targetId));
408+
applyRemoteEvent(addedRemoteEvent(doc("coll/b", 10, map("matches", false)), targetId));
409+
applyRemoteEvent(addedRemoteEvent(doc("coll/c", 10, map("matches", false)), targetId));
410+
applyRemoteEvent(addedRemoteEvent(doc("coll/d", 10, map("matches", false)), targetId));
411+
applyRemoteEvent(addedRemoteEvent(doc("coll/e", 10, map("matches", true)), targetId));
412+
413+
// SDK will not create indexes since collection size is too small.
414+
executeQuery(query);
415+
assertRemoteDocumentsRead(/* byKey= */ 0, /* byCollection= */ 2);
416+
assertQueryReturned("coll/a", "coll/e");
417+
418+
backfillIndexes();
419+
420+
applyRemoteEvent(addedRemoteEvent(doc("coll/f", 20, map("matches", true)), targetId));
421+
422+
executeQuery(query);
423+
assertRemoteDocumentsRead(/* byKey= */ 0, /* byCollection= */ 3);
424+
assertQueryReturned("coll/a", "coll/e", "coll/f");
425+
}
426+
399427
@Test
400428
public void testIndexAutoCreationWorksWhenBackfillerRunsHalfway() {
401429
Query query = query("coll").filter(filter("matches", "==", true));
402430
int targetId = allocateQuery(query);
403431

404432
enableIndexAutoCreation();
433+
setMinCollectionSizeToAutoCreateIndex(0);
405434

406435
applyRemoteEvent(addedRemoteEvent(doc("coll/a", 10, map("matches", true)), targetId));
407436
applyRemoteEvent(addedRemoteEvent(doc("coll/b", 10, map("matches", false)), targetId));
@@ -433,6 +462,7 @@ public void testIndexCreatedByIndexAutoCreationExistsAfterTurnOffAutoCreation()
433462
int targetId = allocateQuery(query);
434463

435464
enableIndexAutoCreation();
465+
setMinCollectionSizeToAutoCreateIndex(0);
436466

437467
applyRemoteEvent(addedRemoteEvent(doc("coll/a", 10, map("matches", true)), targetId));
438468
applyRemoteEvent(addedRemoteEvent(doc("coll/b", 10, map("matches", false)), targetId));
@@ -464,6 +494,7 @@ public void testDisableIndexAutoCreationWorks() {
464494
int targetId1 = allocateQuery(query1);
465495

466496
enableIndexAutoCreation();
497+
setMinCollectionSizeToAutoCreateIndex(0);
467498

468499
applyRemoteEvent(addedRemoteEvent(doc("coll/a", 10, map("matches", true)), targetId1));
469500
applyRemoteEvent(addedRemoteEvent(doc("coll/b", 10, map("matches", false)), targetId1));
@@ -509,6 +540,7 @@ public void testIndexAutoCreationWorksWithMutation() {
509540
int targetId = allocateQuery(query);
510541

511542
enableIndexAutoCreation();
543+
setMinCollectionSizeToAutoCreateIndex(0);
512544

513545
applyRemoteEvent(addedRemoteEvent(doc("coll/a", 10, map("matches", true)), targetId));
514546
applyRemoteEvent(addedRemoteEvent(doc("coll/b", 10, map("matches", false)), targetId));

0 commit comments

Comments
 (0)