Skip to content

Remote document reads elision #3246

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 14 commits into from
Jan 11, 2022
Merged

Remote document reads elision #3246

merged 14 commits into from
Jan 11, 2022

Conversation

wu-hui
Copy link
Contributor

@wu-hui wu-hui commented Dec 15, 2021

No description provided.

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Dec 15, 2021

Coverage Report 1

Affected Products

  • firebase-firestore

    Overall coverage changed from 45.25% (5657f12) to 45.26% (af9449d) by +0.02%.

    FilenameBase (5657f12)Merge (af9449d)Diff
    DeleteMutation.java90.00%95.00%+5.00%
    PatchMutation.java98.39%100.00%+1.61%

Test Logs

Notes

  • Commit (af9449d) is created by Prow via merging PR base commit (5657f12) and head commit (6f97357).
  • Run gradle <product>:checkCoverage to produce HTML coverage reports locally. After gradle commands finished, report files can be found under <product-build-dir>/reports/jacoco/.

  1. https://storage.googleapis.com/firebase-sdk-metric-reports/EJQTWXmIPZ.html

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Dec 15, 2021

Size Report 1

Affected Products

  • firebase-firestore

    TypeBase (5657f12)Merge (af9449d)Diff
    aar1.23 MB1.23 MB+49 B (+0.0%)
    apk (release)3.33 MB3.33 MB-48 B (-0.0%)

Test Logs

Notes

  • Commit (af9449d) is created by Prow via merging PR base commit (5657f12) and head commit (6f97357).

  1. https://storage.googleapis.com/firebase-sdk-metric-reports/G4Ce2oBnai.html

Copy link
Contributor

@schmidt-sebastian schmidt-sebastian left a comment

Choose a reason for hiding this comment

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

Thank you for doing this. Some suggestions to trim this down a bit.

}

Map<DocumentKey, MutableDocument> remoteDocuments =
remoteDocumentCache.getAll(query.getPath(), offset, ignore);
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this part of the optimization is quite worth it. We are still reading the elements from the cache. What do you think about not touching getAll()?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It might be useful when user goes offline long enough and there are a lot documents with overlays. It is hard to say at what point it is worth it, but it does not hurt performance so let's keep it?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd rather keep it as is. The old way is shorter, easier to understand and does not require porting. The only thing you are saving here is the Proto decoding, which already happens in the background.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, removed.

package com.google.firebase.firestore.model;

/** Interface exposing underlying document information that is not visible in {@code Document}. */
public interface InternalDocument extends Document {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't quite understand the need for this indirection. Can you explain your reasoning?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess I wanted a bit type safety, that getVersion and getReadTime can only be accessed via this interface, instead of setting them to 0. And DocumentSnapshot holds a Document so no access to version/readtime to user code.

I feel safer this way, comparing to reviewing all places where they are used and reason whether 0 makes sense there. Setting them to 0 also felt "wrong" because we know they are at least the versions they are set now, and setting to 0 gives up that information.

Copy link
Contributor

Choose a reason for hiding this comment

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

My concern here is the same as with the other change: It adds a layer of indirection which adds porting work and code size. We already use SnapshotVersion.NONE as the "non-existing" snapshot version in a lot of places in our codebase.

If you want to achieve what you are after, you could make the missing versions nullable - but I really thing we should just continue to use SnapshotVersion.NONE.

I also do not quite understand where the name "Internal" comes from. I think you mean something like "FoundDocument", which we used to have but moved away from.

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.

@@ -164,15 +166,18 @@ public MutableDocument get(DocumentKey documentKey) {
if (collections.isEmpty()) {
return Collections.emptyMap();
} else if (BINDS_PER_STATEMENT * collections.size() < SQLitePersistence.MAX_ARGS) {
return getAll(collections, offset, limit);
return getAll(collections, offset, limit, new HashSet<>());
Copy link
Contributor

Choose a reason for hiding this comment

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

Collections.emptySet() to avoid creating a new object.

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.

* Returns the version of this document if it exists or a version at which this document was
* guaranteed to not exist.
*/
SnapshotVersion getVersion();
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure where to put this as a comment, but I think we should just set the "version" and "readTime" to 0 in setHasLocalMutations()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See my other comment.

@@ -389,7 +389,8 @@ public void testHandlesSetMutationThenDocument() {
asList(targetId),
emptyList()));
assertChanged(doc("foo/bar", 2, map("foo", "bar")).setHasLocalMutations());
assertContains(doc("foo/bar", 2, map("foo", "bar")).setHasLocalMutations());
// Version is 0 because of remote document elision
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we need these comments once we use SnapshotVersion.NONE for all documents with local mutations (plus, I am not sure that the terminology used in this comment makes it obvious what is going on here)

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 IS a bit awkward, but let's decide which way to go first.

Copy link
Contributor

Choose a reason for hiding this comment

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

If we keep the comment, we should phrase it differently and remove the term "elision", which requires too much knowledge to understand.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed comments.

wu-hui and others added 2 commits January 4, 2022 09:38
@wu-hui wu-hui assigned schmidt-sebastian and unassigned wu-hui Jan 7, 2022
@wu-hui
Copy link
Contributor Author

wu-hui commented Jan 7, 2022

/retest

@@ -546,9 +548,10 @@ public void testHandlesPatchMutationThenDocumentThenAck() {
int targetId = allocateQuery(query);
applyRemoteEvent(
addedRemoteEvent(
doc("foo/bar", 1, map("it", "base")).setHasLocalMutations(),
asList(doc("foo/bar", 1, map("it", "base")).setHasLocalMutations()),
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you can undo the change to "addedRemoteEvent". A remote doc should never have local mutations, so some of these tests are wrong.

@schmidt-sebastian schmidt-sebastian removed their assignment Jan 10, 2022
@wu-hui wu-hui merged commit 712e5b8 into master Jan 11, 2022
@wu-hui wu-hui deleted the wuandy/JustEnoughDocReads branch January 11, 2022 18:19
@firebase firebase locked and limited conversation to collaborators Feb 11, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants