| 590 | } |
| 591 | |
| 592 | Status SubarrayPartitioner::split_current(bool* unsplittable) { |
| 593 | auto timer_se = stats_->start_timer("read_split_current_partition"); |
| 594 | |
| 595 | *unsplittable = false; |
| 596 | |
| 597 | // Current came from splitting a multi-range partition |
| 598 | if (current_.split_multi_range_) { |
| 599 | if (state_.multi_range_.empty()) |
| 600 | state_.start_ = current_.start_; |
| 601 | state_.multi_range_.push_front(current_.partition_); |
| 602 | throw_if_not_ok(split_top_multi_range(unsplittable)); |
| 603 | return next_from_multi_range(unsplittable); |
| 604 | } |
| 605 | |
| 606 | // Current came from retrieving a multi-range partition from subarray |
| 607 | if (current_.start_ < current_.end_) { |
| 608 | auto range_num = (current_.end_ - current_.start_ + 1); |
| 609 | iassert(1 - constants::multi_range_reduction_in_split <= 1); |
| 610 | auto new_range_num = |
| 611 | range_num * (1 - constants::multi_range_reduction_in_split); |
| 612 | current_.end_ = current_.start_ + (uint64_t)new_range_num - 1; |
| 613 | |
| 614 | bool must_split_slab; |
| 615 | RETURN_NOT_OK(calibrate_current_start_end(&must_split_slab)); |
| 616 | |
| 617 | // If the range between `current_.start_` and `current_.end_` |
| 618 | // will not fit within the memory contraints, `must_split_slab` |
| 619 | // will be true. We must split the current partition. |
| 620 | // |
| 621 | // This is a difficult path to reach, but this has been manually |
| 622 | // tested. This path was reached by re-assigning the query |
| 623 | // buffers with smaller buffers after an incomplete read. |
| 624 | if (must_split_slab) { |
| 625 | if (state_.multi_range_.empty()) |
| 626 | state_.start_ = current_.start_; |
| 627 | state_.multi_range_.push_front(current_.partition_); |
| 628 | throw_if_not_ok(split_top_multi_range(unsplittable)); |
| 629 | return next_from_multi_range(unsplittable); |
| 630 | } |
| 631 | |
| 632 | current_.partition_ = |
| 633 | subarray_.get_subarray(current_.start_, current_.end_); |
| 634 | state_.start_ = current_.end_ + 1; |
| 635 | |
| 636 | return Status::Ok(); |
| 637 | } |
| 638 | |
| 639 | // Current came from splitting a single-range partition |
| 640 | if (state_.single_range_.empty()) |
| 641 | state_.start_--; |
| 642 | state_.single_range_.push_front(current_.partition_); |
| 643 | throw_if_not_ok(split_top_single_range(unsplittable)); |
| 644 | return next_from_single_range(unsplittable); |
| 645 | } |
| 646 | |
| 647 | const SubarrayPartitioner::State* SubarrayPartitioner::state() const { |
| 648 | return &state_; |
nothing calls this directly
no test coverage detected