| 534 | } |
| 535 | |
| 536 | Status TopNNode::EvictPartitions(RuntimeState* state, bool evict_final) { |
| 537 | DCHECK(is_partitioned()); |
| 538 | vector<unique_ptr<Heap>> heaps_to_evict; |
| 539 | if (evict_final) { |
| 540 | // Move all the partitions to 'sorter_' in preparation for the final sort. Partitions |
| 541 | // are evicted in the order of the partition key to reduce the amount of shuffling |
| 542 | // that the final sort will do to rearrange partitions. |
| 543 | for (auto& entry : partition_heaps_) { |
| 544 | heaps_to_evict.push_back(move(entry.second)); |
| 545 | } |
| 546 | partition_heaps_.clear(); |
| 547 | } else { |
| 548 | heaps_to_evict = SelectPartitionsToEvict(); |
| 549 | } |
| 550 | // Only count heap eviction if they are as a result of memory pressure. |
| 551 | if (!evict_final) COUNTER_ADD(in_mem_heap_evicted_counter_, heaps_to_evict.size()); |
| 552 | |
| 553 | RowBatch batch(row_desc(), state->batch_size(), mem_tracker()); |
| 554 | for (auto& heap : heaps_to_evict) { |
| 555 | DCHECK(heap->DCheckConsistency()); |
| 556 | // Extract partition entries from the heap in sorted order to reduce amount of sorting |
| 557 | // required in final sort. This sorting is not required for correctness since |
| 558 | // 'sorter_' will do a full sort later. |
| 559 | heap->PrepareForOutput(*this, &sorted_top_n_); |
| 560 | for (int64_t i = 0; i < sorted_top_n_.size(); ++i) { |
| 561 | TupleRow* row = batch.GetRow(batch.AddRow()); |
| 562 | row->SetTuple(0, sorted_top_n_[i]); |
| 563 | batch.CommitLastRow(); |
| 564 | if (batch.AtCapacity() || i == sorted_top_n_.size() - 1) { |
| 565 | RETURN_IF_ERROR(sorter_->AddBatch(&batch)); |
| 566 | batch.Reset(); |
| 567 | } |
| 568 | } |
| 569 | sorted_top_n_.clear(); |
| 570 | } |
| 571 | heaps_to_evict.clear(); |
| 572 | |
| 573 | // ReclaimTuplePool() can now reclaim memory that is not used by in-memory partitions. |
| 574 | RETURN_IF_ERROR(ReclaimTuplePool(state)); |
| 575 | return Status::OK(); |
| 576 | } |
| 577 | |
| 578 | vector<unique_ptr<TopNNode::Heap>> TopNNode::SelectPartitionsToEvict() { |
| 579 | // Evict a subset of heaps to free enough memory to continue. |
nothing calls this directly
no test coverage detected