avoid allocations when not columnar

pull/5217/head
Jeff Davis 2021-08-25 10:15:40 -07:00
parent 3020e4d96d
commit 79236ab81f
1 changed files with 54 additions and 17 deletions

View File

@ -69,6 +69,7 @@
typedef struct ColumnarExecLevel typedef struct ColumnarExecLevel
{ {
int depth;
HTAB *hashtable; HTAB *hashtable;
struct ColumnarExecLevel *next; /* next higher level */ struct ColumnarExecLevel *next; /* next higher level */
} ColumnarExecLevel; } ColumnarExecLevel;
@ -124,6 +125,7 @@ static ExecutorStart_hook_type PrevExecutorStartHook = NULL;
static ExecutorFinish_hook_type PrevExecutorFinishHook = NULL; static ExecutorFinish_hook_type PrevExecutorFinishHook = NULL;
static HTAB *ColumnarCopier = NULL; static HTAB *ColumnarCopier = NULL;
static int ColumnarExecDepth = 0;
static ColumnarExecLevel *ColumnarExecLevelStack = NULL; static ColumnarExecLevel *ColumnarExecLevelStack = NULL;
static MemoryContext ColumnarWriterContext = NULL; static MemoryContext ColumnarWriterContext = NULL;
@ -568,15 +570,39 @@ GetWriteContextForDebug(void)
} }
static ColumnarWriteState * static void
GetWriteState(Relation relation, TupleDesc tupdesc, bool iscopy) AllocateWriterContext(void)
{ {
if (ColumnarWriterContext == NULL) if (ColumnarWriterContext == NULL)
{ {
ColumnarWriterContext = AllocSetContextCreate(TopMemoryContext, ColumnarWriterContext = AllocSetContextCreate(
"Columnar Writers Memory Context", TopMemoryContext, "Columnar Writer Memory Context",
ALLOCSET_DEFAULT_SIZES); ALLOCSET_DEFAULT_SIZES);
} }
}
static ColumnarExecLevel *
GetCurrentExecLevel()
{
if (ColumnarExecLevelStack == NULL ||
ColumnarExecLevelStack->depth != ColumnarExecDepth)
{
ColumnarExecLevel *newLevel = MemoryContextAllocZero(
ColumnarWriterContext, sizeof(ColumnarExecLevel));
newLevel->depth = ColumnarExecDepth;
newLevel->next = ColumnarExecLevelStack;
ColumnarExecLevelStack = newLevel;
}
return ColumnarExecLevelStack;
}
static HTAB *
GetWriterHashTable(bool iscopy)
{
AllocateWriterContext();
HTAB **hashtablep; HTAB **hashtablep;
if (iscopy) if (iscopy)
@ -585,7 +611,7 @@ GetWriteState(Relation relation, TupleDesc tupdesc, bool iscopy)
} }
else else
{ {
ColumnarExecLevel *level = ColumnarExecLevelStack; ColumnarExecLevel *level = GetCurrentExecLevel();
hashtablep = &level->hashtable; hashtablep = &level->hashtable;
} }
@ -601,15 +627,25 @@ GetWriteState(Relation relation, TupleDesc tupdesc, bool iscopy)
*hashtablep = hash_create("columnar writers", 64, &info, hashFlags); *hashtablep = hash_create("columnar writers", 64, &info, hashFlags);
} }
return *hashtablep;
}
static ColumnarWriteState *
GetWriteState(Relation relation, TupleDesc tupdesc, bool iscopy)
{
HTAB *hashtable = GetWriterHashTable(iscopy);
bool found; bool found;
ColumnarWriterEntry *entry = hash_search( ColumnarWriterEntry *entry = hash_search(
*hashtablep, &relation->rd_node, HASH_ENTER, &found); hashtable, &relation->rd_node, HASH_ENTER, &found);
if (!found) if (!found)
{ {
ColumnarOptions columnarOptions = { 0 }; ColumnarOptions columnarOptions = { 0 };
ReadColumnarOptions(relation->rd_id, &columnarOptions); ReadColumnarOptions(relation->rd_id, &columnarOptions);
/* if we have a hash table, the memory context must exist */
Assert(ColumnarWriterContext != NULL);
MemoryContext oldContext = MemoryContextSwitchTo(ColumnarWriterContext); MemoryContext oldContext = MemoryContextSwitchTo(ColumnarWriterContext);
entry->writeState = ColumnarBeginWrite(relation->rd_node, entry->writeState = ColumnarBeginWrite(relation->rd_node,
columnarOptions, columnarOptions,
@ -1783,11 +1819,7 @@ ColumnarExecutorStart(QueryDesc *queryDesc, int eflags)
{ {
PrevExecutorStartHook(queryDesc, eflags); PrevExecutorStartHook(queryDesc, eflags);
ColumnarExecLevel *level = MemoryContextAllocZero(TopMemoryContext, ColumnarExecDepth++;
sizeof(ColumnarExecLevel));
/* initialize hashtable lazily */
level->next = ColumnarExecLevelStack;
ColumnarExecLevelStack = level;
} }
@ -1814,13 +1846,18 @@ ColumnarFlushWriters(HTAB *hashtable)
static void static void
ColumnarExecutorFinish(QueryDesc *queryDesc) ColumnarExecutorFinish(QueryDesc *queryDesc)
{ {
ColumnarExecLevel *level = ColumnarExecLevelStack; Assert(ColumnarExecDepth > 0);
Assert(level != NULL); if (ColumnarExecLevelStack != NULL &&
ColumnarExecLevelStack->depth == ColumnarExecDepth)
{
ColumnarExecLevel *level = ColumnarExecLevelStack;
ColumnarExecLevelStack = ColumnarExecLevelStack->next;
ColumnarFlushWriters(level->hashtable);
pfree(level);
}
ColumnarFlushWriters(level->hashtable); ColumnarExecDepth--;
ColumnarExecLevelStack = level->next;
pfree(level);
PrevExecutorFinishHook(queryDesc); PrevExecutorFinishHook(queryDesc);
} }