iobuf: fix operator<=> and operator== for string_view comparisons#29461
iobuf: fix operator<=> and operator== for string_view comparisons#29461travisdowns merged 3 commits intodevfrom
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.
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.
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.
remove or reword what it's trying to say? Should it be ==?
There was a problem hiding this comment.
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.
Other method calls size_bytes(). Shoudl this too?
There was a problem hiding this comment.
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
|
/backport v25.3.x |
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