| 67 | } |
| 68 | |
| 69 | Status SpillableRowBatchQueue::AddBatch(RowBatch* batch) { |
| 70 | DCHECK(!IsFull()) << "Cannot AddBatch on a full SpillableRowBatchQueue"; |
| 71 | DCHECK(!closed_) << "Cannot AddBatch on a closed SpillableRowBatchQueue"; |
| 72 | Status status; |
| 73 | FOREACH_ROW(batch, 0, batch_itr) { |
| 74 | // AddRow should only return false if there was not enough unused reservation to |
| 75 | // allocate a page for the given row. If a row cannot be added to the batch_queue_ |
| 76 | // then start spilling to disk by unpining the stream. Once the stream is unpinned, |
| 77 | // adding the row to the stream should succeed unless the unpinned pages needed to |
| 78 | // be spilled and either (1) there was an error (e.g. IO error) when writing to disk, |
| 79 | // (2) there is no more scratch space left to write to disk, or (3) spilling to disk |
| 80 | // is disabled. |
| 81 | if (UNLIKELY(!batch_queue_->AddRow(batch_itr.Get(), &status))) { |
| 82 | RETURN_IF_ERROR(status); |
| 83 | // StartSpilling checks if spilling is disabled and returns an error if it is not. |
| 84 | RETURN_IF_ERROR(state_->StartSpilling(mem_tracker_)); |
| 85 | |
| 86 | // The pin should be stream at this point. |
| 87 | DCHECK(batch_queue_->is_pinned()); |
| 88 | DCHECK_EQ(batch_queue_->bytes_unpinned(), 0); |
| 89 | |
| 90 | // Unpin the stream and then add the row. |
| 91 | RETURN_IF_ERROR( |
| 92 | batch_queue_->UnpinStream(BufferedTupleStream::UNPIN_ALL_EXCEPT_CURRENT)); |
| 93 | |
| 94 | // Append "Spilled" to the "ExecOption" info string in the runtime profile. |
| 95 | profile_->AppendExecOption("Spilled"); |
| 96 | |
| 97 | if (!batch_queue_->AddRow(batch_itr.Get(), &status)) { |
| 98 | RETURN_IF_ERROR(status); |
| 99 | // If the row could not be added after the stream was unpinned, an error should |
| 100 | // have been set. |
| 101 | DCHECK(false) << Substitute("Row with a size of $0 should be added successfully " |
| 102 | "in unpinned mode unless an error occurred. " |
| 103 | "batch_queue_: $1", |
| 104 | PrettyPrinter::PrintBytes( |
| 105 | batch_queue_->ComputeRowSize(batch_itr.Get())), |
| 106 | batch_queue_->DebugString()); |
| 107 | } |
| 108 | } |
| 109 | } |
| 110 | return Status::OK(); |
| 111 | } |
| 112 | |
| 113 | Status SpillableRowBatchQueue::GetBatch(RowBatch* batch) { |
| 114 | DCHECK(!IsEmpty()) << "Cannot GetBatch on an empty SpillableRowBatchQueue"; |
nothing calls this directly
no test coverage detected