Repository navigation
ORC-1170:[C++] Optimize the RowReader::seekToRow function in the case of seeking within the same stripe - #1114
coderex2522 wants to merge 5 commits into
Conversation
dongjoon-hyun
left a comment
There was a problem hiding this comment.
Thank you for making a PR, @coderex2522 .
| const T& operator[](uint64_t i) const { | ||
| return buf[i]; | ||
| } | ||
|
|
There was a problem hiding this comment.
Does this part have a big impact?
There was a problem hiding this comment.
The DataBuffer class already has a non-const operator() function, so adding a const operator() function should have no effect.
There was a problem hiding this comment.
suggest to use the trick to remove duplicates between const and non-const overloads: https://stackoverflow.com/questions/123758/how-do-i-remove-code-duplication-between-similar-const-and-non-const-member-func
There was a problem hiding this comment.
There was a problem hiding this comment.
Thanks. Could you share your environment information and the numbers with the above, @coderex2522 ?
There was a problem hiding this comment.
Test Environment: x86_64, gcc version 4.8.5
The test results were 7.03 seconds and 3.82 seconds respectively. @dongjoon-hyun
There was a problem hiding this comment.
Which OS are you on? The build chain looks a little old to me. I expected 9.4.0 or 11.2.0.
There was a problem hiding this comment.
I retested it with gcc 9.2.1 and the results were similar. And both tests were on Linux OS x86_64.
| friend class TestRowReader_advanceToNextRowGroup_Test; | ||
| friend class TestRowReader_computeBatchSize_Test; | ||
|
|
||
| inline uint64_t lastRowOfCurrentStripe() const { |
There was a problem hiding this comment.
Please add a function description comment.
There was a problem hiding this comment.
Do we use this somewhere?
There was a problem hiding this comment.
The function has remove.
stiga-huang
left a comment
There was a problem hiding this comment.
LGTM. It'd be nice if we can have a more specifit commit tittle. We are optimzing the case seeking within the same stripe. Seeking within the same RowGroup is not optimized in this PR. So having a title like "ORC-1170:[C++] Optimize seeking within the same stripe" seems better to me.
| friend class TestRowReader_advanceToNextRowGroup_Test; | ||
| friend class TestRowReader_computeBatchSize_Test; | ||
|
|
||
| inline uint64_t lastRowOfCurrentStripe() const { |
There was a problem hiding this comment.
Do we use this somewhere?
I think seeking within the same stripe is inclusive of seeking withing the same RowGroup. Seeking withing the same RowGroup will also call function startNextStripe under the original implementation. |
| if (rowIndexes.empty()) { | ||
| loadStripeIndex(); | ||
| } | ||
| seekToRowGroup(static_cast<uint32_t>(rowsToSkip / rowIndexStride)); |
There was a problem hiding this comment.
If somehow it fails to parse the row index or finds some missing columns in the call of loadStripeIndex(), the seekToRowGroup here cannot proceed. Maybe add a TODO here to mark a future improvement.
There was a problem hiding this comment.
nit.
For TODO comment, an IDed TODO style is recommended in order not to forget about it.
It means to file an official ORC JIRA and use TODO(ORC-XXX) style.
There was a problem hiding this comment.
Improved the todo comment, thanks!
| uint64_t firstStripe; | ||
| uint64_t currentStripe; | ||
| uint64_t lastStripe; // the stripe AFTER the last one | ||
| uint64_t currentInitedStripe; |
There was a problem hiding this comment.
The naming is a little bit casual, maybe processingStripe?
|
Although I set the milestone for Apache ORC 1.9.0, please feel free to backport this if you want in Apache ORC 1.8.0, @wgtmac and @stiga-huang . |
dongjoon-hyun
left a comment
There was a problem hiding this comment.
+1, LGTM, too. Thank you, @coderex2522 , @stiga-huang , @wgtmac .
Merged to master.
|
This is merged via 11a2544 |
…#70079) ### What problem does this PR solve? Related PR: apache/doris-thirdparty#431 (merge the ORC dependency fix first) A condition-cache granule can start in a stripe's SARG-filtered suffix while containing a matching row in the next stripe. On an initialized stripe, ORC's `seekToRow()` uses the stripe-end sentinel as a row-group index. This can access past the index when the stripe ends on an index boundary, or prematurely return EOF when the last row group is partial. The same-stripe fast path originates in [Apache ORC ORC-1170](apache/orc#1114); the same missing stripe-end handling remains in the current upstream C++ reader. Pin the ORC fix that initializes the next selected stripe before positioning its column readers. Preserve SARG pruning, lazy reads and split boundaries. Add a Doris reader regression and a 1.5 KB synthetic ORC fixture with its generator. The fixture has two 20,000-row stripes, a 10,000-row index stride, and one matching row at the start of each stripe. A cache hit seeks to row 18,432 in the first stripe's filtered suffix. The SQL regression compares cache-disabled and cached results with lazy reads and min/max pruning enabled or disabled, and checks the profile for actual cache hits and skipped rows. ### Release note Fix potential crashes and missing rows when ORC condition-cache seeks reach a SARG-filtered stripe suffix. ### Check List (For Author) - Test: - [x] Unit Test: 247 ORC-related BE tests passed under AddressSanitizer, including the new Doris condition-cache case and 32 dependency boundary cases. - [x] Unit Test: 56 focused standalone ORC tests passed under AddressSanitizer. Reverting the fix makes all 16 initialized-stripe boundary cases fail. - [ ] Regression test: SQL suite added; Groovy compilation checked. The external SQL suite has not been executed locally. - [x] clang-format 16 and BE build-hygiene checks passed. - [ ] Local full-file clang-tidy analysis did not complete within ten minutes; no completed result is available. - Behavior changed: - [x] Yes. Safely advance to the next matching stripe or EOF. - Does this need documentation? - [x] No.

What changes were proposed in this pull request?
The patch will optimize the seekToRow function. The RowReader::seekToRow() function always call startNextStripe() to seek to the beginning of target stripe. However, when PPD is enabled many calls are still staying in the same stripe which results in many unnecessary calls.
Why are the changes needed?
This PR improves the seekToRow function call. I pick a 259MB file of the TPCH lineitem table which contains 7200030
records. I use a modified orc-scan tool that calls the RowReader::seekToRow function once before each call the RowReader:: next() function to test this patch. The results are shown below:
How was this patch tested?
The original UTs(TestPredicatePushdown, DictionaryEncoding::multipleStripesWithIndex, DictionaryEncoding::multipleStripesWithoutIndex) will cover this patch.