-
Notifications
You must be signed in to change notification settings - Fork 710
iobuf: fix operator<=> and operator== for string_view comparisons #29461
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
base: dev
Are you sure you want to change the base?
Conversation
The previous implementation had inverted stop_iteration logic - it stopped when the comparison was equal and continued when not equal, causing incorrect results when the first fragment comparison determined the ordering. Replaced iterator_consumer pattern with a simpler for-each loop over fragments. Added comprehensive tests covering multi-fragment comparisons. Benchmark results (instructions, runtime): - sv_cmp_0000: 49 -> 36 inst (-27%), 2.28ns -> 2.16ns (-5%) - sv_cmp_0001: 87 -> 64 inst (-26%), 3.61ns -> 3.17ns (-12%) - sv_cmp_1024 (different): 121 -> 60 inst (-50%), 4.98ns -> 3.44ns (-31%) - sv_cmp_1024 (same): 256 -> 214 inst (-16%), 10.37ns -> 9.41ns (-9%) Runtime improvements are consistent with instruction count reductions.
Simplify operator== by delegating to the fixed operator<=> implementation. This reduces code duplication and ensures consistent comparison behavior. Benchmark results (instructions, runtime): - sv_eq_0000: 38 -> 30 inst (-21%), 2.30ns -> 1.95ns (-15%) - sv_eq_0001: 83 -> 58 inst (-30%), 3.61ns -> 2.96ns (-18%) - sv_eq_1024 (different): 80 -> 57 inst (-29%), 3.70ns -> 3.25ns (-12%) - sv_eq_1024 (same): 247 -> 209 inst (-15%), 10.50ns -> 9.46ns (-10%) Runtime improvements are consistent with instruction count reductions.
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.
Pull request overview
This PR fixes a bug in iobuf::operator<=>(string_view) where inverted stop iteration logic caused incorrect comparison results for multi-fragment iobufs. The fix simplifies the implementation to use a clearer loop-based approach and delegates operator== to the corrected spaceship operator for consistency.
Changes:
- Fixed
operator<=>logic by replacing the iterator_consumer pattern with a simpler fragment-by-fragment loop - Simplified
operator==to delegate to the fixedoperator<=> - Added comprehensive unit tests for multi-fragment iobuf comparisons with string_view
- Added benchmarks to measure performance of iobuf vs string_view comparisons
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/v/bytes/iobuf.cc | Fixed operator<=> implementation and simplified operator== to use the corrected spaceship operator |
| src/v/bytes/tests/iobuf_tests.cc | Added unit tests for multi-fragment iobuf spaceship operator comparisons with string_view |
| src/v/bytes/tests/iobuf_bench.cc | Added benchmarks for iobuf vs string_view equality and comparison operations |
|
@rockwotj - not sure about backport here, I think you added the initial (maybe only) use case? |
|
Needs a backport to 25.3.x |
rockwotj
left a comment
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.
very embarrassing there are so many bugs here, need some more fuzzing here
This bug was actually turned up by fuzzing, as I had added more coverage to the fuzzer. That's in another PR. |
Retry command for Build#79846please wait until all jobs are finished before running the slash command |
CI test resultstest results on build#79846test results on build#79865
|
|
/ci-repeat 1 |
src/v/bytes/tests/iobuf_tests.cc
Outdated
| buf2.append_fragments(iobuf::from("a")); | ||
| buf2.append_fragments(iobuf::from("b")); | ||
| buf2.append_fragments(iobuf::from("c")); | ||
| // buf2 = "abc" |
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.
remove or reword what it's trying to say? Should it be ==?
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.
Well I guess it's like "this is the equivalent assignment" rather than an assertion, but regardless removed.
src/v/bytes/iobuf.cc
Outdated
| return !are_equal ? ss::stop_iteration::yes : ss::stop_iteration::no; | ||
| }); | ||
| return are_equal; | ||
| return _size == o.size() && (*this <=> o) == std::strong_ordering::equal; |
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.
Other method calls size_bytes(). Shoudl this too?
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.
Yes, better to use the method, fixed.
75f1508
722dc19 to
75f1508
Compare
Add sv_eq_* and sv_cmp_* benchmark cases to measure performance of iobuf::operator== and operator<=> against string_view. Uses a templated cmp_bench function with rhs_type parameter to support both iobuf-vs-iobuf and iobuf-vs-string_view comparisons. Tests both single-fragment and fragmented iobufs at sizes 0, 1, 1024.
75f1508 to
5752502
Compare
Summary
iobuf::operator<=>(string_view)where inverted stop_iteration logic caused incorrect results for multi-fragment iobufsiobuf::operator==(string_view)to delegate to the fixedoperator<=>Benchmark results
operator<=>:
operator==:
Test plan
Backports Required
Release Notes