Skip to content

Remove HeaderString::c_str() and migrate callers to getStringView()#6564

Merged
lizan merged 10 commits intoenvoyproxy:masterfrom
dnoe:no_c_str_by_the_c_shore
Apr 16, 2019
Merged

Remove HeaderString::c_str() and migrate callers to getStringView()#6564
lizan merged 10 commits intoenvoyproxy:masterfrom
dnoe:no_c_str_by_the_c_shore

Conversation

@dnoe
Copy link
Contributor

@dnoe dnoe commented Apr 12, 2019

Remove the HeaderString::c_str() API, and migrate all callers of it to getStringView() and string_view style usage (ie, absl::string_view::find instead of C style comparisons) wherever appropriate.

Risk Level: Medium. No logic changes intended, but this is delicate and risky code and a large portion of the code base was touched.
Testing: bazel test //test/...
Docs Changes: None
Release Notes: None
Fixes #6494

dnoe added 2 commits April 11, 2019 18:21
Signed-off-by: Dan Noé <dpn@google.com>
Signed-off-by: Dan Noé <dpn@google.com>
@dnoe dnoe requested review from lizan, snowp and zuercher as code owners April 12, 2019 13:22
This doesn't work, of course.

Signed-off-by: Dan Noé <dpn@google.com>
@dnoe
Copy link
Contributor Author

dnoe commented Apr 12, 2019

The old code in the section that failed to build in release and coverage builds is this:

    const std::string& request_override_host =
        downstream_headers->get(Http::Headers::get().EnvoyOriginalDstHost)->value().c_str();

I'll admit to being a little confused about what it means to assign a const char* to a const std::string&. I suppose there's some magic happening under the hood where implicit construction of an rvalue std::string is happening and then the reference is bound to it?

It's also unclear why the other configurations didn't fail to build.

@mattklein123 mattklein123 self-assigned this Apr 12, 2019
@snowp
Copy link
Contributor

snowp commented Apr 12, 2019

@dnoe Yeah it'll create a temporary and its lifetime is extended (https://abseil.io/tips/107)

dnoe added 2 commits April 12, 2019 12:41
Signed-off-by: Dan Noé <dpn@google.com>
Now that we use string_view, we can use range-based-for and make the
loop more readable.

Signed-off-by: Dan Noé <dpn@google.com>
@lambdai
Copy link
Contributor

lambdai commented Apr 12, 2019

Looks great!

Copy link
Member

@lizan lizan left a comment

Choose a reason for hiding this comment

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

Great, I only reviewed until source/common though.

grpc_status->value().getStringView()))
.inc();
uint64_t grpc_status_code;
std::string grpc_status_string(grpc_status->value().getStringView());
Copy link
Member

Choose a reason for hiding this comment

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

consider use absl::SimpleAtoi instead of atoull (or implement StringUtil::atoull with absl::SimpleAtoi) so we can avoid this string allocation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great idea - I will create an issue to follow up by either implementing StringUtil::atoull with absl::SimpleAtoi or converting call sites. I think there was only one spot in the code I found where the return value of StringUtil::atoull (which is C-style) was used.

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Thanks this is absolutely awesome. Huge props for slogging through this and I love seeing the tech debt disappear.

I mainly have comments around adding TODOs for all the other places we can get rid of string copies. We have the opportunity here to speed things up in a non-trivial way as part of these changes which is great.

/wait

grpc_status->value().getStringView()))
.inc();
uint64_t grpc_status_code;
std::string grpc_status_string(grpc_status->value().getStringView());
Copy link
Member

Choose a reason for hiding this comment

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

nit: const here and elsewhere.

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, though my eyes glaze over reading this diff so please let me know if I missed another :)

}

bool match;
absl::string_view header_view = header->value().getStringView();
Copy link
Member

Choose a reason for hiding this comment

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

Do we have to make this copy? If so can we TODO removing it?

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 one is just for readability reasons since it gets pretty busy seeing header->value().getStringView() repeated especially when std::regex_match takes begin() and end(). The copy of a string_view should be only slightly worse than a pointer. I've marked it as const, which may prevent the copy entirely.

I'm happy to remove it too if you'd like, but I think it makes this much more readable rather than repeating the header->value().getStringView().

@@ -66,7 +66,7 @@ Decision HttpTracerUtility::isTracing(const StreamInfo::StreamInfo& stream_info,

// TODO PERF: Avoid copy.
Copy link
Member

Choose a reason for hiding this comment

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

I think you fixed this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indeed I did now that isTraceableUuid takes string_view rather than std::string. Removing the comment, taking the credit (I don't see an existing issue for this, if there is feel free to close it).

Signed-off-by: Dan Noé <dpn@google.com>
@dnoe
Copy link
Contributor Author

dnoe commented Apr 15, 2019

I think everything should be resolved. Follow ups are tracked at #6580 and #6581

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Nice this is so awesome. Looking forward to the followup cleanups. A few more comments from another pass. Thank you!

/wait

Use lua_pushlstring to avoid std::string construction.

Signed-off-by: Dan Noé <dpn@google.com>
mattklein123
mattklein123 previously approved these changes Apr 15, 2019
Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Nice! @lizan do you want to do any additional review?

Signed-off-by: Dan Noé <dpn@google.com>
@dnoe dnoe requested a review from lizan April 16, 2019 13:07
@dnoe dnoe requested a review from mattklein123 April 16, 2019 13:07
mattklein123
mattklein123 previously approved these changes Apr 16, 2019
lizan
lizan previously approved these changes Apr 16, 2019
Copy link
Member

@lizan lizan left a comment

Choose a reason for hiding this comment

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

@dnoe can you merge master again?

…c_str_by_the_c_shore

Signed-off-by: Dan Noe <dpn@google.com>
@dnoe dnoe dismissed stale reviews from lizan and mattklein123 via 2cdc003 April 16, 2019 16:15
@dnoe
Copy link
Contributor Author

dnoe commented Apr 16, 2019

Master merge conflicts addressed.

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.

Remove HeaderMap uses of c_str

5 participants