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:
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user