| 210 | } |
| 211 | |
| 212 | Status GroupingAggregator::Open(RuntimeState* state) { |
| 213 | RETURN_IF_ERROR(Aggregator::Open(state)); |
| 214 | |
| 215 | // Claim reservation after the child has been opened to reduce the peak reservation |
| 216 | // requirement. |
| 217 | if (!buffer_pool_client()->is_registered()) { |
| 218 | DCHECK_GE(resource_profile_.min_reservation, MinReservation()); |
| 219 | RETURN_IF_ERROR(reservation_manager_.ClaimBufferReservation(state)); |
| 220 | } |
| 221 | |
| 222 | // Init the SubReservations for non-streaming instances. Open() may be called many times |
| 223 | // if this is in a subplan. Only init them once. |
| 224 | if (!is_streaming_preagg_ && large_write_page_reservation_.is_closed()) { |
| 225 | DCHECK(large_read_page_reservation_.is_closed()); |
| 226 | large_write_page_reservation_.Init(buffer_pool_client()); |
| 227 | large_read_page_reservation_.Init(buffer_pool_client()); |
| 228 | // The min reservation only guarantees reading one large page and writing one large |
| 229 | // page at the same time. Save the extra reservation so we can restore them when we |
| 230 | // actually need them, to avoid accidentally occupy them for other purposes. |
| 231 | int64_t extra_reservation = resource_profile_.max_row_buffer_size |
| 232 | - resource_profile_.spillable_buffer_size; |
| 233 | if (extra_reservation > 0) { |
| 234 | DCHECK_GT(buffer_pool_client()->GetUnusedReservation(), extra_reservation * 2) |
| 235 | << buffer_pool_client()->DebugString() << "\n" << resource_profile_; |
| 236 | SaveLargeReadPageReservation(); |
| 237 | SaveLargeWritePageReservation(); |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | DCHECK(ht_ctx_.get() != nullptr); |
| 242 | RETURN_IF_ERROR(ht_ctx_->Open(state)); |
| 243 | |
| 244 | if (ht_allocator_ == nullptr) { |
| 245 | // Allocate 'serialize_stream_' and 'ht_allocator_' on the first Open() call. |
| 246 | ht_allocator_.reset(new Suballocator(ExecEnv::GetInstance()->buffer_pool(), |
| 247 | buffer_pool_client(), resource_profile_.spillable_buffer_size)); |
| 248 | |
| 249 | if (!is_streaming_preagg_ && needs_serialize_) { |
| 250 | serialize_stream_.reset(new BufferedTupleStream(state, &intermediate_row_desc_, |
| 251 | buffer_pool_client(), resource_profile_.spillable_buffer_size, |
| 252 | resource_profile_.max_row_buffer_size)); |
| 253 | RETURN_IF_ERROR(serialize_stream_->Init(exec_node_->label(), false)); |
| 254 | bool got_buffer; |
| 255 | // Reserve the memory for 'serialize_stream_' so we don't need to scrounge up |
| 256 | // another buffer during spilling. |
| 257 | RETURN_IF_ERROR(serialize_stream_->PrepareForWrite(&got_buffer)); |
| 258 | DCHECK(got_buffer) << "Accounted in min reservation" |
| 259 | << buffer_pool_client()->DebugString(); |
| 260 | DCHECK(serialize_stream_->has_write_iterator()); |
| 261 | } |
| 262 | } |
| 263 | RETURN_IF_ERROR(CreateHashPartitions(0)); |
| 264 | return Status::OK(); |
| 265 | } |
| 266 | |
| 267 | Status GroupingAggregator::GetNext(RuntimeState* state, RowBatch* row_batch, bool* eos) { |
| 268 | RETURN_IF_ERROR(QueryMaintenance(state)); |
nothing calls this directly
no test coverage detected