1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-09 06:21:09 +03:00

Rearrange fmgr.c and relcache so that it's possible to keep FmgrInfo

lookup info in the relcache for index access method support functions.
This makes a huge difference for dynamically loaded support functions,
and should save a few cycles even for built-in ones.  Also tweak dfmgr.c
so that load_external_function is called only once, not twice, when
doing fmgr_info for a dynamically loaded function.  All per performance
gripe from Teodor Sigaev, 5-Oct-01.
This commit is contained in:
Tom Lane
2001-10-06 23:21:45 +00:00
parent a965750abf
commit 85801a4dbd
31 changed files with 424 additions and 390 deletions

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/common/scankey.c,v 1.19 2001/06/01 02:41:35 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/common/scankey.c,v 1.20 2001/10/06 23:21:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -69,3 +69,31 @@ ScanKeyEntryInitialize(ScanKey entry,
Assert(ScanKeyEntryIsLegal(entry));
}
/*
* ScanKeyEntryInitializeWithInfo
* Initializes a scan key entry using an already-completed FmgrInfo
* function lookup record.
*
* mcxt is the memory context holding the scan key; it'll be used for
* any subsidiary info attached to the scankey's FmgrInfo record.
*/
void
ScanKeyEntryInitializeWithInfo(ScanKey entry,
bits16 flags,
AttrNumber attributeNumber,
FmgrInfo *finfo,
MemoryContext mcxt,
Datum argument)
{
Assert(PointerIsValid(entry));
Assert(RegProcedureIsValid(finfo->fn_oid));
entry->sk_flags = flags;
entry->sk_attno = attributeNumber;
entry->sk_procedure = finfo->fn_oid;
entry->sk_argument = argument;
fmgr_info_copy(&entry->sk_func, finfo, mcxt);
Assert(ScanKeyEntryIsLegal(entry));
}

View File

@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.83 2001/08/22 18:24:26 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.84 2001/10/06 23:21:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1542,13 +1542,6 @@ gistbulkdelete(PG_FUNCTION_ARGS)
void
initGISTstate(GISTSTATE *giststate, Relation index)
{
RegProcedure consistent_proc,
union_proc,
compress_proc,
decompress_proc,
penalty_proc,
picksplit_proc,
equal_proc;
int i;
if (index->rd_att->natts > INDEX_MAX_KEYS)
@@ -1559,20 +1552,27 @@ initGISTstate(GISTSTATE *giststate, Relation index)
for (i = 0; i < index->rd_att->natts; i++)
{
consistent_proc = index_getprocid(index, i+1, GIST_CONSISTENT_PROC );
union_proc = index_getprocid(index, i+1, GIST_UNION_PROC );
compress_proc = index_getprocid(index, i+1, GIST_COMPRESS_PROC );
decompress_proc = index_getprocid(index, i+1, GIST_DECOMPRESS_PROC );
penalty_proc = index_getprocid(index, i+1, GIST_PENALTY_PROC );
picksplit_proc = index_getprocid(index, i+1, GIST_PICKSPLIT_PROC );
equal_proc = index_getprocid(index, i+1, GIST_EQUAL_PROC );
fmgr_info(consistent_proc, &((giststate->consistentFn)[i]) );
fmgr_info(union_proc, &((giststate->unionFn)[i]) );
fmgr_info(compress_proc, &((giststate->compressFn)[i]) );
fmgr_info(decompress_proc, &((giststate->decompressFn)[i]) );
fmgr_info(penalty_proc, &((giststate->penaltyFn)[i]) );
fmgr_info(picksplit_proc, &((giststate->picksplitFn)[i]) );
fmgr_info(equal_proc, &((giststate->equalFn)[i]) );
fmgr_info_copy(&(giststate->consistentFn[i]),
index_getprocinfo(index, i+1, GIST_CONSISTENT_PROC),
CurrentMemoryContext);
fmgr_info_copy(&(giststate->unionFn[i]),
index_getprocinfo(index, i+1, GIST_UNION_PROC),
CurrentMemoryContext);
fmgr_info_copy(&(giststate->compressFn[i]),
index_getprocinfo(index, i+1, GIST_COMPRESS_PROC),
CurrentMemoryContext);
fmgr_info_copy(&(giststate->decompressFn[i]),
index_getprocinfo(index, i+1, GIST_DECOMPRESS_PROC),
CurrentMemoryContext);
fmgr_info_copy(&(giststate->penaltyFn[i]),
index_getprocinfo(index, i+1, GIST_PENALTY_PROC),
CurrentMemoryContext);
fmgr_info_copy(&(giststate->picksplitFn[i]),
index_getprocinfo(index, i+1, GIST_PICKSPLIT_PROC),
CurrentMemoryContext);
fmgr_info_copy(&(giststate->equalFn[i]),
index_getprocinfo(index, i+1, GIST_EQUAL_PROC),
CurrentMemoryContext);
}
}

