Skip to content

Commit

Permalink
Avoid reading/hashing the inner stream(s) if the leader stream is empty
Browse files Browse the repository at this point in the history
  • Loading branch information
dyemanov committed Mar 20, 2024
1 parent 2443106 commit fb994b5
Showing 1 changed file with 37 additions and 30 deletions.
67 changes: 37 additions & 30 deletions src/jrd/recsrc/HashJoin.cpp
Expand Up @@ -318,35 +318,10 @@ void HashJoin::internalOpen(thread_db* tdbb) const
impure->irsb_flags = irsb_open | irsb_mustread;

delete impure->irsb_hash_table;
delete[] impure->irsb_leader_buffer;

MemoryPool& pool = *tdbb->getDefaultPool();

const FB_SIZE_T argCount = m_args.getCount();

impure->irsb_hash_table = FB_NEW_POOL(pool) HashTable(pool, argCount);
impure->irsb_leader_buffer = FB_NEW_POOL(pool) UCHAR[m_leader.totalKeyLength];

UCharBuffer buffer(pool);

for (FB_SIZE_T i = 0; i < argCount; i++)
{
// Read and cache the inner streams. While doing that,
// hash the join condition values and populate hash tables.
impure->irsb_hash_table = nullptr;

m_args[i].buffer->open(tdbb);

ULONG counter = 0;
UCHAR* const keyBuffer = buffer.getBuffer(m_args[i].totalKeyLength, false);

while (m_args[i].buffer->getRecord(tdbb))
{
const ULONG hash = computeHash(tdbb, request, m_args[i], keyBuffer);
impure->irsb_hash_table->put(i, hash, counter++);
}
}

impure->irsb_hash_table->sort();
delete[] impure->irsb_leader_buffer;
impure->irsb_leader_buffer = nullptr;

m_leader.source->open(tdbb);
}
Expand All @@ -363,10 +338,10 @@ void HashJoin::close(thread_db* tdbb) const
impure->irsb_flags &= ~irsb_open;

delete impure->irsb_hash_table;
impure->irsb_hash_table = NULL;
impure->irsb_hash_table = nullptr;

delete[] impure->irsb_leader_buffer;
impure->irsb_leader_buffer = NULL;
impure->irsb_leader_buffer = nullptr;

for (FB_SIZE_T i = 0; i < m_args.getCount(); i++)
m_args[i].buffer->close(tdbb);
Expand Down Expand Up @@ -394,6 +369,38 @@ bool HashJoin::internalGetRecord(thread_db* tdbb) const
if (!m_leader.source->getRecord(tdbb))
return false;

// We have something to join with, so ensure the hash table is initialized

if (!impure->irsb_hash_table && !impure->irsb_leader_buffer)
{
auto& pool = *tdbb->getDefaultPool();
const auto argCount = m_args.getCount();

impure->irsb_hash_table = FB_NEW_POOL(pool) HashTable(pool, argCount);
impure->irsb_leader_buffer = FB_NEW_POOL(pool) UCHAR[m_leader.totalKeyLength];

UCharBuffer buffer(pool);

for (FB_SIZE_T i = 0; i < argCount; i++)
{
// Read and cache the inner streams. While doing that,
// hash the join condition values and populate hash tables.

m_args[i].buffer->open(tdbb);

ULONG counter = 0;
const auto keyBuffer = buffer.getBuffer(m_args[i].totalKeyLength, false);

while (m_args[i].buffer->getRecord(tdbb))
{
const auto hash = computeHash(tdbb, request, m_args[i], keyBuffer);
impure->irsb_hash_table->put(i, hash, counter++);
}
}

impure->irsb_hash_table->sort();
}

// Compute and hash the comparison keys

impure->irsb_leader_hash =
Expand Down

0 comments on commit fb994b5

Please sign in to comment.