| 409 | } |
| 410 | |
| 411 | void RowReaderImpl::seekToRow(uint64_t rowNumber) { |
| 412 | // Empty file |
| 413 | if (lastStripe_ == 0) { |
| 414 | return; |
| 415 | } |
| 416 | |
| 417 | // If we are reading only a portion of the file |
| 418 | // (bounded by firstStripe and lastStripe), |
| 419 | // seeking before or after the portion of interest should return no data. |
| 420 | // Implement this by setting previousRow to the number of rows in the file. |
| 421 | |
| 422 | // seeking past lastStripe |
| 423 | uint64_t num_stripes = static_cast<uint64_t>(footer_->stripes_size()); |
| 424 | if ((lastStripe_ == num_stripes && rowNumber >= footer_->number_of_rows()) || |
| 425 | (lastStripe_ < num_stripes && rowNumber >= firstRowOfStripe_[lastStripe_])) { |
| 426 | currentStripe_ = num_stripes; |
| 427 | previousRow_ = footer_->number_of_rows(); |
| 428 | return; |
| 429 | } |
| 430 | |
| 431 | uint64_t seekToStripe = 0; |
| 432 | while (seekToStripe + 1 < lastStripe_ && firstRowOfStripe_[seekToStripe + 1] <= rowNumber) { |
| 433 | seekToStripe++; |
| 434 | } |
| 435 | |
| 436 | // seeking before the first stripe |
| 437 | if (seekToStripe < firstStripe_) { |
| 438 | currentStripe_ = num_stripes; |
| 439 | previousRow_ = footer_->number_of_rows(); |
| 440 | return; |
| 441 | } |
| 442 | |
| 443 | previousRow_ = rowNumber; |
| 444 | auto rowIndexStride = footer_->row_index_stride(); |
| 445 | if (!isCurrentStripeInited() || currentStripe_ != seekToStripe || rowIndexStride == 0 || |
| 446 | currentStripeInfo_.index_length() == 0) { |
| 447 | // current stripe is not initialized or |
| 448 | // target stripe is not current stripe or |
| 449 | // current stripe doesn't have row indexes |
| 450 | currentStripe_ = seekToStripe; |
| 451 | currentRowInStripe_ = rowNumber - firstRowOfStripe_[currentStripe_]; |
| 452 | startNextStripe(); |
| 453 | if (currentStripe_ >= lastStripe_) { |
| 454 | return; |
| 455 | } |
| 456 | } else { |
| 457 | currentRowInStripe_ = rowNumber - firstRowOfStripe_[currentStripe_]; |
| 458 | if (sargsApplier_) { |
| 459 | // advance to selected row group if predicate pushdown is enabled |
| 460 | currentRowInStripe_ = |
| 461 | advanceToNextRowGroup(currentRowInStripe_, rowsInCurrentStripe_, |
| 462 | footer_->row_index_stride(), sargsApplier_->getNextSkippedRows()); |
| 463 | } |
| 464 | } |
| 465 | |
| 466 | uint64_t rowsToSkip = currentRowInStripe_; |
| 467 | // seek to the target row group if row indexes exists |
| 468 | if (rowIndexStride > 0 && currentStripeInfo_.index_length() > 0) { |