-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
filter chain: prefer vector over list for filter chain #37665
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: wangbaiping(wbpcode) <[email protected]>
Signed-off-by: wangbaiping(wbpcode) <[email protected]>
This is why I created PRs to unify the creation downstream and upstream filter chains. All for this PR. |
hi, @adisuissa , could you take a look at this also if you get some free time? I think you also did some similar work. Thanks. |
source/common/http/filter_manager.cc
Outdated
@@ -919,7 +936,7 @@ FilterManager::commonEncodePrefix(ActiveStreamEncoderFilter* filter, bool end_st | |||
state_.decoder_filter_chain_aborted_ = true; | |||
} | |||
} | |||
return encoder_filters_.begin(); | |||
return encoder_filters_.rbegin(); |
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 are we changing these to reverse iterators?
/wait-any
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.
See, the original container of filter chain is list. When a new filter is added, it will be inserted to the begin of the encoder_filters_
to ensure the first added filter will be called at last for encoding path.
And now, we changed the container to vector and the filter will always be appended to the end of the vector. So, we use the reverse iterator to ensure the previous behavior will not be effected.
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.
ah yep, I missed that we inserted in order before and now we don't. IMO it's worth C++ comments either where the vectors are defined or where we get iterators to call out that's what's going on
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 think it is commented at the function where the filter is inserted to the container. I will add some more details at there.
source/common/http/filter_manager.cc
Outdated
@@ -42,12 +37,36 @@ void recordLatestDataFilter(const typename FilterList<T>::iterator current_filte | |||
// correctly iterate over the filters and set latest, but on subsequent onData iterations | |||
// we'd start from the beginning again, potentially allowing filter N to modify the buffer even | |||
// though filter M > N was the filter that inserted data into the buffer. | |||
if (current_filter != filters.begin() && latest_filter == std::prev(current_filter)->get()) { | |||
latest_filter = current_filter->get(); | |||
if (std::distance(decoder_filters_.begin(), current_filter->entry()) > |
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.
ok sorry I feel like I'm live blogging comments but did we need to rewrite this? we've still got iterators so I'd think it would be ok and I find prior syntax easier to read.
/wait-any
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 will check this tomorrow to see if it's necessary. I think I rewrite it mainly because I don't want to use a reference to raw pointer. &*
source/common/http/filter_manager.cc
Outdated
@@ -919,7 +936,7 @@ FilterManager::commonEncodePrefix(ActiveStreamEncoderFilter* filter, bool end_st | |||
state_.decoder_filter_chain_aborted_ = true; | |||
} | |||
} | |||
return encoder_filters_.begin(); | |||
return encoder_filters_.rbegin(); |
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.
ah yep, I missed that we inserted in order before and now we don't. IMO it's worth C++ comments either where the vectors are defined or where we get iterators to call out that's what's going on
…ector-filter-chain
Signed-off-by: wangbaiping(wbpcode) <[email protected]>
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.
Thanks! I think it makes sense to use a vector instead of a list, as filters aren't removed from the middle of the chain.
One high-level comment about the iteration order:
My personal preference is to have non-simple iterators (those that are changed and picked up in multiple places) use the simple begin()->end() forward iteration. IMHO it makes the code more readable, and one less thing to worry about when this code is modified. From big-O notation reversing the container first should also be an O(N).
Another option is to abstract over the iterators, so it will always look like this is a forward iterator, and the underlying abstraction will take care of the iteration direction.
source/common/http/filter_manager.cc
Outdated
template <class T> | ||
void recordLatestDataFilter(const typename FilterList<T>::iterator current_filter, | ||
T*& latest_filter, const FilterList<T>& filters) { | ||
template <class Iterator, class Filter> |
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.
Seems that the function's code requires a strict relationship between the types of Iterator and Filter. Can this be rewritten with a single template type?
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.
sgtm.
Thanks for this comment. It's pretty easy to reverse the vector first because the unique pointer is used. The reason I use the
This sound reasonable to me. |
Signed-off-by: wangbaiping(wbpcode) <[email protected]>
Signed-off-by: wangbaiping(wbpcode) <[email protected]>
cc @adisuissa is this what you want? Now, even the PR self is more cleaner. |
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.
Thanks, looks better IMHO.
Left a request for adding comments but otherwise LGTM.
source/common/http/filter_manager.h
Outdated
Iterator begin() { return entries.begin(); } | ||
Iterator end() { return entries.end(); } | ||
|
||
std::vector<ActiveStreamDecoderFilterPtr> entries; |
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.
not sure if the style guide states that it needs to end with _ or not.
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.
it should be added according to our style. added it.
Signed-off-by: wangbaiping(wbpcode) <[email protected]>
I did nothing to quic.
Let'me merge main and try again. |
…ector-filter-chain
retest |
/retest |
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.
much more comfortable with this version, thanks for the update. LGTM modulo two little comment nits
/wait
That's why need code review! 😄 |
Signed-off-by: wangbaiping(wbpcode) <[email protected]>
…ector-filter-chain
Commit Message: filter chain: prefer vector over list for filter chain
Additional Description:
Use vector to store the filter chain rather than list. Note, we never require to insert/remove element in the intermediate node of filter chain container. In this scenario, vector is much more memory-friend than list.
Risk Level: mid.
Testing: n/a.
Docs Changes: n/a.
Release Notes: n/a.
Platform Specific Features: n/a.