View File

@@ -8,13 +8,14 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashutil.c,v 1.26 2001/02/22 21:48:49 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashutil.c,v 1.27 2001/10/06 23:21:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/genam.h"
#include "access/hash.h"
#include "access/iqual.h"
@@ -27,8 +28,8 @@ _hash_mkscankey(Relation rel, IndexTuple itup, HashMetaPage metap)
int natts;
AttrNumber i;
Datum arg;
RegProcedure proc;
bool null;
FmgrInfo *procinfo;
bool isnull;
natts = rel->rd_rel->relnatts;
itupdesc = RelationGetDescr(rel);
@@ -37,10 +38,14 @@ _hash_mkscankey(Relation rel, IndexTuple itup, HashMetaPage metap)
for (i = 0; i < natts; i++)
{
arg = index_getattr(itup, i + 1, itupdesc, &null);
proc = metap->hashm_procid;
ScanKeyEntryInitialize(&skey[i],
0x0, (AttrNumber) (i + 1), proc, arg);
arg = index_getattr(itup, i + 1, itupdesc, &isnull);
procinfo = index_getprocinfo(rel, i + 1, HASHPROC);
ScanKeyEntryInitializeWithInfo(&skey[i],
0x0,
(AttrNumber) (i + 1),
procinfo,
CurrentMemoryContext,
arg);
}
return skey;
@@ -89,10 +94,13 @@ _hash_formitem(IndexTuple itup)
Bucket
_hash_call(Relation rel, HashMetaPage metap, Datum key)
{
FmgrInfo *procinfo;
uint32 n;
Bucket bucket;
n = DatumGetUInt32(OidFunctionCall1(metap->hashm_procid, key));
/* XXX assumes index has only one attribute */
procinfo = index_getprocinfo(rel, 1, HASHPROC);
n = DatumGetUInt32(FunctionCall1(procinfo, key));
bucket = n & metap->hashm_highmask;
if (bucket > metap->hashm_maxbucket)
bucket = bucket & metap->hashm_lowmask;

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.52 2001/07/15 22:48:15 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.53 2001/10/06 23:21:43 tgl Exp $
*
* INTERFACE ROUTINES
* index_open - open an index relation by relationId
@@ -428,12 +428,58 @@ index_getprocid(Relation irel,
{
RegProcedure *loc;
int nproc;
int procindex;
nproc = irel->rd_am->amsupport;
Assert(procnum > 0 && procnum <= (uint16) nproc);
procindex = (nproc * (attnum - 1)) + (procnum - 1);
loc = irel->rd_support;
Assert(loc != NULL);
return loc[(nproc * (attnum - 1)) + (procnum - 1)];
return loc[procindex];
}
/* ----------------
* index_getprocinfo
*
* This routine allows index AMs to keep fmgr lookup info for
* support procs in the relcache.
* ----------------
*/
struct FmgrInfo *
index_getprocinfo(Relation irel,
AttrNumber attnum,
uint16 procnum)
{
FmgrInfo *locinfo;
int nproc;
int procindex;
nproc = irel->rd_am->amsupport;
Assert(procnum > 0 && procnum <= (uint16) nproc);
procindex = (nproc * (attnum - 1)) + (procnum - 1);
locinfo = irel->rd_supportinfo;
Assert(locinfo != NULL);
locinfo += procindex;
/* Initialize the lookup info if first time through */
if (locinfo->fn_oid == InvalidOid)
{
RegProcedure *loc = irel->rd_support;
Assert(loc != NULL);
fmgr_info_cxt(loc[procindex], locinfo, irel->rd_indexcxt);
}
return locinfo;
}

View File

@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.52 2001/08/21 16:36:00 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.53 2001/10/06 23:21:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -486,12 +486,9 @@ FillScanKeyEntry(Oid operatorObjectId, ScanKey entry)
operatorObjectId);
/*
* Formerly we initialized entry->sk_func here, but that's a waste of
* time because ScanKey entries in strategy maps are never actually
* used to invoke the operator. Furthermore, to do that we'd have to
* worry about setting the proper memory context (the map is probably
* not allocated in the current memory context!)
* Mark entry->sk_func invalid, until and unless someone sets it up.
*/
entry->sk_func.fn_oid = InvalidOid;
}

