-
-
Notifications
You must be signed in to change notification settings - Fork 734
Avoid regenerating all formatters when only one object/union/enum changes #1884
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
Avoid regenerating all formatters when only one object/union/enum changes #1884
Conversation
…AvoidRegenerateAllFormatters
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.
Thank you very much for identifying this shortcoming and proposing a fix. I think we can take it, after a few issues are worked out.
@@ -13,4 +13,6 @@ public override string GetFormatterInstanceForResolver() | ||
? base.GetFormatterInstanceForResolver() | ||
: $"{this.GetFormatterNameForResolver()}.{this.CustomFormatter.InstanceProvidingMember}"; | ||
} | ||
|
||
public override int GetHashCode() => base.GetHashCode(); |
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.
Why is this necessary?
Same question for the other additions like this.
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.
Sorry for the late reply. I thought GetHashCode
in base class is sufficent to hash the instances and tried to avoid use every fields to hash, so I made child classes to use GetHashCode
in base class.
@@ -124,5 +124,5 @@ public virtual bool Equals(ObjectSerializationInfo? other) | ||
&& NeedsCastOnBefore == other.NeedsCastOnBefore; | ||
} | ||
|
||
public override int GetHashCode() => throw new NotImplementedException(); | ||
public override int GetHashCode() => base.GetHashCode(); |
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.
This is insufficient, for the same reason we need to implement our own Equals
method: some fields are arrays, which don't implement by-value equality (or GetHashCode), so the default GetHashCode
implementation would produce a different return value even though the content may be equal by-value. An invariant that we must hold is that GetHashCode return the same value from two objects whose Equals method returns true for each other.
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.
I added the fixes that seemed prudent. I'm ready to merge this. Thank you for your contribution.
Currently, if one object with
MessagePackObjectAttribute
changes, all formatters would be regenerated because the source (FullModel
) ofcontext.RegisterSourceOutput
changes. Since one generated file contains only one formatter for one object, these files can be generated separately.This PR also fixes an issue in #1874 where
SequenceEqual
was used to compareImmutableHashSet
.SetEqual
should be used instead.