Skip to content

Commit 8aed796

Browse files
committed
implement autoClientIndexing
1 parent e8debe3 commit 8aed796

File tree

10 files changed

+100
-12
lines changed

10 files changed

+100
-12
lines changed

firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheSettings.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,11 @@ public static PersistentCacheSettings.Builder newBuilder() {
3737

3838
private final long sizeBytes;
3939

40-
private PersistentCacheSettings(long sizeBytes) {
40+
private final boolean autoClientIndexingEnabled;
41+
42+
private PersistentCacheSettings(long sizeBytes, boolean autoClientIndexingEnabled) {
4143
this.sizeBytes = sizeBytes;
44+
this.autoClientIndexingEnabled = autoClientIndexingEnabled;
4245
}
4346

4447
@Override
@@ -74,11 +77,17 @@ public long getSizeBytes() {
7477
return sizeBytes;
7578
}
7679

80+
public boolean autoClientIndexingEnabled() {
81+
return autoClientIndexingEnabled;
82+
}
83+
7784
/** A Builder for creating {@code PersistentCacheSettings} instance. */
7885
public static class Builder {
7986

8087
private long sizeBytes = FirebaseFirestoreSettings.DEFAULT_CACHE_SIZE_BYTES;
8188

89+
private boolean autoClientIndexingEnabled = false;
90+
8291
private Builder() {}
8392

8493
/**
@@ -98,10 +107,16 @@ public Builder setSizeBytes(long sizeBytes) {
98107
return this;
99108
}
100109

110+
@NonNull
111+
public Builder enableAutoClientIndexing(boolean value) {
112+
this.autoClientIndexingEnabled = value;
113+
return this;
114+
}
115+
101116
/** Creates a {@code PersistentCacheSettings} instance from this builder instance. */
102117
@NonNull
103118
public PersistentCacheSettings build() {
104-
return new PersistentCacheSettings(sizeBytes);
119+
return new PersistentCacheSettings(sizeBytes, autoClientIndexingEnabled);
105120
}
106121
}
107122
}

firebase-firestore/src/main/java/com/google/firebase/firestore/core/SQLiteComponentProvider.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
package com.google.firebase.firestore.core;
1616

17+
import com.google.firebase.firestore.PersistentCacheSettings;
1718
import com.google.firebase.firestore.local.IndexBackfiller;
1819
import com.google.firebase.firestore.local.LocalSerializer;
1920
import com.google.firebase.firestore.local.LruDelegate;
@@ -50,6 +51,9 @@ protected Persistence createPersistence(Configuration configuration) {
5051
configuration.getDatabaseInfo().getPersistenceKey(),
5152
configuration.getDatabaseInfo().getDatabaseId(),
5253
serializer,
53-
params);
54+
params,
55+
configuration.getSettings().getCacheSettings() != null
56+
&& ((PersistentCacheSettings) configuration.getSettings().getCacheSettings())
57+
.autoClientIndexingEnabled());
5458
}
5559
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ enum IndexType {
7878
/** Removes the given field index and deletes all index values. */
7979
void deleteFieldIndex(FieldIndex index);
8080

81+
void createTargetIndices(Target target);
82+
8183
/**
8284
* Returns a list of field indexes that correspond to the specified collection group.
8385
*

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ public void deleteFieldIndex(FieldIndex index) {
6060
// Field indices are not supported with memory persistence.
6161
}
6262

63+
@Override
64+
public void createTargetIndices(Target target) {}
65+
6366
@Override
6467
@Nullable
6568
public List<DocumentKey> getDocumentsMatchingTarget(Target target) {

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,17 @@ public ImmutableSortedMap<DocumentKey, Document> getDocumentsMatchingQuery(
8585
QueryContext counter = new QueryContext();
8686
result = performQueryUsingRemoteKeys(query, remoteKeys, lastLimboFreeSnapshotVersion, counter);
8787
if (result != null) {
88+
if (counter.fullScanCount > 2 * result.size()) {
89+
indexManager.createTargetIndices(query.toTarget());
90+
}
8891
return result;
8992
}
9093
counter = new QueryContext();
91-
return executeFullCollectionScan(query, counter);
94+
result = executeFullCollectionScan(query, counter);
95+
if (counter.fullScanCount > 2 * result.size()) {
96+
indexManager.createTargetIndices(query.toTarget());
97+
}
98+
return result;
9299
}
93100

94101
/**

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,17 @@ final class SQLiteIndexManager implements IndexManager {
107107
private boolean started = false;
108108
private int memoizedMaxIndexId = -1;
109109
private long memoizedMaxSequenceNumber = -1;
110+
private boolean autoClientIndexingEnabled;
110111

111-
SQLiteIndexManager(SQLitePersistence persistence, LocalSerializer serializer, User user) {
112+
SQLiteIndexManager(
113+
SQLitePersistence persistence,
114+
LocalSerializer serializer,
115+
User user,
116+
boolean autoClientIndexingEnabled) {
112117
this.db = persistence;
113118
this.serializer = serializer;
114119
this.uid = user.isAuthenticated() ? user.getUid() : "";
120+
this.autoClientIndexingEnabled = autoClientIndexingEnabled;
115121
}
116122

117123
@Override
@@ -233,6 +239,21 @@ public void deleteFieldIndex(FieldIndex index) {
233239
}
234240
}
235241

242+
@Override
243+
public void createTargetIndices(Target target) {
244+
hardAssert(started, "IndexManager not started");
245+
246+
if (!autoClientIndexingEnabled) return;
247+
248+
for (Target subTarget : getSubTargets(target)) {
249+
IndexType type = getIndexType(subTarget);
250+
if (type == IndexType.NONE) {
251+
TargetIndexMatcher targetIndexMatcher = new TargetIndexMatcher(subTarget);
252+
addFieldIndex(targetIndexMatcher.BuildTargetIndex());
253+
}
254+
}
255+
}
256+
236257
@Override
237258
public @Nullable String getNextCollectionGroupToUpdate() {
238259
hardAssert(started, "IndexManager not started");

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ public static String databaseName(String persistenceKey, DatabaseId databaseId)
8585

8686
private final OpenHelper opener;
8787
private final LocalSerializer serializer;
88+
private final boolean autoClientIndexingEnabled;
8889
private final SQLiteTargetCache targetCache;
8990
private final SQLiteBundleCache bundleCache;
9091
private final SQLiteRemoteDocumentCache remoteDocumentCache;
@@ -113,17 +114,23 @@ public SQLitePersistence(
113114
String persistenceKey,
114115
DatabaseId databaseId,
115116
LocalSerializer serializer,
116-
LruGarbageCollector.Params params) {
117+
LruGarbageCollector.Params params,
118+
Boolean autoClientIndexingEnabled) {
117119
this(
118120
serializer,
119121
params,
120-
new OpenHelper(context, serializer, databaseName(persistenceKey, databaseId)));
122+
new OpenHelper(context, serializer, databaseName(persistenceKey, databaseId)),
123+
autoClientIndexingEnabled);
121124
}
122125

123126
public SQLitePersistence(
124-
LocalSerializer serializer, LruGarbageCollector.Params params, OpenHelper openHelper) {
127+
LocalSerializer serializer,
128+
LruGarbageCollector.Params params,
129+
OpenHelper openHelper,
130+
Boolean autoClientIndexingEnabled) {
125131
this.opener = openHelper;
126132
this.serializer = serializer;
133+
this.autoClientIndexingEnabled = autoClientIndexingEnabled;
127134
this.targetCache = new SQLiteTargetCache(this, this.serializer);
128135
this.bundleCache = new SQLiteBundleCache(this, this.serializer);
129136
this.remoteDocumentCache = new SQLiteRemoteDocumentCache(this, this.serializer);
@@ -182,7 +189,7 @@ SQLiteTargetCache getTargetCache() {
182189

183190
@Override
184191
IndexManager getIndexManager(User user) {
185-
return new SQLiteIndexManager(this, serializer, user);
192+
return new SQLiteIndexManager(this, serializer, user, autoClientIndexingEnabled);
186193
}
187194

188195
@Override

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,34 @@ public boolean servedByIndex(FieldIndex index) {
186186
return true;
187187
}
188188

189+
public FieldIndex BuildTargetIndex() {
190+
List<FieldIndex.Segment> segments = new ArrayList<>();
191+
192+
for (FieldFilter filter : equalityFilters) {
193+
boolean isArrayOperator =
194+
filter.getOperator().equals(FieldFilter.Operator.ARRAY_CONTAINS)
195+
|| filter.getOperator().equals(FieldFilter.Operator.ARRAY_CONTAINS_ANY);
196+
segments.add(
197+
FieldIndex.Segment.create(
198+
filter.getField(),
199+
isArrayOperator
200+
? FieldIndex.Segment.Kind.CONTAINS
201+
: FieldIndex.Segment.Kind.ASCENDING));
202+
}
203+
204+
for (OrderBy orderBy : orderBys) {
205+
segments.add(
206+
FieldIndex.Segment.create(
207+
orderBy.getField(),
208+
orderBy.getDirection() == OrderBy.Direction.ASCENDING
209+
? FieldIndex.Segment.Kind.ASCENDING
210+
: FieldIndex.Segment.Kind.DESCENDING));
211+
}
212+
213+
return FieldIndex.create(
214+
FieldIndex.UNKNOWN_ID, collectionId, segments, FieldIndex.INITIAL_STATE);
215+
}
216+
189217
private boolean hasMatchingEqualityFilter(FieldIndex.Segment segment) {
190218
for (FieldFilter filter : equalityFilters) {
191219
if (matchesFilter(filter, segment)) {

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ private static SQLitePersistence openSQLitePersistence(
8585
LocalSerializer serializer = new LocalSerializer(new RemoteSerializer(databaseId));
8686
Context context = ApplicationProvider.getApplicationContext();
8787
SQLitePersistence persistence =
88-
new SQLitePersistence(context, name, databaseId, serializer, params);
88+
new SQLitePersistence(context, name, databaseId, serializer, params, false);
8989
persistence.start();
9090
return persistence;
9191
}
@@ -100,7 +100,8 @@ private static SQLitePersistence openSQLitePersistence(
100100
serializer,
101101
params,
102102
new SQLitePersistence.OpenHelper(
103-
context, serializer, databaseName(name, databaseId), version));
103+
context, serializer, databaseName(name, databaseId), version),
104+
false);
104105
persistence.start();
105106
return persistence;
106107
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,7 @@ public void createsOverlaysAndMigrationTable() {
698698

699699
private SQLiteRemoteDocumentCache createRemoteDocumentCache() {
700700
SQLitePersistence persistence =
701-
new SQLitePersistence(serializer, LruGarbageCollector.Params.Default(), opener);
701+
new SQLitePersistence(serializer, LruGarbageCollector.Params.Default(), opener, false);
702702
persistence.start();
703703
return new SQLiteRemoteDocumentCache(persistence, serializer);
704704
}

0 commit comments

Comments
 (0)