View File

@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.67 2001/07/15 22:48:16 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.68 2001/10/06 23:21:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -435,7 +435,6 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
BlockNumber blkno;
StrategyNumber strat;
RetrieveIndexResult res;
RegProcedure proc;
int32 result;
BTScanOpaque so;
bool continuescan;
@@ -532,6 +531,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
scankeys = (ScanKey) palloc(keysCount * sizeof(ScanKeyData));
for (i = 0; i < keysCount; i++)
{
FmgrInfo *procinfo;
j = nKeyIs[i];
/*
@@ -545,9 +546,13 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
elog(ERROR, "_bt_first: btree doesn't support is(not)null, yet");
return ((RetrieveIndexResult) NULL);
}
proc = index_getprocid(rel, i + 1, BTORDER_PROC);
ScanKeyEntryInitialize(scankeys + i, so->keyData[j].sk_flags,
i + 1, proc, so->keyData[j].sk_argument);
procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
ScanKeyEntryInitializeWithInfo(scankeys + i,
so->keyData[j].sk_flags,
i + 1,
procinfo,
CurrentMemoryContext,
so->keyData[j].sk_argument);
}
if (nKeyIs)
pfree(nKeyIs);

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.45 2001/05/17 14:59:31 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.46 2001/10/06 23:21:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -36,7 +36,7 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
TupleDesc itupdesc;
int natts;
int i;
RegProcedure proc;
FmgrInfo *procinfo;
Datum arg;
bool null;
bits16 flag;
@@ -48,14 +48,15 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
for (i = 0; i < natts; i++)
{
proc = index_getprocid(rel, i + 1, BTORDER_PROC);
procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
arg = index_getattr(itup, i + 1, itupdesc, &null);
flag = null ? SK_ISNULL : 0x0;
ScanKeyEntryInitialize(&skey[i],
flag,
(AttrNumber) (i + 1),
proc,
arg);
ScanKeyEntryInitializeWithInfo(&skey[i],
flag,
(AttrNumber) (i + 1),
procinfo,
CurrentMemoryContext,
arg);
}
return skey;
@@ -76,7 +77,7 @@ _bt_mkscankey_nodata(Relation rel)
ScanKey skey;
int natts;
int i;
RegProcedure proc;
FmgrInfo *procinfo;
natts = RelationGetNumberOfAttributes(rel);
@@ -84,12 +85,13 @@ _bt_mkscankey_nodata(Relation rel)
for (i = 0; i < natts; i++)
{
proc = index_getprocid(rel, i + 1, BTORDER_PROC);
ScanKeyEntryInitialize(&skey[i],
SK_ISNULL,
(AttrNumber) (i + 1),
proc,
(Datum) NULL);
procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
ScanKeyEntryInitializeWithInfo(&skey[i],
SK_ISNULL,
(AttrNumber) (i + 1),
procinfo,
CurrentMemoryContext,
(Datum) 0);
}
return skey;

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.64 2001/09/29 03:46:12 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtree.c,v 1.65 2001/10/06 23:21:43 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1264,17 +1264,15 @@ rtbulkdelete(PG_FUNCTION_ARGS)
static void
initRtstate(RTSTATE *rtstate, Relation index)
{
RegProcedure union_proc,
size_proc,
inter_proc;
union_proc = index_getprocid(index, 1, RT_UNION_PROC);
size_proc = index_getprocid(index, 1, RT_SIZE_PROC);
inter_proc = index_getprocid(index, 1, RT_INTER_PROC);
fmgr_info(union_proc, &rtstate->unionFn);
fmgr_info(size_proc, &rtstate->sizeFn);
fmgr_info(inter_proc, &rtstate->interFn);
return;
fmgr_info_copy(&rtstate->unionFn,
index_getprocinfo(index, 1, RT_UNION_PROC),
CurrentMemoryContext);
fmgr_info_copy(&rtstate->sizeFn,
index_getprocinfo(index, 1, RT_SIZE_PROC),
CurrentMemoryContext);
fmgr_info_copy(&rtstate->interFn,
index_getprocinfo(index, 1, RT_INTER_PROC),
CurrentMemoryContext);
}
/* for sorting SPLITCOST records in descending order */