Skip to content
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

Reducing the Use of oneof in Protos #3527

Merged
merged 12 commits into from
Feb 14, 2022
Merged

Reducing the Use of oneof in Protos #3527

merged 12 commits into from
Feb 14, 2022

Conversation

kevinkreiser
Copy link
Member

In a previous PR #3457, we migrated our protobuf definitions to proto3. When we did that we needed to make use of a trick that uses the oneof keyword to emulate the ability to do optional that was removed from the language in proto3. We took the conservative approach by simply adding oneof to any previously optional parameter. This is pretty ugly and quite verbose but it allowed us to make the migration without having to think about each individual field.

This PR significantly reduces the use of oneof. I accomplished this in the following ways:

  1. in proto3 default values for all primative types are 0 (strings are empty string), this means that if the field has no semantic use for the 0 value (or empty string) we can simply allow these values to communicate them not being set. many many cases in the code worked that way so i was able to remove a great many oneofs this way
  2. enums which make use of the default value 0 but do need differentiate being unset get a new default value denoting its unset-ness
  3. deleteing unused options such as all the address stuff in location

Cases where we cannot remove oneof are those in which we need to differentiate between being set and not set (optional) but also the default value is not 0 in the case its not set. For example our node snap tolerance defaults to 5 meters when you dont set it, but if we removed the oneof this would end up making 0 the new default which is a breaking change. In those cases we need to keep using oneof. I s hould note that this only matters for pbf input, json input allows us to check whether something was or wasnt set.


#include <string>

namespace valhalla {
namespace thor {
namespace baldr {
Copy link
Contributor

Choose a reason for hiding this comment

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

Whats the reason for moving this to baldr?

Copy link
Member Author

Choose a reason for hiding this comment

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

this was so that we could re-use this class in odin when we serialize the route out. im not sure its the best place, we could hvae argued to put it in tyr also i think. if you like tyr better we could totally move that in the next pr. also sorry for not answering this question earlier somehow i didnt see it!

@mandeepsandhu
Copy link
Contributor

For string types, does this PR switch to using !string.empty() where previously we'd do has_string() ?

mandeepsandhu
mandeepsandhu previously approved these changes Feb 2, 2022
Copy link
Contributor

@mandeepsandhu mandeepsandhu left a comment

Choose a reason for hiding this comment

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

Thanks for the cleanup! Too many diffs, I'll base my review on all tests passing! 🙂

@kevinkreiser
Copy link
Member Author

@mandeepsandhu its ready for another look!

oneof has_distance_from_leg_origin {
double distance_from_leg_origin = 55;
}
repeated PathEdge edges = 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

any concerns renumbering the fields here and few other places? I remember we store the trip leg pbf for some of the pinpoint tests which would fail to read back the correct data if the pbf fields were renumbered.

I guess since the tests are passing the renumbering here does not affect the few places we've stored these protobufs on disk?

Copy link
Member Author

Choose a reason for hiding this comment

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

oh it broke the tests, but i fixed them by leaving the old defs there and copying them to the new defs and overwiiting the files. ive been doing this alot for all the protobuf changes, its a huge pain in the butt but its worth it to get the code cleaner. you see how it did it over here (takes a long time to load because of diff size): https://github.com/valhalla/valhalla/pull/3527/files#diff-836ee7bf7651f8100e6b6072ab85387a7fee2ea9178762aabf200726bd31a0d9R32

Copy link
Member Author

Choose a reason for hiding this comment

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

the other stuff i renumbered were things that were parsed from the request, so i could just call ParseApi and then again overwrite the proto after i've parsed the request. Also a pain in the butt but something ive been doing a lot with all these changes and organizational stuff

Copy link
Contributor

Choose a reason for hiding this comment

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

ah ok I missed some of those diffs at first glance (as you said, because of the size of the change github had issues expanding all the diffs).

thanks for updating the tests! 👍

@@ -44,7 +44,7 @@ void loki_worker_t::parse_locations(google::protobuf::RepeatedPtrField<valhalla:
else if (location.radius() > max_radius)
location.set_radius(max_radius);

if (!location.has_heading_tolerance_case())
if (location.has_heading_tolerance_case())
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure I follow this. We're now overriding heading_tolerance_case even if it explicitly set?

Copy link
Member Author

Choose a reason for hiding this comment

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

i do not know how that got in here, i didnt even change heading tolarance in the proto. ill add a unit test because obviously this isnt protected by existing tests

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@@ -445,9 +443,9 @@ void CopyLocations(TripLeg& trip_path,
valhalla::Location* tp_intermediate = trip_path.add_location();
tp_intermediate->CopyFrom(intermediate);
// we can grab the right edge index in the path because we temporarily set it for trimming
if (!intermediate.correlation().has_leg_shape_index_case()) {
/*if (!intermediate.correlation().has_leg_shape_index_case()) {
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 leave this commented?

Copy link
Member Author

Choose a reason for hiding this comment

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

this was basically an assertion, i think ill add a different check that every index is larger than the next or something so at least a check still exists.

Copy link
Member Author

Choose a reason for hiding this comment

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

done

mandeepsandhu
mandeepsandhu previously approved these changes Feb 11, 2022
Copy link
Contributor

@mandeepsandhu mandeepsandhu left a comment

Choose a reason for hiding this comment

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

had a few clarifying question. rest lgtm. Thx for heavy lifting! 🙂

Copy link
Contributor

@mandeepsandhu mandeepsandhu left a comment

Choose a reason for hiding this comment

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

Thx for adding new tests. lgtm

@kevinkreiser kevinkreiser merged commit b821ce2 into master Feb 14, 2022
@kevinkreiser kevinkreiser deleted the kk_less_oneof branch February 14, 2022 02:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants