Skip to content

Release Overlay #3112

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Dec 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion firebase-firestore/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ Android changes are not released automatically. Ensure that changes are released
by opting into a release at
[go/firebase-android-release](http:go/firebase-android-release) (Googlers only).

# Unreleased
# 24.1.0
- [changed] Performance optimization for offline usage.
- [changed] Improved performance for queries with collections that contain
subcollections.

Expand Down
7 changes: 0 additions & 7 deletions firebase-firestore/firebase-firestore.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,6 @@ android.libraryVariants.all { variant ->
} else {
variant.buildConfigField("boolean", "ENABLE_INDEXING", "false")
}

// TODO(Overlay): Delete below once overlay is shipped.
if (localProps['firestoreEnableOverlay']) {
variant.buildConfigField("boolean", "ENABLE_OVERLAY", "true")
} else {
variant.buildConfigField("boolean", "ENABLE_OVERLAY", "false")
}
}

configurations.all {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,6 @@ public static FirebaseFirestore testFirestore(
// This unfortunately is a global setting that affects existing Firestore clients.
Logger.setLogLevel(logLevel);

// TODO(Overlay): Remove below once this is ready to ship.
Persistence.OVERLAY_SUPPORT_ENABLED = true;
Persistence.INDEXING_SUPPORT_ENABLED = true;

Context context = ApplicationProvider.getApplicationContext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@ private void recalculateAndSaveOverlays(Map<DocumentKey, MutableDocument> docs)
// along the way.
for (MutationBatch batch : batches) {
for (DocumentKey key : batch.getKeys()) {
FieldMask mask = batch.applyToLocalView(docs.get(key), masks.get(key));
FieldMask mask = masks.containsKey(key) ? masks.get(key) : FieldMask.EMPTY;
mask = batch.applyToLocalView(docs.get(key), mask);
masks.put(key, mask);
int batchId = batch.getBatchId();
if (!documentsByBatchId.containsKey(batchId)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public abstract class Persistence {

/** Temporary setting for enabling document overlays. */
// TODO(Overlay): Remove this.
public static boolean OVERLAY_SUPPORT_ENABLED = BuildConfig.ENABLE_OVERLAY;
public static boolean OVERLAY_SUPPORT_ENABLED = true;
/** Constant string to indicate a data migration is required to support overlays. */
public static String DATA_MIGRATION_BUILD_OVERLAYS = "BUILD_OVERLAYS";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,10 @@ class SQLiteSchema {
* The version of the schema. Increase this by one for each migration added to runMigrations
* below.
*/
static final int VERSION = 13;

static final int OVERLAY_SUPPORT_VERSION = VERSION + 1;
static final int VERSION = 14;

// TODO(indexing): Remove this constant and increment VERSION to enable indexing support
static final int INDEXING_SUPPORT_VERSION = OVERLAY_SUPPORT_VERSION + 1;
static final int INDEXING_SUPPORT_VERSION = VERSION + 1;

/**
* The batch size for data migrations.
Expand All @@ -75,14 +73,11 @@ class SQLiteSchema {
}

void runSchemaUpgrades() {
runSchemaUpgrades(0, VERSION);
runSchemaUpgrades(0);
}

void runSchemaUpgrades(int fromVersion) {
int toVersion = VERSION;
if (Persistence.OVERLAY_SUPPORT_ENABLED) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should remove the flag in its entirety to just set it to true but leave all conditional checks. This makes sure that we can turn it to false again.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one here has to be deleted, because if the version is increased again, doing this will override it.

toVersion = OVERLAY_SUPPORT_VERSION;
}
if (Persistence.INDEXING_SUPPORT_ENABLED) {
toVersion = INDEXING_SUPPORT_VERSION;
}
Expand Down Expand Up @@ -178,8 +173,16 @@ void runSchemaUpgrades(int fromVersion, int toVersion) {
ensurePathLength();
}

if (fromVersion < 14 && toVersion >= 14) {
Preconditions.checkState(
Persistence.OVERLAY_SUPPORT_ENABLED || Persistence.INDEXING_SUPPORT_ENABLED);
createOverlays();
createDataMigrationTable();
addPendingDataMigration(Persistence.DATA_MIGRATION_BUILD_OVERLAYS);
}

/*
* Adding a new migration? READ THIS FIRST!
* Adding a new schema upgrade? READ THIS FIRST!
*
* Be aware that the SDK version may be downgraded then re-upgraded. This means that running
* your new migration must not prevent older versions of the SDK from functioning. Additionally,
Expand All @@ -190,13 +193,6 @@ void runSchemaUpgrades(int fromVersion, int toVersion) {
* maintained invariants from later versions, so migrations that update values cannot assume
* that existing values have been properly maintained. Calculate them again, if applicable.
*/
if (fromVersion < OVERLAY_SUPPORT_VERSION && toVersion >= OVERLAY_SUPPORT_VERSION) {
Preconditions.checkState(
Persistence.OVERLAY_SUPPORT_ENABLED || Persistence.INDEXING_SUPPORT_ENABLED);
createOverlays();
createDataMigrationTable();
addPendingDataMigration(Persistence.DATA_MIGRATION_BUILD_OVERLAYS);
}

if (fromVersion < INDEXING_SUPPORT_VERSION && toVersion >= INDEXING_SUPPORT_VERSION) {
Preconditions.checkState(Persistence.INDEXING_SUPPORT_ENABLED);
Expand Down Expand Up @@ -708,7 +704,9 @@ private void createDataMigrationTable() {
}

private void addPendingDataMigration(String migration) {
db.execSQL("INSERT INTO data_migrations (migration_name) VALUES (?)", new String[] {migration});
db.execSQL(
"INSERT OR IGNORE INTO data_migrations (migration_name) VALUES (?)",
new String[] {migration});
}

private boolean tableExists(String table) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package com.google.firebase.firestore.model.mutation;

import com.google.firebase.firestore.model.FieldPath;
import java.util.HashSet;
import java.util.Set;

/**
Expand All @@ -26,6 +27,8 @@
* object foo. If foo is not an object, foo is replaced with an object containing foo.
*/
public final class FieldMask {
public static FieldMask EMPTY = fromSet(new HashSet<>());

public static FieldMask fromSet(Set<FieldPath> mask) {
return new FieldMask(mask);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
Expand All @@ -52,17 +51,6 @@ public abstract class DocumentOverlayCacheTestCase {
private DocumentOverlayCache overlays;
private static boolean overlayEnabled = false;

@BeforeClass
public static void beforeClass() {
overlayEnabled = Persistence.OVERLAY_SUPPORT_ENABLED;
Persistence.OVERLAY_SUPPORT_ENABLED = true;
}

@BeforeClass
public static void afterClass() {
Persistence.OVERLAY_SUPPORT_ENABLED = overlayEnabled;
}

@Before
public void setUp() {
persistence = getPersistence();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import static com.google.firebase.firestore.testutil.TestUtil.viewChanges;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
Expand Down Expand Up @@ -75,16 +74,17 @@
import com.google.firebase.firestore.testutil.TestUtil;
import com.google.firebase.firestore.util.AsyncQueue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

/**
Expand Down Expand Up @@ -155,23 +155,27 @@ private void udpateViews(int targetId, boolean fromCache) {
notifyLocalViewChanges(viewChanges(targetId, fromCache, asList(), asList()));
}

private void acknowledgeMutation(long documentVersion, @Nullable Object transformResult) {
private void acknowledgeMutationWithTransformResults(
long documentVersion, Object... transformResult) {
MutationBatch batch = batches.remove(0);
SnapshotVersion version = version(documentVersion);
MutationResult mutationResult =
new MutationResult(
version,
transformResult != null
? Collections.singletonList(TestUtil.wrap(transformResult))
: Collections.emptyList());
List<MutationResult> mutationResults =
Collections.singletonList(new MutationResult(version, emptyList()));

if (transformResult.length != 0) {
mutationResults =
Arrays.stream(transformResult)
.map(r -> new MutationResult(version, Collections.singletonList(TestUtil.wrap(r))))
.collect(Collectors.toList());
}

MutationBatchResult result =
MutationBatchResult.create(
batch, version, singletonList(mutationResult), WriteStream.EMPTY_STREAM_TOKEN);
MutationBatchResult.create(batch, version, mutationResults, WriteStream.EMPTY_STREAM_TOKEN);
lastChanges = localStore.acknowledgeBatch(result);
}

private void acknowledgeMutation(long documentVersion) {
acknowledgeMutation(documentVersion, null);
acknowledgeMutationWithTransformResults(documentVersion);
}

private void rejectMutation() {
Expand Down Expand Up @@ -974,7 +978,10 @@ public void testReadsAllDocumentsForInitialCollectionQueries() {
localStore.executeQuery(query, /* usePreviousResults= */ true);

assertRemoteDocumentsRead(/* byKey= */ 0, /* byQuery= */ 2);
if (!Persistence.OVERLAY_SUPPORT_ENABLED) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a blocker, but we should ideally remove all statements like this (including the flag) or leave them all here. If we leave the flag, we should be able to turn it off during development and have the tests pass.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

if (Persistence.OVERLAY_SUPPORT_ENABLED) {
// No mutations are read because only overlay is needed.
assertMutationsRead(/* byKey= */ 0, /* byQuery= */ 0);
} else {
assertMutationsRead(/* byKey= */ 0, /* byQuery= */ 1);
}
}
Expand Down Expand Up @@ -1070,7 +1077,7 @@ public void testHandlesSetMutationThenAckThenTransformThenAckThenTransform() {
assertContains(doc("foo/bar", 1, map("sum", 1)).setHasLocalMutations());
assertChanged(doc("foo/bar", 1, map("sum", 1)).setHasLocalMutations());

acknowledgeMutation(2, 1);
acknowledgeMutationWithTransformResults(2, 1);
assertChanged(doc("foo/bar", 2, map("sum", 1)).setHasCommittedMutations());
assertContains(doc("foo/bar", 2, map("sum", 1)).setHasCommittedMutations());

Expand Down Expand Up @@ -1284,19 +1291,17 @@ public void testHandlesSetMutationThenTransformThenRemoteEventThenTransform() {
assertChanged(doc("foo/bar", 2, map("sum", 3)).setHasLocalMutations());
assertContains(doc("foo/bar", 2, map("sum", 3)).setHasLocalMutations());

acknowledgeMutation(3, 1);
acknowledgeMutationWithTransformResults(3, 1);
assertChanged(doc("foo/bar", 3, map("sum", 3)).setHasLocalMutations());
assertContains(doc("foo/bar", 3, map("sum", 3)).setHasLocalMutations());

acknowledgeMutation(4, 1339);
acknowledgeMutationWithTransformResults(4, 1339);
assertChanged(doc("foo/bar", 4, map("sum", 1339)).setHasCommittedMutations());
assertContains(doc("foo/bar", 4, map("sum", 1339)).setHasCommittedMutations());
}

@Test
@Ignore("Test fails in CI")
// TODO(Overlay): Fix me :)
public void testHoldsBackOnlyNonIdempotentTransforms() {
public void testHoldsBackTransforms() {
Query query = Query.atPath(ResourcePath.fromString("foo"));
allocateQuery(query);
assertTargetId(2);
Expand Down Expand Up @@ -1333,8 +1338,13 @@ public void testHoldsBackOnlyNonIdempotentTransforms() {
asList(2),
emptyList()));
assertChanged(
doc("foo/bar", 2, map("sum", 1, "array_union", asList("bar", "foo")))
.setHasLocalMutations());
doc("foo/bar", 2, map("sum", 1, "array_union", asList("foo"))).setHasLocalMutations());

acknowledgeMutationWithTransformResults(3, 1338, asList("bar", "foo"));
assertChanged(
doc("foo/bar", 3, map("sum", 1338, "array_union", asList("bar", "foo")))
.withReadTime(new SnapshotVersion(new Timestamp(0, 3000)))
.setHasCommittedMutations());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@

package com.google.firebase.firestore.local;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
Expand All @@ -25,17 +23,6 @@
public class MemoryLocalStoreTest extends LocalStoreTestCase {
private static boolean enabled = false;

@BeforeClass
public static void beforeClass() {
enabled = Persistence.OVERLAY_SUPPORT_ENABLED;
Persistence.OVERLAY_SUPPORT_ENABLED = false;
}

@AfterClass
public static void afterClass() {
Persistence.OVERLAY_SUPPORT_ENABLED = enabled;
}

@Override
Persistence getPersistence() {
return PersistenceTestHelpers.createEagerGCMemoryPersistence();
Expand Down

This file was deleted.

Loading