From ace0357470ca4b0eb128b9749d11d04bd11a400b Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Mon, 8 May 2023 00:23:46 -0400 Subject: [PATCH 01/16] Add counter --- .../com/google/firebase/firestore/local/AutoIndexing.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 firebase-firestore/src/main/java/com/google/firebase/firestore/local/AutoIndexing.java diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/AutoIndexing.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/AutoIndexing.java new file mode 100644 index 00000000000..7b1f09ff43a --- /dev/null +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/AutoIndexing.java @@ -0,0 +1,7 @@ +package com.google.firebase.firestore.local; + +public class AutoIndexing { + AutoIndexing() {} + + int fullScanCount = 0; +} From cdbfa19e25cd43fdc8f6891d4971be046009b168 Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Wed, 10 May 2023 16:00:01 -0400 Subject: [PATCH 02/16] address feedback 1 --- .../com/google/firebase/firestore/local/AutoIndexing.java | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 firebase-firestore/src/main/java/com/google/firebase/firestore/local/AutoIndexing.java diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/AutoIndexing.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/AutoIndexing.java deleted file mode 100644 index 7b1f09ff43a..00000000000 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/AutoIndexing.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.google.firebase.firestore.local; - -public class AutoIndexing { - AutoIndexing() {} - - int fullScanCount = 0; -} From 582dc5059f4b2e6110b5c59320925ba9b7efccdd Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Tue, 16 May 2023 22:23:45 -0400 Subject: [PATCH 03/16] implement autoClientIndexing --- .../firestore/PersistentCacheSettings.java | 19 +++++++++++++++++-- .../core/SQLiteComponentProvider.java | 6 +++++- .../firestore/local/SQLitePersistence.java | 15 +++++++++++---- .../local/PersistenceTestHelpers.java | 5 +++-- .../firestore/local/SQLiteSchemaTest.java | 2 +- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheSettings.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheSettings.java index 5f23df46707..53698d7be98 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheSettings.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheSettings.java @@ -37,8 +37,11 @@ public static PersistentCacheSettings.Builder newBuilder() { private final long sizeBytes; - private PersistentCacheSettings(long sizeBytes) { + private final boolean autoClientIndexingEnabled; + + private PersistentCacheSettings(long sizeBytes, boolean autoClientIndexingEnabled) { this.sizeBytes = sizeBytes; + this.autoClientIndexingEnabled = autoClientIndexingEnabled; } @Override @@ -74,11 +77,17 @@ public long getSizeBytes() { return sizeBytes; } + public boolean autoClientIndexingEnabled() { + return autoClientIndexingEnabled; + } + /** A Builder for creating {@code PersistentCacheSettings} instance. */ public static class Builder { private long sizeBytes = FirebaseFirestoreSettings.DEFAULT_CACHE_SIZE_BYTES; + private boolean autoClientIndexingEnabled = false; + private Builder() {} /** @@ -98,10 +107,16 @@ public Builder setSizeBytes(long sizeBytes) { return this; } + @NonNull + public Builder enableAutoClientIndexing(boolean value) { + this.autoClientIndexingEnabled = value; + return this; + } + /** Creates a {@code PersistentCacheSettings} instance from this builder instance. */ @NonNull public PersistentCacheSettings build() { - return new PersistentCacheSettings(sizeBytes); + return new PersistentCacheSettings(sizeBytes, autoClientIndexingEnabled); } } } diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/core/SQLiteComponentProvider.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/core/SQLiteComponentProvider.java index e77d3a64a29..335f814f7d3 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/core/SQLiteComponentProvider.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/core/SQLiteComponentProvider.java @@ -14,6 +14,7 @@ package com.google.firebase.firestore.core; +import com.google.firebase.firestore.PersistentCacheSettings; import com.google.firebase.firestore.local.IndexBackfiller; import com.google.firebase.firestore.local.LocalSerializer; import com.google.firebase.firestore.local.LruDelegate; @@ -50,6 +51,9 @@ protected Persistence createPersistence(Configuration configuration) { configuration.getDatabaseInfo().getPersistenceKey(), configuration.getDatabaseInfo().getDatabaseId(), serializer, - params); + params, + configuration.getSettings().getCacheSettings() != null + && ((PersistentCacheSettings) configuration.getSettings().getCacheSettings()) + .autoClientIndexingEnabled()); } } diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/SQLitePersistence.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/SQLitePersistence.java index 8c0cd993cb2..bcdbfbaba8f 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/SQLitePersistence.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/SQLitePersistence.java @@ -85,6 +85,7 @@ public static String databaseName(String persistenceKey, DatabaseId databaseId) private final OpenHelper opener; private final LocalSerializer serializer; + private final boolean autoClientIndexingEnabled; private final SQLiteTargetCache targetCache; private final SQLiteBundleCache bundleCache; private final SQLiteRemoteDocumentCache remoteDocumentCache; @@ -113,17 +114,23 @@ public SQLitePersistence( String persistenceKey, DatabaseId databaseId, LocalSerializer serializer, - LruGarbageCollector.Params params) { + LruGarbageCollector.Params params, + Boolean autoClientIndexingEnabled) { this( serializer, params, - new OpenHelper(context, serializer, databaseName(persistenceKey, databaseId))); + new OpenHelper(context, serializer, databaseName(persistenceKey, databaseId)), + autoClientIndexingEnabled); } public SQLitePersistence( - LocalSerializer serializer, LruGarbageCollector.Params params, OpenHelper openHelper) { + LocalSerializer serializer, + LruGarbageCollector.Params params, + OpenHelper openHelper, + Boolean autoClientIndexingEnabled) { this.opener = openHelper; this.serializer = serializer; + this.autoClientIndexingEnabled = autoClientIndexingEnabled; this.targetCache = new SQLiteTargetCache(this, this.serializer); this.bundleCache = new SQLiteBundleCache(this, this.serializer); this.remoteDocumentCache = new SQLiteRemoteDocumentCache(this, this.serializer); @@ -182,7 +189,7 @@ SQLiteTargetCache getTargetCache() { @Override IndexManager getIndexManager(User user) { - return new SQLiteIndexManager(this, serializer, user); + return new SQLiteIndexManager(this, serializer, user, autoClientIndexingEnabled); } @Override diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/PersistenceTestHelpers.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/PersistenceTestHelpers.java index 1a47b0652ab..51f103734c7 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/PersistenceTestHelpers.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/PersistenceTestHelpers.java @@ -85,7 +85,7 @@ private static SQLitePersistence openSQLitePersistence( LocalSerializer serializer = new LocalSerializer(new RemoteSerializer(databaseId)); Context context = ApplicationProvider.getApplicationContext(); SQLitePersistence persistence = - new SQLitePersistence(context, name, databaseId, serializer, params); + new SQLitePersistence(context, name, databaseId, serializer, params, false); persistence.start(); return persistence; } @@ -100,7 +100,8 @@ private static SQLitePersistence openSQLitePersistence( serializer, params, new SQLitePersistence.OpenHelper( - context, serializer, databaseName(name, databaseId), version)); + context, serializer, databaseName(name, databaseId), version), + false); persistence.start(); return persistence; } diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/SQLiteSchemaTest.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/SQLiteSchemaTest.java index 44fe6051898..42096a29075 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/SQLiteSchemaTest.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/SQLiteSchemaTest.java @@ -698,7 +698,7 @@ public void createsOverlaysAndMigrationTable() { private SQLiteRemoteDocumentCache createRemoteDocumentCache() { SQLitePersistence persistence = - new SQLitePersistence(serializer, LruGarbageCollector.Params.Default(), opener); + new SQLitePersistence(serializer, LruGarbageCollector.Params.Default(), opener, false); persistence.start(); return new SQLiteRemoteDocumentCache(persistence, serializer); } From 44432770a4abff59d2a60ad2f4e2b639e68986f3 Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Tue, 23 May 2023 12:43:14 -0400 Subject: [PATCH 04/16] Add tests and fix bugs for BuildTargetIndex --- .../model/TargetIndexMatcherTest.java | 157 ++++++++++++++++++ 1 file changed, 157 insertions(+) diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/model/TargetIndexMatcherTest.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/model/TargetIndexMatcherTest.java index 627775c8a2a..d45cf8a0d01 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/model/TargetIndexMatcherTest.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/model/TargetIndexMatcherTest.java @@ -449,6 +449,163 @@ public void withMultipleNotIn() { validateServesTarget(q, "a", FieldIndex.Segment.Kind.ASCENDING); } + @Test + public void buildTargetIndex() { + Query q = + query("collId") + .filter(filter("a", "==", 1)) + .filter(filter("b", "==", 2)) + .orderBy(orderBy("__name__", "desc")); + TargetIndexMatcher targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + FieldIndex expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = query("collId").orderBy(orderBy("a")); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = query("collId").orderBy(orderBy("a")).orderBy(orderBy("b")); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = query("collId").filter(filter("a", "array-contains", "a")).orderBy(orderBy("b")); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = query("collId").orderBy(orderBy("b")); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = query("collId").orderBy(orderBy("a")); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = query("collId").filter(filter("a", ">", 1)).filter(filter("a", "<", 10)); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = query("collId").filter(filter("a", "in", Arrays.asList(1, 2))).filter(filter("b", "==", 5)); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = query("collId").filter(filter("value", "array-contains", "foo")).orderBy(orderBy("value")); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = + query("collId") + .filter(filter("a", "array-contains", "a")) + .filter(filter("a", ">", "b")) + .orderBy(orderBy("a", "asc")); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = query("collId").filter(filter("a", "==", 1)).orderBy(orderBy("__name__", "desc")); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = query("collId").filter(filter("a1", "==", "a")).filter(filter("a2", "==", "b")); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = + query("collId") + .filter(filter("equality1", "==", "a")) + .filter(filter("equality2", "==", "b")) + .filter(filter("inequality", ">=", "c")); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = + query("collId") + .filter(filter("equality1", "==", "a")) + .filter(filter("inequality", ">=", "c")) + .filter(filter("equality2", "==", "b")); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = query("collId").orderBy(orderBy("a")); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = query("collId").orderBy(orderBy("a", "desc")); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = query("collId").orderBy(orderBy("a")).orderBy(orderBy("__name__")); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = query("collId").filter(filter("a", "!=", 1)); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = query("collId").filter(filter("a", "!=", 1)).orderBy(orderBy("a")).orderBy(orderBy("b")); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = query("collId").filter(filter("a", "==", "a")).filter(filter("b", ">", "b")); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = + query("collId") + .filter(filter("a1", "==", "a")) + .filter(filter("a2", ">", "b")) + .orderBy(orderBy("a2", "asc")); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = + query("collId") + .filter(filter("a", ">=", 1)) + .filter(filter("a", "==", 5)) + .filter(filter("a", "<=", 10)); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + // assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + + q = + query("collId") + .filter(filter("a", "not-in", Arrays.asList(1, 2, 3))) + .filter(filter("a", ">=", 2)); + targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + } + + @Test + public void failedTest() { + Query q = + query("collId") + .filter(filter("a", ">=", 1)) + .filter(filter("a", "==", 5)) + .filter(filter("a", "<=", 10)); + TargetIndexMatcher targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); + FieldIndex expectedIndex = targetIndexMatcher.BuildTargetIndex(); + assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); + } + @Test public void withMultipleOrderBys() { Query q = From 763593d1c3333841e86a26bf4ef7c8eea24ed14f Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Wed, 24 May 2023 00:34:19 -0400 Subject: [PATCH 05/16] hide getter from public API --- .../com/google/firebase/firestore/PersistentCacheSettings.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheSettings.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheSettings.java index 53698d7be98..3b53e0325df 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheSettings.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheSettings.java @@ -14,6 +14,7 @@ package com.google.firebase.firestore; import androidx.annotation.NonNull; +import androidx.annotation.RestrictTo; /** * Configures the SDK to use a persistent cache. Firestore documents and mutations are persisted @@ -77,6 +78,7 @@ public long getSizeBytes() { return sizeBytes; } + @RestrictTo(RestrictTo.Scope.LIBRARY) public boolean autoClientIndexingEnabled() { return autoClientIndexingEnabled; } From 1dfcacbf9b36f85899cdebbf2a2afa4de4435645 Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Thu, 25 May 2023 10:55:11 -0400 Subject: [PATCH 06/16] move the flag from IndexManager to QueryEngine --- .../firestore/core/MemoryComponentProvider.java | 8 +++++++- .../firestore/core/SQLiteComponentProvider.java | 6 +----- .../firebase/firestore/local/LocalStore.java | 13 ++++++++++++- .../firestore/local/SQLitePersistence.java | 15 ++++----------- .../firestore/local/CountingQueryEngine.java | 5 +++-- .../firestore/local/PersistenceTestHelpers.java | 5 ++--- .../firestore/local/QueryEngineTestCase.java | 2 +- .../firestore/local/SQLiteSchemaTest.java | 2 +- .../firestore/model/TargetIndexMatcherTest.java | 2 ++ 9 files changed, 33 insertions(+), 25 deletions(-) diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/core/MemoryComponentProvider.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/core/MemoryComponentProvider.java index fc8180b6937..b25dd55bc85 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/core/MemoryComponentProvider.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/core/MemoryComponentProvider.java @@ -19,6 +19,7 @@ import com.google.firebase.firestore.FirebaseFirestoreSettings; import com.google.firebase.firestore.MemoryCacheSettings; import com.google.firebase.firestore.MemoryLruGcSettings; +import com.google.firebase.firestore.PersistentCacheSettings; import com.google.firebase.firestore.local.IndexBackfiller; import com.google.firebase.firestore.local.LocalSerializer; import com.google.firebase.firestore.local.LocalStore; @@ -60,7 +61,12 @@ protected EventManager createEventManager(Configuration configuration) { @Override protected LocalStore createLocalStore(Configuration configuration) { - return new LocalStore(getPersistence(), new QueryEngine(), configuration.getInitialUser()); + boolean autoIndexEnabled = + configuration.getSettings().getCacheSettings() != null + && ((PersistentCacheSettings) configuration.getSettings().getCacheSettings()) + .autoClientIndexingEnabled(); + return new LocalStore( + getPersistence(), new QueryEngine(), configuration.getInitialUser(), autoIndexEnabled); } @Override diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/core/SQLiteComponentProvider.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/core/SQLiteComponentProvider.java index 335f814f7d3..e77d3a64a29 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/core/SQLiteComponentProvider.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/core/SQLiteComponentProvider.java @@ -14,7 +14,6 @@ package com.google.firebase.firestore.core; -import com.google.firebase.firestore.PersistentCacheSettings; import com.google.firebase.firestore.local.IndexBackfiller; import com.google.firebase.firestore.local.LocalSerializer; import com.google.firebase.firestore.local.LruDelegate; @@ -51,9 +50,6 @@ protected Persistence createPersistence(Configuration configuration) { configuration.getDatabaseInfo().getPersistenceKey(), configuration.getDatabaseInfo().getDatabaseId(), serializer, - params, - configuration.getSettings().getCacheSettings() != null - && ((PersistentCacheSettings) configuration.getSettings().getCacheSettings()) - .autoClientIndexingEnabled()); + params); } } diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/LocalStore.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/LocalStore.java index c0be00e8111..1326bc38e44 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/LocalStore.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/LocalStore.java @@ -147,11 +147,22 @@ public final class LocalStore implements BundleCallback { /** Used to generate targetIds for queries tracked locally. */ private final TargetIdGenerator targetIdGenerator; + private boolean autoIndexEnabled; + public LocalStore(Persistence persistence, QueryEngine queryEngine, User initialUser) { + this(persistence, queryEngine, initialUser, false); + } + + public LocalStore( + Persistence persistence, + QueryEngine queryEngine, + User initialUser, + boolean autoIndexEnabled) { hardAssert( persistence.isStarted(), "LocalStore was passed an unstarted persistence implementation"); this.persistence = persistence; this.queryEngine = queryEngine; + this.autoIndexEnabled = autoIndexEnabled; targetCache = persistence.getTargetCache(); bundleCache = persistence.getBundleCache(); @@ -175,7 +186,7 @@ private void initializeUserComponents(User user) { new LocalDocumentsView(remoteDocuments, mutationQueue, documentOverlayCache, indexManager); remoteDocuments.setIndexManager(indexManager); - queryEngine.initialize(localDocuments, indexManager); + queryEngine.initialize(localDocuments, indexManager, autoIndexEnabled); } public void start() { diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/SQLitePersistence.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/SQLitePersistence.java index bcdbfbaba8f..8c0cd993cb2 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/SQLitePersistence.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/SQLitePersistence.java @@ -85,7 +85,6 @@ public static String databaseName(String persistenceKey, DatabaseId databaseId) private final OpenHelper opener; private final LocalSerializer serializer; - private final boolean autoClientIndexingEnabled; private final SQLiteTargetCache targetCache; private final SQLiteBundleCache bundleCache; private final SQLiteRemoteDocumentCache remoteDocumentCache; @@ -114,23 +113,17 @@ public SQLitePersistence( String persistenceKey, DatabaseId databaseId, LocalSerializer serializer, - LruGarbageCollector.Params params, - Boolean autoClientIndexingEnabled) { + LruGarbageCollector.Params params) { this( serializer, params, - new OpenHelper(context, serializer, databaseName(persistenceKey, databaseId)), - autoClientIndexingEnabled); + new OpenHelper(context, serializer, databaseName(persistenceKey, databaseId))); } public SQLitePersistence( - LocalSerializer serializer, - LruGarbageCollector.Params params, - OpenHelper openHelper, - Boolean autoClientIndexingEnabled) { + LocalSerializer serializer, LruGarbageCollector.Params params, OpenHelper openHelper) { this.opener = openHelper; this.serializer = serializer; - this.autoClientIndexingEnabled = autoClientIndexingEnabled; this.targetCache = new SQLiteTargetCache(this, this.serializer); this.bundleCache = new SQLiteBundleCache(this, this.serializer); this.remoteDocumentCache = new SQLiteRemoteDocumentCache(this, this.serializer); @@ -189,7 +182,7 @@ SQLiteTargetCache getTargetCache() { @Override IndexManager getIndexManager(User user) { - return new SQLiteIndexManager(this, serializer, user, autoClientIndexingEnabled); + return new SQLiteIndexManager(this, serializer, user); } @Override diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java index 61385eff006..b599928b23b 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java @@ -69,14 +69,15 @@ void resetCounts() { } @Override - public void initialize(LocalDocumentsView localDocuments, IndexManager indexManager) { + public void initialize( + LocalDocumentsView localDocuments, IndexManager indexManager, boolean autoIndexEnabled) { LocalDocumentsView wrappedView = new LocalDocumentsView( wrapRemoteDocumentCache(localDocuments.getRemoteDocumentCache()), localDocuments.getMutationQueue(), wrapOverlayCache(localDocuments.getDocumentOverlayCache()), indexManager); - queryEngine.initialize(wrappedView, indexManager); + queryEngine.initialize(wrappedView, indexManager, autoIndexEnabled); } @Override diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/PersistenceTestHelpers.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/PersistenceTestHelpers.java index 51f103734c7..1a47b0652ab 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/PersistenceTestHelpers.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/PersistenceTestHelpers.java @@ -85,7 +85,7 @@ private static SQLitePersistence openSQLitePersistence( LocalSerializer serializer = new LocalSerializer(new RemoteSerializer(databaseId)); Context context = ApplicationProvider.getApplicationContext(); SQLitePersistence persistence = - new SQLitePersistence(context, name, databaseId, serializer, params, false); + new SQLitePersistence(context, name, databaseId, serializer, params); persistence.start(); return persistence; } @@ -100,8 +100,7 @@ private static SQLitePersistence openSQLitePersistence( serializer, params, new SQLitePersistence.OpenHelper( - context, serializer, databaseName(name, databaseId), version), - false); + context, serializer, databaseName(name, databaseId), version)); persistence.start(); return persistence; } diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/QueryEngineTestCase.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/QueryEngineTestCase.java index aedd1401c74..af57ff9e4b5 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/QueryEngineTestCase.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/QueryEngineTestCase.java @@ -125,7 +125,7 @@ public ImmutableSortedMap getDocumentsMatchingQuery( return super.getDocumentsMatchingQuery(query, offset); } }; - queryEngine.initialize(localDocuments, indexManager); + queryEngine.initialize(localDocuments, indexManager, false); } abstract Persistence getPersistence(); diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/SQLiteSchemaTest.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/SQLiteSchemaTest.java index 42096a29075..44fe6051898 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/SQLiteSchemaTest.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/SQLiteSchemaTest.java @@ -698,7 +698,7 @@ public void createsOverlaysAndMigrationTable() { private SQLiteRemoteDocumentCache createRemoteDocumentCache() { SQLitePersistence persistence = - new SQLitePersistence(serializer, LruGarbageCollector.Params.Default(), opener, false); + new SQLitePersistence(serializer, LruGarbageCollector.Params.Default(), opener); persistence.start(); return new SQLiteRemoteDocumentCache(persistence, serializer); } diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/model/TargetIndexMatcherTest.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/model/TargetIndexMatcherTest.java index d45cf8a0d01..fe63de02612 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/model/TargetIndexMatcherTest.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/model/TargetIndexMatcherTest.java @@ -23,6 +23,7 @@ import static com.google.firebase.firestore.testutil.TestUtil.query; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; import com.google.firebase.firestore.core.Query; import com.google.firebase.firestore.core.Target; @@ -596,6 +597,7 @@ public void buildTargetIndex() { @Test public void failedTest() { + assumeTrue("Skip this test due to a bug in CSI.", false); Query q = query("collId") .filter(filter("a", ">=", 1)) From f930018cca9ef0f437742b57884fe437ae15501f Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Sun, 25 Jun 2023 19:52:19 -0400 Subject: [PATCH 07/16] move auto index flag to runtime --- .../firestore/PersistentCacheManager.java | 22 +++++++++++++++++++ .../firestore/PersistentCacheSettings.java | 21 ++---------------- .../core/MemoryComponentProvider.java | 8 +------ .../firestore/local/CountingQueryEngine.java | 5 ++--- .../firestore/local/QueryEngineTestCase.java | 2 +- 5 files changed, 28 insertions(+), 30 deletions(-) create mode 100644 firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheManager.java diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheManager.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheManager.java new file mode 100644 index 00000000000..0f34e5fbfcd --- /dev/null +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheManager.java @@ -0,0 +1,22 @@ +package com.google.firebase.firestore; + +import androidx.annotation.NonNull; +import androidx.annotation.RestrictTo; +import com.google.android.gms.tasks.Task; +import com.google.firebase.firestore.core.FirestoreClient; + +// TODO(csi): Remove the `hide` and scope annotations. +/** @hide */ +@RestrictTo(RestrictTo.Scope.LIBRARY) +public class PersistentCacheManager { + @NonNull private FirestoreClient client; + + @RestrictTo(RestrictTo.Scope.LIBRARY) + public PersistentCacheManager(FirestoreClient client) { + this.client = client; + } + + public Task setAutomaticIndexingEnabled(boolean isEnabled) { + return client.setAutomaticIndexingEnabled(isEnabled); + } +} diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheSettings.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheSettings.java index 3b53e0325df..5f23df46707 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheSettings.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheSettings.java @@ -14,7 +14,6 @@ package com.google.firebase.firestore; import androidx.annotation.NonNull; -import androidx.annotation.RestrictTo; /** * Configures the SDK to use a persistent cache. Firestore documents and mutations are persisted @@ -38,11 +37,8 @@ public static PersistentCacheSettings.Builder newBuilder() { private final long sizeBytes; - private final boolean autoClientIndexingEnabled; - - private PersistentCacheSettings(long sizeBytes, boolean autoClientIndexingEnabled) { + private PersistentCacheSettings(long sizeBytes) { this.sizeBytes = sizeBytes; - this.autoClientIndexingEnabled = autoClientIndexingEnabled; } @Override @@ -78,18 +74,11 @@ public long getSizeBytes() { return sizeBytes; } - @RestrictTo(RestrictTo.Scope.LIBRARY) - public boolean autoClientIndexingEnabled() { - return autoClientIndexingEnabled; - } - /** A Builder for creating {@code PersistentCacheSettings} instance. */ public static class Builder { private long sizeBytes = FirebaseFirestoreSettings.DEFAULT_CACHE_SIZE_BYTES; - private boolean autoClientIndexingEnabled = false; - private Builder() {} /** @@ -109,16 +98,10 @@ public Builder setSizeBytes(long sizeBytes) { return this; } - @NonNull - public Builder enableAutoClientIndexing(boolean value) { - this.autoClientIndexingEnabled = value; - return this; - } - /** Creates a {@code PersistentCacheSettings} instance from this builder instance. */ @NonNull public PersistentCacheSettings build() { - return new PersistentCacheSettings(sizeBytes, autoClientIndexingEnabled); + return new PersistentCacheSettings(sizeBytes); } } } diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/core/MemoryComponentProvider.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/core/MemoryComponentProvider.java index b25dd55bc85..fc8180b6937 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/core/MemoryComponentProvider.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/core/MemoryComponentProvider.java @@ -19,7 +19,6 @@ import com.google.firebase.firestore.FirebaseFirestoreSettings; import com.google.firebase.firestore.MemoryCacheSettings; import com.google.firebase.firestore.MemoryLruGcSettings; -import com.google.firebase.firestore.PersistentCacheSettings; import com.google.firebase.firestore.local.IndexBackfiller; import com.google.firebase.firestore.local.LocalSerializer; import com.google.firebase.firestore.local.LocalStore; @@ -61,12 +60,7 @@ protected EventManager createEventManager(Configuration configuration) { @Override protected LocalStore createLocalStore(Configuration configuration) { - boolean autoIndexEnabled = - configuration.getSettings().getCacheSettings() != null - && ((PersistentCacheSettings) configuration.getSettings().getCacheSettings()) - .autoClientIndexingEnabled(); - return new LocalStore( - getPersistence(), new QueryEngine(), configuration.getInitialUser(), autoIndexEnabled); + return new LocalStore(getPersistence(), new QueryEngine(), configuration.getInitialUser()); } @Override diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java index b599928b23b..61385eff006 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java @@ -69,15 +69,14 @@ void resetCounts() { } @Override - public void initialize( - LocalDocumentsView localDocuments, IndexManager indexManager, boolean autoIndexEnabled) { + public void initialize(LocalDocumentsView localDocuments, IndexManager indexManager) { LocalDocumentsView wrappedView = new LocalDocumentsView( wrapRemoteDocumentCache(localDocuments.getRemoteDocumentCache()), localDocuments.getMutationQueue(), wrapOverlayCache(localDocuments.getDocumentOverlayCache()), indexManager); - queryEngine.initialize(wrappedView, indexManager, autoIndexEnabled); + queryEngine.initialize(wrappedView, indexManager); } @Override diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/QueryEngineTestCase.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/QueryEngineTestCase.java index af57ff9e4b5..aedd1401c74 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/QueryEngineTestCase.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/QueryEngineTestCase.java @@ -125,7 +125,7 @@ public ImmutableSortedMap getDocumentsMatchingQuery( return super.getDocumentsMatchingQuery(query, offset); } }; - queryEngine.initialize(localDocuments, indexManager, false); + queryEngine.initialize(localDocuments, indexManager); } abstract Persistence getPersistence(); From 4591144dcd5cb96d8789026b0795db93b0a20cc5 Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Mon, 26 Jun 2023 16:41:08 -0400 Subject: [PATCH 08/16] Support old way to enable persistent for PersistentCacheManager --- .../google/firebase/firestore/PersistentCacheManager.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheManager.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheManager.java index 0f34e5fbfcd..86c549711de 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheManager.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheManager.java @@ -2,7 +2,6 @@ import androidx.annotation.NonNull; import androidx.annotation.RestrictTo; -import com.google.android.gms.tasks.Task; import com.google.firebase.firestore.core.FirestoreClient; // TODO(csi): Remove the `hide` and scope annotations. @@ -16,7 +15,7 @@ public PersistentCacheManager(FirestoreClient client) { this.client = client; } - public Task setAutomaticIndexingEnabled(boolean isEnabled) { - return client.setAutomaticIndexingEnabled(isEnabled); + public void setAutomaticIndexingEnabled(boolean isEnabled) { + client.setAutomaticIndexingEnabled(isEnabled); } } From 4c71da09191ee2a3ed014ae87213ceb6667630b4 Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Mon, 26 Jun 2023 23:25:49 -0400 Subject: [PATCH 09/16] Add hide and copyright --- .../firebase/firestore/PersistentCacheManager.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheManager.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheManager.java index 86c549711de..e068fa9b8db 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheManager.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheManager.java @@ -1,3 +1,17 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package com.google.firebase.firestore; import androidx.annotation.NonNull; From aa0efd9cae48a57fb5f484ab8eaa7e85aea9487d Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Wed, 28 Jun 2023 17:00:24 -0400 Subject: [PATCH 10/16] Rename PersistentCacheManager to PersistentCacheIndexManager --- .../firestore/PersistentCacheManager.java | 35 ------------------- 1 file changed, 35 deletions(-) delete mode 100644 firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheManager.java diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheManager.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheManager.java deleted file mode 100644 index e068fa9b8db..00000000000 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheManager.java +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.firebase.firestore; - -import androidx.annotation.NonNull; -import androidx.annotation.RestrictTo; -import com.google.firebase.firestore.core.FirestoreClient; - -// TODO(csi): Remove the `hide` and scope annotations. -/** @hide */ -@RestrictTo(RestrictTo.Scope.LIBRARY) -public class PersistentCacheManager { - @NonNull private FirestoreClient client; - - @RestrictTo(RestrictTo.Scope.LIBRARY) - public PersistentCacheManager(FirestoreClient client) { - this.client = client; - } - - public void setAutomaticIndexingEnabled(boolean isEnabled) { - client.setAutomaticIndexingEnabled(isEnabled); - } -} From 2a19419f9f4d17eafb01a8d1d1572fc825ea1bd6 Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Wed, 19 Jul 2023 12:25:16 -0400 Subject: [PATCH 11/16] add configurable min documents to create indexes --- .../google/firebase/firestore/local/CountingQueryEngine.java | 5 +++++ .../google/firebase/firestore/local/LocalStoreTestCase.java | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java index 61385eff006..80c1f046e97 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java @@ -102,6 +102,11 @@ public void setRelativeIndexReadCostPerDocument(double newCost) { queryEngine.setRelativeIndexReadCostPerDocument(newCost); } + @Override + public void setMinCollectionSizeToAutoCreateIndex(int newMin) { + queryEngine.setMinCollectionSizeToAutoCreateIndex(newMin); + } + /** * Returns the number of documents returned by the RemoteDocumentCache's `getAll()` API (since the * last call to `resetCounts()`) diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/LocalStoreTestCase.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/LocalStoreTestCase.java index 4f8645add10..3d64daebb6f 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/LocalStoreTestCase.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/LocalStoreTestCase.java @@ -234,6 +234,10 @@ protected void setRelativeIndexReadCostPerDocument(double newCost) { queryEngine.setRelativeIndexReadCostPerDocument(newCost); } + protected void setMinCollectionSizeToAutoCreateIndex(int newMin) { + queryEngine.setMinCollectionSizeToAutoCreateIndex(newMin); + } + private void releaseTarget(int targetId) { localStore.releaseTarget(targetId); } From ba932dce88cd93c16931ca986b5ffe087ca2e74f Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Mon, 24 Jul 2023 01:10:31 -0400 Subject: [PATCH 12/16] Address feedback --- .../google/firebase/firestore/local/CountingQueryEngine.java | 5 +++++ .../google/firebase/firestore/local/LocalStoreTestCase.java | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java index 80c1f046e97..4d56d2acf73 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java @@ -107,6 +107,11 @@ public void setMinCollectionSizeToAutoCreateIndex(int newMin) { queryEngine.setMinCollectionSizeToAutoCreateIndex(newMin); } + @Override + public void setRelativeIndexReadCost(int newCost) { + queryEngine.setRelativeIndexReadCost(newCost); + } + /** * Returns the number of documents returned by the RemoteDocumentCache's `getAll()` API (since the * last call to `resetCounts()`) diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/LocalStoreTestCase.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/LocalStoreTestCase.java index 3d64daebb6f..b279a1e0f39 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/LocalStoreTestCase.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/LocalStoreTestCase.java @@ -238,6 +238,10 @@ protected void setMinCollectionSizeToAutoCreateIndex(int newMin) { queryEngine.setMinCollectionSizeToAutoCreateIndex(newMin); } + protected void setRelativeIndexReadCost(int newCost) { + queryEngine.setRelativeIndexReadCost(newCost); + } + private void releaseTarget(int targetId) { localStore.releaseTarget(targetId); } From 1529296b9bad8d3bbae167816dd2a077c4101caa Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Fri, 14 Jul 2023 12:29:22 -0400 Subject: [PATCH 13/16] Add deleteAllIndexes --- .../PersistentCacheIndexManager.java | 4 ++ .../firestore/core/FirestoreClient.java | 5 ++ .../firestore/local/IndexManager.java | 3 + .../firebase/firestore/local/LocalStore.java | 4 ++ .../firestore/local/MemoryIndexManager.java | 5 ++ .../firestore/local/SQLiteIndexManager.java | 10 ++++ .../firestore/local/LocalStoreTestCase.java | 8 +-- .../firestore/local/SQLiteLocalStoreTest.java | 60 +++++++++++++++++++ 8 files changed, 93 insertions(+), 6 deletions(-) diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheIndexManager.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheIndexManager.java index d9251ba45a3..e84ac514558 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheIndexManager.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheIndexManager.java @@ -51,4 +51,8 @@ public void enableIndexAutoCreation() { public void disableIndexAutoCreation() { client.setIndexAutoCreationEnabled(false); } + + public void deleteAllIndexes() { + client.deleteAllFieldIndexes(); + } } diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/core/FirestoreClient.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/core/FirestoreClient.java index 9367712d991..182b7d6ef35 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/core/FirestoreClient.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/core/FirestoreClient.java @@ -358,6 +358,11 @@ public void setIndexAutoCreationEnabled(boolean enabled) { asyncQueue.enqueueAndForget(() -> localStore.setIndexAutoCreationEnabled(enabled)); } + public void deleteAllFieldIndexes() { + verifyNotTerminated(); + asyncQueue.enqueueAndForget(() -> localStore.deleteAllFieldIndexes()); + } + public void removeSnapshotsInSyncListener(EventListener listener) { // Checks for shutdown but does not raise error, allowing remove after shutdown to be a no-op. if (isTerminated()) { diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/IndexManager.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/IndexManager.java index 8ba45cd6efd..4751ae6e208 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/IndexManager.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/IndexManager.java @@ -78,6 +78,9 @@ enum IndexType { /** Removes the given field index and deletes all index values. */ void deleteFieldIndex(FieldIndex index); + /** Removes all field indexes and deletes all index values. */ + void deleteAllFieldIndexes(); + /** Creates a full matched field index which serves the given target. */ void createTargetIndexes(Target target); diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/LocalStore.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/LocalStore.java index 1326bc38e44..78ac3bb3a5d 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/LocalStore.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/LocalStore.java @@ -813,6 +813,10 @@ public void configureFieldIndexes(List newFieldIndexes) { }); } + public void deleteAllFieldIndexes() { + persistence.runTransaction("Delete All Indexes", () -> indexManager.deleteAllFieldIndexes()); + } + public void setIndexAutoCreationEnabled(boolean enabled) { queryEngine.setIndexAutoCreationEnabled(enabled); } diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/MemoryIndexManager.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/MemoryIndexManager.java index 0cb81deae8b..a55734b3859 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/MemoryIndexManager.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/MemoryIndexManager.java @@ -60,6 +60,11 @@ public void deleteFieldIndex(FieldIndex index) { // Field indices are not supported with memory persistence. } + @Override + public void deleteAllFieldIndexes() { + // Field indices are not supported with memory persistence. + } + @Override public void createTargetIndexes(Target target) {} diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/SQLiteIndexManager.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/SQLiteIndexManager.java index 5c3e4a844a4..8f4edc2125b 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/SQLiteIndexManager.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/SQLiteIndexManager.java @@ -233,6 +233,16 @@ public void deleteFieldIndex(FieldIndex index) { } } + @Override + public void deleteAllFieldIndexes() { + db.execute("DELETE FROM index_configuration"); + db.execute("DELETE FROM index_entries"); + db.execute("DELETE FROM index_state"); + + nextIndexToUpdate.clear(); + memoizedIndexes.clear(); + } + @Override public void createTargetIndexes(Target target) { hardAssert(started, "IndexManager not started"); diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/LocalStoreTestCase.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/LocalStoreTestCase.java index b279a1e0f39..4c93fca4a63 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/LocalStoreTestCase.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/LocalStoreTestCase.java @@ -234,12 +234,8 @@ protected void setRelativeIndexReadCostPerDocument(double newCost) { queryEngine.setRelativeIndexReadCostPerDocument(newCost); } - protected void setMinCollectionSizeToAutoCreateIndex(int newMin) { - queryEngine.setMinCollectionSizeToAutoCreateIndex(newMin); - } - - protected void setRelativeIndexReadCost(int newCost) { - queryEngine.setRelativeIndexReadCost(newCost); + protected void deleteAllIndexes() { + localStore.deleteAllFieldIndexes(); } private void releaseTarget(int targetId) { diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/SQLiteLocalStoreTest.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/SQLiteLocalStoreTest.java index 2885b8aa412..360084f1d21 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/SQLiteLocalStoreTest.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/SQLiteLocalStoreTest.java @@ -575,6 +575,66 @@ public void testDisableIndexAutoCreationWorks() { assertRemoteDocumentsRead(/* byKey= */ 0, /* byCollection= */ 2); } + @Test + public void testDeleteAllIndexesWorksWithIndexAutoCreation() { + Query query = query("coll").filter(filter("matches", "==", true)); + int targetId = allocateQuery(query); + + enableIndexAutoCreation(); + + applyRemoteEvent(addedRemoteEvent(doc("coll/a", 10, map("matches", true)), targetId)); + applyRemoteEvent(addedRemoteEvent(doc("coll/b", 10, map("matches", false)), targetId)); + applyRemoteEvent(addedRemoteEvent(doc("coll/c", 10, map("matches", false)), targetId)); + applyRemoteEvent(addedRemoteEvent(doc("coll/d", 10, map("matches", false)), targetId)); + applyRemoteEvent(addedRemoteEvent(doc("coll/e", 10, map("matches", true)), targetId)); + + // First time query is running without indexes. + // Based on current heuristic, collection document counts (5) > 2 * resultSize (2). + // Full matched index should be created. + executeQuery(query); + assertRemoteDocumentsRead(/* byKey= */ 0, /* byCollection= */ 2); + assertQueryReturned("coll/a", "coll/e"); + + disableIndexAutoCreation(); + + backfillIndexes(); + + executeQuery(query); + assertRemoteDocumentsRead(/* byKey= */ 2, /* byCollection= */ 0); + assertQueryReturned("coll/a", "coll/e"); + + deleteAllIndexes(); + + executeQuery(query); + assertRemoteDocumentsRead(/* byKey= */ 0, /* byCollection= */ 2); + assertQueryReturned("coll/a", "coll/e"); + } + + @Test + public void testDeleteAllIndexesWorksWithManualAddedIndexes() { + FieldIndex index = + fieldIndex( + "coll", 0, FieldIndex.INITIAL_STATE, "matches", FieldIndex.Segment.Kind.ASCENDING); + configureFieldIndexes(singletonList(index)); + + Query query = query("coll").filter(filter("matches", "==", true)); + int targetId = allocateQuery(query); + + applyRemoteEvent(addedRemoteEvent(doc("coll/a", 10, map("matches", true)), targetId)); + + backfillIndexes(); + + executeQuery(query); + assertRemoteDocumentsRead(/* byKey= */ 1, /* byCollection= */ 0); + assertQueryReturned("coll/a"); + + deleteAllIndexes(); + + executeQuery(query); + assertRemoteDocumentsRead(/* byKey= */ 0, /* byCollection= */ 1); + assertQueryReturned("coll/a"); + } + @Test public void testIndexAutoCreationWorksWithMutation() { Query query = From beb4d4d53b4d07cde1e0506f702336d75f32c667 Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Mon, 17 Jul 2023 13:12:38 -0400 Subject: [PATCH 14/16] Add documentation --- .../java/com/google/firebase/firestore/IndexingTest.java | 8 ++++++++ .../firebase/firestore/PersistentCacheIndexManager.java | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/firebase-firestore/src/androidTest/java/com/google/firebase/firestore/IndexingTest.java b/firebase-firestore/src/androidTest/java/com/google/firebase/firestore/IndexingTest.java index ea36090853e..585093b15b2 100644 --- a/firebase-firestore/src/androidTest/java/com/google/firebase/firestore/IndexingTest.java +++ b/firebase-firestore/src/androidTest/java/com/google/firebase/firestore/IndexingTest.java @@ -118,6 +118,7 @@ public void testAutoIndexCreationSetSuccessfully() { .build(); db.setFirestoreSettings(settings); + // Based on current heuristic, collection document counts (3) > 2 * resultSize (1). CollectionReference collection = testCollectionWithDocs( map( @@ -136,6 +137,9 @@ public void testAutoIndexCreationSetSuccessfully() { results = waitFor(collection.whereEqualTo("match", true).get()); assertEquals(1, results.size()); + + assertDoesNotThrow(() -> db.getPersistentCacheIndexManager().deleteAllIndexes()); + assertEquals(1, results.size()); } @Test @@ -143,6 +147,7 @@ public void testAutoIndexCreationSetSuccessfullyUsingDefault() { // Use persistent disk cache (default) FirebaseFirestore db = testFirestore(); + // Based on current heuristic, collection document counts (3) > 2 * resultSize (1). CollectionReference collection = testCollectionWithDocs( map( @@ -161,6 +166,9 @@ public void testAutoIndexCreationSetSuccessfullyUsingDefault() { results = waitFor(collection.whereEqualTo("match", true).get()); assertEquals(1, results.size()); + + assertDoesNotThrow(() -> db.getPersistentCacheIndexManager().deleteAllIndexes()); + assertEquals(1, results.size()); } @Test diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheIndexManager.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheIndexManager.java index e84ac514558..00ff2cfa260 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheIndexManager.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheIndexManager.java @@ -52,6 +52,10 @@ public void disableIndexAutoCreation() { client.setIndexAutoCreationEnabled(false); } + /** + * Removes all persistent cache indexes. Please note this function will also deletes indexes + * generated by {@link FirebaseFirestore#setIndexConfiguration(String)}. + */ public void deleteAllIndexes() { client.deleteAllFieldIndexes(); } From dc168fe038368837a09bceb9866654fac8282715 Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Wed, 26 Jul 2023 14:58:30 -0400 Subject: [PATCH 15/16] add test coverage --- .../firebase/firestore/IndexingTest.java | 6 ++++-- .../firestore/PersistentCacheIndexManager.java | 2 +- .../firestore/local/SQLiteLocalStoreTest.java | 18 ++++++++++-------- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/firebase-firestore/src/androidTest/java/com/google/firebase/firestore/IndexingTest.java b/firebase-firestore/src/androidTest/java/com/google/firebase/firestore/IndexingTest.java index 585093b15b2..f04bd00fbec 100644 --- a/firebase-firestore/src/androidTest/java/com/google/firebase/firestore/IndexingTest.java +++ b/firebase-firestore/src/androidTest/java/com/google/firebase/firestore/IndexingTest.java @@ -118,7 +118,6 @@ public void testAutoIndexCreationSetSuccessfully() { .build(); db.setFirestoreSettings(settings); - // Based on current heuristic, collection document counts (3) > 2 * resultSize (1). CollectionReference collection = testCollectionWithDocs( map( @@ -147,7 +146,6 @@ public void testAutoIndexCreationSetSuccessfullyUsingDefault() { // Use persistent disk cache (default) FirebaseFirestore db = testFirestore(); - // Based on current heuristic, collection document counts (3) > 2 * resultSize (1). CollectionReference collection = testCollectionWithDocs( map( @@ -183,5 +181,9 @@ public void testAutoIndexCreationAfterFailsTermination() { expectError( () -> db.getPersistentCacheIndexManager().disableIndexAutoCreation(), "The client has already been terminated"); + + expectError( + () -> db.getPersistentCacheIndexManager().deleteAllIndexes(), + "The client has already been terminated"); } } diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheIndexManager.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheIndexManager.java index 00ff2cfa260..f73b2332049 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheIndexManager.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/PersistentCacheIndexManager.java @@ -54,7 +54,7 @@ public void disableIndexAutoCreation() { /** * Removes all persistent cache indexes. Please note this function will also deletes indexes - * generated by {@link FirebaseFirestore#setIndexConfiguration(String)}. + * generated by {@link FirebaseFirestore#setIndexConfiguration(String)}, which is deprecated. */ public void deleteAllIndexes() { client.deleteAllFieldIndexes(); diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/SQLiteLocalStoreTest.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/SQLiteLocalStoreTest.java index 360084f1d21..5fe08a2cb21 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/SQLiteLocalStoreTest.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/SQLiteLocalStoreTest.java @@ -577,16 +577,18 @@ public void testDisableIndexAutoCreationWorks() { @Test public void testDeleteAllIndexesWorksWithIndexAutoCreation() { - Query query = query("coll").filter(filter("matches", "==", true)); + Query query = query("coll").filter(filter("value", "==", "match")); int targetId = allocateQuery(query); - enableIndexAutoCreation(); + setIndexAutoCreationEnabled(true); + setMinCollectionSizeToAutoCreateIndex(0); + setRelativeIndexReadCostPerDocument(2); - applyRemoteEvent(addedRemoteEvent(doc("coll/a", 10, map("matches", true)), targetId)); - applyRemoteEvent(addedRemoteEvent(doc("coll/b", 10, map("matches", false)), targetId)); - applyRemoteEvent(addedRemoteEvent(doc("coll/c", 10, map("matches", false)), targetId)); - applyRemoteEvent(addedRemoteEvent(doc("coll/d", 10, map("matches", false)), targetId)); - applyRemoteEvent(addedRemoteEvent(doc("coll/e", 10, map("matches", true)), targetId)); + applyRemoteEvent(addedRemoteEvent(doc("coll/a", 10, map("value", "match")), targetId)); + applyRemoteEvent(addedRemoteEvent(doc("coll/b", 10, map("value", Double.NaN)), targetId)); + applyRemoteEvent(addedRemoteEvent(doc("coll/c", 10, map("value", null)), targetId)); + applyRemoteEvent(addedRemoteEvent(doc("coll/d", 10, map("value", "mismatch")), targetId)); + applyRemoteEvent(addedRemoteEvent(doc("coll/e", 10, map("value", "match")), targetId)); // First time query is running without indexes. // Based on current heuristic, collection document counts (5) > 2 * resultSize (2). @@ -595,7 +597,7 @@ public void testDeleteAllIndexesWorksWithIndexAutoCreation() { assertRemoteDocumentsRead(/* byKey= */ 0, /* byCollection= */ 2); assertQueryReturned("coll/a", "coll/e"); - disableIndexAutoCreation(); + setIndexAutoCreationEnabled(false); backfillIndexes(); From 74ba50023cf3f5270cbb4acbc257b9c47c0a40a8 Mon Sep 17 00:00:00 2001 From: cherylEnkidu Date: Thu, 27 Jul 2023 15:33:43 -0400 Subject: [PATCH 16/16] merge main branch --- .../firebase/firestore/local/LocalStore.java | 13 +- .../firestore/local/CountingQueryEngine.java | 10 -- .../model/TargetIndexMatcherTest.java | 159 ------------------ 3 files changed, 1 insertion(+), 181 deletions(-) diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/LocalStore.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/LocalStore.java index 78ac3bb3a5d..a5e79c76c1d 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/LocalStore.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/LocalStore.java @@ -147,22 +147,11 @@ public final class LocalStore implements BundleCallback { /** Used to generate targetIds for queries tracked locally. */ private final TargetIdGenerator targetIdGenerator; - private boolean autoIndexEnabled; - public LocalStore(Persistence persistence, QueryEngine queryEngine, User initialUser) { - this(persistence, queryEngine, initialUser, false); - } - - public LocalStore( - Persistence persistence, - QueryEngine queryEngine, - User initialUser, - boolean autoIndexEnabled) { hardAssert( persistence.isStarted(), "LocalStore was passed an unstarted persistence implementation"); this.persistence = persistence; this.queryEngine = queryEngine; - this.autoIndexEnabled = autoIndexEnabled; targetCache = persistence.getTargetCache(); bundleCache = persistence.getBundleCache(); @@ -186,7 +175,7 @@ private void initializeUserComponents(User user) { new LocalDocumentsView(remoteDocuments, mutationQueue, documentOverlayCache, indexManager); remoteDocuments.setIndexManager(indexManager); - queryEngine.initialize(localDocuments, indexManager, autoIndexEnabled); + queryEngine.initialize(localDocuments, indexManager); } public void start() { diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java index 4d56d2acf73..61385eff006 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/CountingQueryEngine.java @@ -102,16 +102,6 @@ public void setRelativeIndexReadCostPerDocument(double newCost) { queryEngine.setRelativeIndexReadCostPerDocument(newCost); } - @Override - public void setMinCollectionSizeToAutoCreateIndex(int newMin) { - queryEngine.setMinCollectionSizeToAutoCreateIndex(newMin); - } - - @Override - public void setRelativeIndexReadCost(int newCost) { - queryEngine.setRelativeIndexReadCost(newCost); - } - /** * Returns the number of documents returned by the RemoteDocumentCache's `getAll()` API (since the * last call to `resetCounts()`) diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/model/TargetIndexMatcherTest.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/model/TargetIndexMatcherTest.java index fe63de02612..627775c8a2a 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/model/TargetIndexMatcherTest.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/model/TargetIndexMatcherTest.java @@ -23,7 +23,6 @@ import static com.google.firebase.firestore.testutil.TestUtil.query; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.junit.Assume.assumeTrue; import com.google.firebase.firestore.core.Query; import com.google.firebase.firestore.core.Target; @@ -450,164 +449,6 @@ public void withMultipleNotIn() { validateServesTarget(q, "a", FieldIndex.Segment.Kind.ASCENDING); } - @Test - public void buildTargetIndex() { - Query q = - query("collId") - .filter(filter("a", "==", 1)) - .filter(filter("b", "==", 2)) - .orderBy(orderBy("__name__", "desc")); - TargetIndexMatcher targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - FieldIndex expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = query("collId").orderBy(orderBy("a")); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = query("collId").orderBy(orderBy("a")).orderBy(orderBy("b")); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = query("collId").filter(filter("a", "array-contains", "a")).orderBy(orderBy("b")); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = query("collId").orderBy(orderBy("b")); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = query("collId").orderBy(orderBy("a")); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = query("collId").filter(filter("a", ">", 1)).filter(filter("a", "<", 10)); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = query("collId").filter(filter("a", "in", Arrays.asList(1, 2))).filter(filter("b", "==", 5)); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = query("collId").filter(filter("value", "array-contains", "foo")).orderBy(orderBy("value")); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = - query("collId") - .filter(filter("a", "array-contains", "a")) - .filter(filter("a", ">", "b")) - .orderBy(orderBy("a", "asc")); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = query("collId").filter(filter("a", "==", 1)).orderBy(orderBy("__name__", "desc")); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = query("collId").filter(filter("a1", "==", "a")).filter(filter("a2", "==", "b")); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = - query("collId") - .filter(filter("equality1", "==", "a")) - .filter(filter("equality2", "==", "b")) - .filter(filter("inequality", ">=", "c")); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = - query("collId") - .filter(filter("equality1", "==", "a")) - .filter(filter("inequality", ">=", "c")) - .filter(filter("equality2", "==", "b")); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = query("collId").orderBy(orderBy("a")); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = query("collId").orderBy(orderBy("a", "desc")); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = query("collId").orderBy(orderBy("a")).orderBy(orderBy("__name__")); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = query("collId").filter(filter("a", "!=", 1)); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = query("collId").filter(filter("a", "!=", 1)).orderBy(orderBy("a")).orderBy(orderBy("b")); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = query("collId").filter(filter("a", "==", "a")).filter(filter("b", ">", "b")); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = - query("collId") - .filter(filter("a1", "==", "a")) - .filter(filter("a2", ">", "b")) - .orderBy(orderBy("a2", "asc")); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = - query("collId") - .filter(filter("a", ">=", 1)) - .filter(filter("a", "==", 5)) - .filter(filter("a", "<=", 10)); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - // assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - - q = - query("collId") - .filter(filter("a", "not-in", Arrays.asList(1, 2, 3))) - .filter(filter("a", ">=", 2)); - targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - } - - @Test - public void failedTest() { - assumeTrue("Skip this test due to a bug in CSI.", false); - Query q = - query("collId") - .filter(filter("a", ">=", 1)) - .filter(filter("a", "==", 5)) - .filter(filter("a", "<=", 10)); - TargetIndexMatcher targetIndexMatcher = new TargetIndexMatcher(q.toTarget()); - FieldIndex expectedIndex = targetIndexMatcher.BuildTargetIndex(); - assertTrue(targetIndexMatcher.servedByIndex(expectedIndex)); - } - @Test public void withMultipleOrderBys() { Query q =