MCPcopy Create free account
hub / github.com/apache/cloudberry / ExecParallelHashTupleAlloc

Function ExecParallelHashTupleAlloc

src/backend/executor/nodeHash.c:3504–3645  ·  view source on GitHub ↗

* Allocate space for a tuple in shared dense storage. This is equivalent to * dense_alloc but for Parallel Hash using shared memory. * * While loading a tuple into shared memory, we might run out of memory and * decide to repartition, or determine that the load factor is too high and * decide to expand the bucket array, or discover that another participant has * commanded us to help do that

Source from the content-addressed store, hash-verified

3502 * possibility that the tuple no longer belongs in the same batch).
3503 */
3504static HashJoinTuple
3505ExecParallelHashTupleAlloc(HashJoinTable hashtable, size_t size,
3506 dsa_pointer *shared)
3507{
3508 ParallelHashJoinState *pstate = hashtable->parallel_state;
3509 dsa_pointer chunk_shared;
3510 HashMemoryChunk chunk;
3511 Size chunk_size;
3512 HashJoinTuple result;
3513 int curbatch = hashtable->curbatch;
3514
3515 size = MAXALIGN(size);
3516
3517 /*
3518 * Fast path: if there is enough space in this backend's current chunk,
3519 * then we can allocate without any locking.
3520 */
3521 chunk = hashtable->current_chunk;
3522 if (chunk != NULL &&
3523 size <= HASH_CHUNK_THRESHOLD &&
3524 chunk->maxlen - chunk->used >= size)
3525 {
3526
3527 chunk_shared = hashtable->current_chunk_shared;
3528 Assert(chunk == dsa_get_address(hashtable->area, chunk_shared));
3529 *shared = chunk_shared + HASH_CHUNK_HEADER_SIZE + chunk->used;
3530 result = (HashJoinTuple) (HASH_CHUNK_DATA(chunk) + chunk->used);
3531 chunk->used += size;
3532
3533 Assert(chunk->used <= chunk->maxlen);
3534 Assert(result == dsa_get_address(hashtable->area, *shared));
3535
3536 return result;
3537 }
3538
3539 /* Slow path: try to allocate a new chunk. */
3540 LWLockAcquire(&pstate->lock, LW_EXCLUSIVE);
3541
3542 /*
3543 * Check if we need to help increase the number of buckets or batches.
3544 */
3545 if (pstate->growth == PHJ_GROWTH_NEED_MORE_BATCHES ||
3546 pstate->growth == PHJ_GROWTH_NEED_MORE_BUCKETS)
3547 {
3548 ParallelHashGrowth growth = pstate->growth;
3549
3550 hashtable->current_chunk = NULL;
3551 LWLockRelease(&pstate->lock);
3552
3553 /* Another participant has commanded us to help grow. */
3554 if (growth == PHJ_GROWTH_NEED_MORE_BATCHES)
3555 ExecParallelHashIncreaseNumBatches(hashtable);
3556 else if (growth == PHJ_GROWTH_NEED_MORE_BUCKETS)
3557 ExecParallelHashIncreaseNumBuckets(hashtable);
3558
3559 /* The caller must retry. */
3560 return NULL;
3561 }

Calls 6

dsa_get_addressFunction · 0.85
LWLockAcquireFunction · 0.85
LWLockReleaseFunction · 0.85
BarrierPhaseFunction · 0.85

Tested by

no test coverage detected