Skip to content

Replace usage of transforms with update transforms #7276

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 7 commits into from
Jan 21, 2021

Conversation

thebrianchen
Copy link

@thebrianchen thebrianchen commented Jan 8, 2021

Porting from web and Android.

First commit contains initial port changes. Second commit changes contains code removal for localTransformResults, which was done in Android and backported to web.

@google-cla google-cla bot added the cla: yes label Jan 8, 2021
@thebrianchen thebrianchen force-pushed the bc/update-transforms branch 3 times, most recently from 11e07ae to 05f33ce Compare January 13, 2021 23:58
@thebrianchen thebrianchen self-assigned this Jan 14, 2021
@thebrianchen thebrianchen marked this pull request as ready for review January 14, 2021 00:36
@thebrianchen thebrianchen removed their assignment Jan 14, 2021
@thebrianchen thebrianchen changed the title WIP: failing merge tests Replace usage of transforms with update transforms Jan 14, 2021
schmidt-sebastian added a commit to firebase/firebase-android-sdk that referenced this pull request Jan 19, 2021
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.

I am surprised by how pretty this looks. Thanks for doing this!

for (size_t i = proto.writes_count; i > 0; --i) {
// Calculate appropriate index from `i`. We do this because decrementing
// `i` when i == 0 results in wraparound.
size_t index = i - 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you use a more specific name? "i" and "index" both mean the same thing. Also maybe "underflow" instead of "wraparound?"

Copy link
Author

Choose a reason for hiding this comment

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

N/A now since we're iterating in the normal direction.

// Reverse the mutations to preserve the original ordering since the above
// for-loop iterates in reverse order. We use reverse() instead of prepending
// the elements into the mutations array since prepending to a List is O(n).
std::reverse(mutations.begin(), mutations.end());
Copy link
Contributor

Choose a reason for hiding this comment

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

We could probably get rid of the underflow issue and the reversing if we flipped the order of iterations and looked ahead in line 344 (index +1 < proto.writes_count && which_operation ...).

Copy link
Author

Choose a reason for hiding this comment

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

Big brain suggestion!! Done, and removed the test with only a transformMutation as well.

for (size_t j = 0; j < mutation.transform.field_transforms_count; ++j) {
new_mutation.update_transforms[j] =
mutation.transform.field_transforms[j];
}
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 know the answer here - but could we just assign the old array to the new location?

Copy link
Author

Choose a reason for hiding this comment

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

Done.

for (const FieldTransform& transform : field_transforms_) {
absl::optional<FieldValue> existing_value;
if (maybe_doc && maybe_doc->is_document()) {
existing_value = Document(*maybe_doc).field(transform.path());
Copy link
Contributor

Choose a reason for hiding this comment

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

This creates a new Document for every iteration. We should probably do this outside of th eloop.

Copy link
Author

Choose a reason for hiding this comment

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

done.

* @return The transform results array.
*/
virtual std::vector<FieldValue> ServerTransformResults(
const absl::optional<MaybeDocument>& base_doc,
Copy link
Contributor

Choose a reason for hiding this comment

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

Now that we removed base_doc from LocalTransformResults, should this be maybe_doc?

Copy link
Author

Choose a reason for hiding this comment

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

Good catch, done.

Comment on lines +190 to +198
EXPECT_EQ(google_firestore_v1_Write_update_tag, encoded.which_operation);
EXPECT_EQ(2, encoded.update.fields_count);
EXPECT_EQ("a", nanopb::MakeString(encoded.update.fields[0].key));
EXPECT_EQ("b",
nanopb::MakeString(encoded.update.fields[0].value.string_value));
EXPECT_EQ("num", nanopb::MakeString(encoded.update.fields[1].key));
EXPECT_EQ(1, encoded.update.fields[1].value.integer_value);
EXPECT_FALSE(encoded.has_update_mask);
EXPECT_FALSE(encoded.has_current_document);
Copy link
Contributor

Choose a reason for hiding this comment

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

Fun :/

Copy link
Author

Choose a reason for hiding this comment

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

thanks for your help in helping me debug this earlier!

Comment on lines 1441 to 1445
// WriteMutations({
// testutil::PatchMutation("foo/bar", Map(), {}),
// testutil::PatchMutation("foo/bar", Map(),
// {testutil::Increment("sum", Value(1))}),
// });
Copy link
Contributor

Choose a reason for hiding this comment

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

Oh no! Such a great PR, ruined by this careless mistake. I guess I gotta press 'Request Changes' now :)

Copy link
Author

Choose a reason for hiding this comment

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

aw shucks I was so close


ExpectRoundTrip(model, proto);
PatchMutation patch_model =
Copy link
Contributor

Choose a reason for hiding this comment

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

This test could be split in two. Both verification chains are mostly independent and smaller tests are usually better. You might also be able to create some helper methods for some of the state manipulation that is duplicated in this test and the test below.

Copy link
Author

Choose a reason for hiding this comment

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

I kept them together in order to keep parity with Web/Android. There aren't that many helpers I could pull, and these two tests don't share much else in common with the other tests in this file, which would end up making the tests harder to read.


ExpectRoundTrip(model, proto);
PatchMutation patch_model = testutil::PatchMutation(
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment as above.

schmidt-sebastian added a commit to firebase/firebase-android-sdk that referenced this pull request Jan 20, 2021
Copy link
Author

@thebrianchen thebrianchen left a comment

Choose a reason for hiding this comment

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

thanks!

* @return The transform results array.
*/
virtual std::vector<FieldValue> ServerTransformResults(
const absl::optional<MaybeDocument>& base_doc,
Copy link
Author

Choose a reason for hiding this comment

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

Good catch, done.

Comment on lines 1441 to 1445
// WriteMutations({
// testutil::PatchMutation("foo/bar", Map(), {}),
// testutil::PatchMutation("foo/bar", Map(),
// {testutil::Increment("sum", Value(1))}),
// });
Copy link
Author

Choose a reason for hiding this comment

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

aw shucks I was so close

for (const FieldTransform& transform : field_transforms_) {
absl::optional<FieldValue> existing_value;
if (maybe_doc && maybe_doc->is_document()) {
existing_value = Document(*maybe_doc).field(transform.path());
Copy link
Author

Choose a reason for hiding this comment

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

done.

Comment on lines +190 to +198
EXPECT_EQ(google_firestore_v1_Write_update_tag, encoded.which_operation);
EXPECT_EQ(2, encoded.update.fields_count);
EXPECT_EQ("a", nanopb::MakeString(encoded.update.fields[0].key));
EXPECT_EQ("b",
nanopb::MakeString(encoded.update.fields[0].value.string_value));
EXPECT_EQ("num", nanopb::MakeString(encoded.update.fields[1].key));
EXPECT_EQ(1, encoded.update.fields[1].value.integer_value);
EXPECT_FALSE(encoded.has_update_mask);
EXPECT_FALSE(encoded.has_current_document);
Copy link
Author

Choose a reason for hiding this comment

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

thanks for your help in helping me debug this earlier!

// Reverse the mutations to preserve the original ordering since the above
// for-loop iterates in reverse order. We use reverse() instead of prepending
// the elements into the mutations array since prepending to a List is O(n).
std::reverse(mutations.begin(), mutations.end());
Copy link
Author

Choose a reason for hiding this comment

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

Big brain suggestion!! Done, and removed the test with only a transformMutation as well.

for (size_t j = 0; j < mutation.transform.field_transforms_count; ++j) {
new_mutation.update_transforms[j] =
mutation.transform.field_transforms[j];
}
Copy link
Author

Choose a reason for hiding this comment

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

Done.

for (size_t i = proto.writes_count; i > 0; --i) {
// Calculate appropriate index from `i`. We do this because decrementing
// `i` when i == 0 results in wraparound.
size_t index = i - 1;
Copy link
Author

Choose a reason for hiding this comment

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

N/A now since we're iterating in the normal direction.


ExpectRoundTrip(model, proto);
PatchMutation patch_model =
Copy link
Author

Choose a reason for hiding this comment

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

I kept them together in order to keep parity with Web/Android. There aren't that many helpers I could pull, and these two tests don't share much else in common with the other tests in this file, which would end up making the tests harder to read.

@thebrianchen thebrianchen removed their assignment Jan 20, 2021
Comment on lines 352 to 354
new_mutation.update_transforms =
MakeArray<_google_firestore_v1_DocumentTransform_FieldTransform>(
transform_mutation.transform.field_transforms_count);
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we still need this call?

Copy link
Author

Choose a reason for hiding this comment

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

removed.

@thebrianchen thebrianchen merged commit 0088d09 into master Jan 21, 2021
@thebrianchen thebrianchen deleted the bc/update-transforms branch January 21, 2021 18:03
andreaowu pushed a commit to firebase/firebase-android-sdk that referenced this pull request Jan 29, 2021
@firebase firebase locked and limited conversation to collaborators Feb 21, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants