-
Notifications
You must be signed in to change notification settings - Fork 617
Cleanup a number of warnings in the code. #137
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
Changes from 7 commits
ca50431
6b94249
f72a5b3
8a98285
23e5f94
917b0f8
34e8b0e
024e9fe
4d88c95
497434f
124db7f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,11 +51,11 @@ public FieldValue applyToRemoteDocument(FieldValue previousValue, FieldValue tra | |
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
public final boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
if (!(o instanceof ArrayTransformOperation)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hrm. I'm not sure about this... We have two implementations of ArrayTransformOperation: ArrayTransformOperation.Union, and ArrayTransformOperation.Remove. They shouldn't be considered equal even if they have the same elements being unioned or removed. I'm not sure what this means. Honestly, getClass() equality is exactly what we want, and I'm not sure how much I care about the substitutability principle... So we could keep the existing code but suppress the warning... or we could override equals again in the Union / Remove classes to do the right thing. WDYT? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed this change is wrong. I suggest suppressing with a comment indicating that type-sensitive equality is intended. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yup. I suppose the "correct" thing to do would be to roughly duplicate this code out to .Union.equals() and .Remove.equals(). (Or perhaps better, to move the operation into a member and eliminate the subclasses.) But just suppressing the warning seems most pragmatic. Done. |
||
return false; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,7 @@ | |
package com.google.firebase.firestore.model.mutation; | ||
|
||
import com.google.firebase.firestore.model.FieldPath; | ||
import java.util.Collection; | ||
import java.util.Set; | ||
|
||
/** | ||
* Provides a set of fields that can be used to partially patch a document. The FieldMask is used in | ||
|
@@ -25,14 +25,14 @@ | |
* companion ObjectValue, the field is deleted. foo.bar - Overwrites only the field bar of the | ||
* object foo. If foo is not an object, foo is replaced with an object containing foo. | ||
*/ | ||
public class FieldMask { | ||
public static FieldMask fromCollection(Collection<FieldPath> mask) { | ||
public final class FieldMask { | ||
public static FieldMask fromSet(Set<FieldPath> mask) { | ||
return new FieldMask(mask); | ||
} | ||
|
||
private final Collection<FieldPath> mask; | ||
private final Set<FieldPath> mask; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optional: what's the reason to prefer There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mostly, it doesn't matter much. But here's the reasons I went with set: a) The masks are conceptually unordered. I don't think speed is a concern in this case: it's hard to imagine having much more single digits of these; plus we're probably about to hit either the network or the disk which should dominate. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree that Set is the natural data structure (and perf, etc. aren't major concerns). That said, we may now get slightly different behavior than on other platforms (e.g. with regard to duplicates), though I don't think that's a big deal, and the Android behavior will probably be more correct. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While I agree with the academic distinction we're drawing here, this is a change in behavior that we really should mirror out to the other platforms. Once you consider that, is this change really worth it considering that the code works as is? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, Collection isn't right, but I'd be ok with List if we don't think ordering/duplicates are overly relevant. If we do think they're relevant, I'm happy to port to the other platforms. Another option is to leave it as Collection, but eliminate the .equals() method and use the default referential equality instead. Looking at this a bit closer, I don't think we ever actually call FieldMask.equals()... at least not in the test suite. (Tested by changing the implementation to unconditionally throw and re-run all tests.) We do allow callers to fetch the mask, but we only ever iterate over the contents. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm fine with any of these options (including keeping it as a Set as you have it now). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok; I've gone with set. I'll port to the others. |
||
|
||
private FieldMask(Collection<FieldPath> mask) { | ||
private FieldMask(Set<FieldPath> mask) { | ||
this.mask = mask; | ||
} | ||
|
||
|
@@ -49,6 +49,11 @@ public boolean equals(Object o) { | |
return mask.equals(fieldMask.mask); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "FieldMask{mask=" + mask.toString() + "}"; | ||
} | ||
|
||
/** | ||
* Verifies that 'fieldPath' is included by at least one field in this field mask. | ||
* | ||
|
@@ -69,7 +74,7 @@ public int hashCode() { | |
return mask.hashCode(); | ||
} | ||
|
||
public Collection<FieldPath> getMask() { | ||
public Set<FieldPath> getMask() { | ||
return mask; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,6 +44,7 @@ | |
import com.google.firestore.v1beta1.Value; | ||
import com.google.firestore.v1beta1.Write; | ||
import com.google.protobuf.ByteString; | ||
import java.util.HashSet; | ||
import org.junit.Before; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
|
@@ -71,7 +72,7 @@ public void testEncodesMutationBatch() { | |
new PatchMutation( | ||
key("bar/baz"), | ||
TestUtil.wrapObject(map("a", "b", "num", 1)), | ||
FieldMask.fromCollection(asList(field("a"))), | ||
FieldMask.fromSet(new HashSet<>(asList(field("a")))), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Previously this was already slightly ridiculous but this iteration is now over the top. Please add a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Deferred (slightly). If we go with a list, then I'll just revert this line. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
com.google.firebase.firestore.model.mutation.Precondition.exists(true)); | ||
Mutation del = deleteMutation("baz/quux"); | ||
Timestamp writeTime = Timestamp.now(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -78,6 +78,8 @@ | |
import java.util.Map; | ||
import java.util.Map.Entry; | ||
import java.util.Set; | ||
import java.util.SortedSet; | ||
import java.util.TreeSet; | ||
import javax.annotation.Nullable; | ||
|
||
/** A set of utilities for tests */ | ||
|
@@ -431,12 +433,12 @@ public static PatchMutation patchMutation( | |
boolean merge = updateMask != null; | ||
|
||
// We sort the fieldMaskPaths to make the order deterministic in tests. | ||
Collections.sort(objectMask); | ||
SortedSet<FieldPath> fieldMaskPaths = new TreeSet<>(merge ? updateMask : objectMask); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hrm. I wonder if this is really necessary. Were we just sorting them before so equals() would work out? If so, then we're already good. What happens if you use a HashSet here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The production code passes a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh. I thought it was a HashSet. In any case, I'm fine with using a TreeSet, but the comment about sorting seems confusing / wrong now. Perhaps just remove it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The sort is because we compare the actual protos (post serialization from models to protos) in the serializer tests. Sets/Lists are flattened down to repeated fields in iterator order. That maps well for lists (since order is preserved) but isn't great for sets, since our test would incorrectly state that {foo,bar} != {bar,foo}. (We couldn't have used Model.equals() here, because of the whole Collection.equals() not making sense when both lists and sets are involved, though if the test happened to use the same type as the model that it had set up, then we would've gotten away with it.) The old code didn't know if a list or set was used (since a Collection could be either), so it sorted them to ensure everything was fine. The new code (currently) knows that sets are used. Therefore, it needs to sort them to ensure the tests consider the results correct. If we switch to list, I think we could drop the sort altogether. I've updated the comment to hopefully make this clearer. (Though will remove it if we do the set->list thing.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah! Comment makes perfect sense now, thanks. |
||
|
||
return new PatchMutation( | ||
key(path), | ||
objectValue, | ||
FieldMask.fromCollection(merge ? updateMask : objectMask), | ||
FieldMask.fromSet(fieldMaskPaths), | ||
merge ? Precondition.NONE : Precondition.exists(true)); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: why not use
instanceof
here and inQuery#equals
? The article you linked states thatinstanceof
is never worse thangetClass
:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, done.