| 1286 | } |
| 1287 | |
| 1288 | uint64_t HashBuild::probeAdmissionExtraReservationBytes( |
| 1289 | uint64_t numRows) const { |
| 1290 | const bool notReadyForProbeAdmission = |
| 1291 | !operatorCtx_->driverCtx() |
| 1292 | ->queryConfig() |
| 1293 | .hashBuildProbeAdmissionUnderMemoryPressureEnabled() || |
| 1294 | !spillEnabled() || isInputFromSpill() || numRows == 0; |
| 1295 | const bool spillUnavailable = spiller_ == nullptr || |
| 1296 | spiller_->isAllSpilled() || exceededMaxSpillLevelLimit_; |
| 1297 | if (notReadyForProbeAdmission || spillUnavailable) { |
| 1298 | return 0; |
| 1299 | } |
| 1300 | |
| 1301 | const auto currentBytes = pool()->currentBytes(); |
| 1302 | const auto* task = operatorCtx_->task().get(); |
| 1303 | const auto pressure = task->memoryPressureSnapshot(); |
| 1304 | const auto pressureWatermarkBytes = pressure.admissionWatermarkBytes(); |
| 1305 | // Reclaim records a task-level pressure watermark. Borrow-from-RSS records |
| 1306 | // the current task's execution memory usage at the point dynamic memory |
| 1307 | // management is triggered. Taking the minimum non-zero watermark makes the |
| 1308 | // earliest pressure signal drive a stronger pre-probe admission reservation |
| 1309 | // while the build side can still spill. |
| 1310 | LOG(INFO) << name() << " probeAdmissionExtraReservationBytes: currentBytes=" |
| 1311 | << succinctBytes(currentBytes) << ", reclaimWatermarkBytes=" |
| 1312 | << succinctBytes(pressure.reclaimWatermarkBytes) |
| 1313 | << ", borrowFromRssWatermarkBytes=" |
| 1314 | << succinctBytes(pressure.borrowFromRssWatermarkBytes) |
| 1315 | << ", configuredTaskMemoryQuotaBytes=" |
| 1316 | << succinctBytes(pressure.configuredTaskMemoryQuotaBytes) |
| 1317 | << ", pressureWatermarkBytes=" |
| 1318 | << succinctBytes(pressureWatermarkBytes) << ", details " |
| 1319 | << task->memoryPressureDetails(); |
| 1320 | if (pressureWatermarkBytes != 0 && |
| 1321 | currentBytes > pressureWatermarkBytes * |
| 1322 | operatorCtx_->driverCtx() |
| 1323 | ->queryConfig() |
| 1324 | .memoryPressureWatermarkRatio()) { |
| 1325 | return pressureWatermarkBytes; |
| 1326 | } |
| 1327 | |
| 1328 | const uint64_t probeReservationLimit = |
| 1329 | operatorCtx_->driverCtx()->queryConfig().preferredOutputBatchBytes() * |
| 1330 | operatorCtx_->driverCtx() |
| 1331 | ->queryConfig() |
| 1332 | .outputBatchMemoryReservationMultiple(); |
| 1333 | return std::min<uint64_t>(currentBytes / 2, probeReservationLimit); |
| 1334 | } |
| 1335 | |
| 1336 | void HashBuild::recordSpillStats() { |
| 1337 | recordSpillStats(spiller_.get()); |
nothing calls this directly
no test coverage detected