Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd8cedf6

Browse files
committed
Clean up some really grotty coding in catcache.c, improve hashing
performance in catcache lookups.
1 parenta60c9e3 commitd8cedf6

File tree

9 files changed

+128
-131
lines changed

9 files changed

+128
-131
lines changed

‎src/backend/access/hash/hashfunc.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.23 2000/01/26 05:55:55 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.24 2000/02/21 03:36:46 tgl Exp $
1212
*
1313
* NOTES
1414
* These functions are stored in pg_amproc.For each operator class
@@ -146,8 +146,24 @@ hashoidvector(Oid *key)
146146
inti;
147147
uint32result=0;
148148

149-
for (i=0;i<INDEX_MAX_KEYS;i++)
150-
result=result ^ (~(uint32)key[i]);
149+
for (i=INDEX_MAX_KEYS;--i >=0; )
150+
result= (result <<1) ^ (~(uint32)key[i]);
151+
returnresult;
152+
}
153+
154+
/*
155+
* Note: hashint2vector currently can't be used as a user hash table
156+
* hash function, because it has no pg_proc entry. We only need it
157+
* for catcache indexing.
158+
*/
159+
uint32
160+
hashint2vector(int16*key)
161+
{
162+
inti;
163+
uint32result=0;
164+
165+
for (i=INDEX_MAX_KEYS;--i >=0; )
166+
result= (result <<1) ^ (~(uint32)key[i]);
151167
returnresult;
152168
}
153169

@@ -158,13 +174,10 @@ hashoidvector(Oid *key)
158174
uint32
159175
hashchar(charkey)
160176
{
161-
intlen;
162177
uint32h;
163178

164-
h=0;
165-
len=sizeof(char);
166179
/* Convert char to integer */
167-
h=h*PRIME1 ^(key-' ');
180+
h= (key-' ');
168181
h %=PRIME2;
169182

170183
returnh;

‎src/backend/utils/adt/int.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/int.c,v 1.32 2000/01/26 05:57:14 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/int.c,v 1.33 2000/02/21 03:36:48 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -144,6 +144,17 @@ int2vectorout(int16 *int2Array)
144144
returnresult;
145145
}
146146

147+
/*
148+
* We don't have a complete set of int2vector support routines,
149+
* but we need int2vectoreq for catcache indexing.
150+
*/
151+
bool
152+
int2vectoreq(int16*arg1,int16*arg2)
153+
{
154+
return (bool) (memcmp(arg1,arg2,INDEX_MAX_KEYS*sizeof(int16))==0);
155+
}
156+
157+
147158
/*
148159
*int44in- converts "num num ..." to internal form
149160
*
@@ -169,7 +180,7 @@ int44in(char *input_string)
169180
}
170181

171182
/*
172-
*int2vectorout- converts internal form to "num num ..."
183+
*int44out- converts internal form to "num num ..."
173184
*/
174185
char*
175186
int44out(int32*an_array)
@@ -489,13 +500,6 @@ int42ge(int32 arg1, int32 arg2)
489500
returnarg1 >=arg2;
490501
}
491502

492-
493-
bool
494-
keyfirsteq(int16*arg1,int16arg2)
495-
{
496-
return*arg1==arg2;
497-
}
498-
499503
/*
500504
*int[24]pl- returns arg1 + arg2
501505
*int[24]mi- returns arg1 - arg2

‎src/backend/utils/cache/catcache.c

Lines changed: 79 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.61 2000/02/18 09:28:53 inoue Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.62 2000/02/21 03:36:49 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
1515
#include"postgres.h"
16+
1617
#include"access/genam.h"
18+
#include"access/hash.h"
1719
#include"access/heapam.h"
1820
#include"access/valid.h"
1921
#include"catalog/pg_operator.h"
@@ -28,10 +30,11 @@
2830
staticvoidCatCacheRemoveCTup(CatCache*cache,Dlelem*e);
2931
staticIndexCatalogCacheComputeHashIndex(structcatcache*cacheInP);
3032
staticIndexCatalogCacheComputeTupleHashIndex(structcatcache*cacheInOutP,
31-
Relationrelation,HeapTupletuple);
33+
Relationrelation,
34+
HeapTupletuple);
3235
staticvoidCatalogCacheInitializeCache(structcatcache*cache,
33-
Relationrelation);
34-
staticlongcomphash(longl,char*v);
36+
Relationrelation);
37+
staticuint32cc_hashname(NameData*n);
3538

3639
/* ----------------
3740
*variables, macros and other stuff
@@ -63,14 +66,15 @@ GlobalMemory CacheCxt;/* context in which caches are allocated */
6366
/* ----------------
6467
*EQPROC is used in CatalogCacheInitializeCache to find the equality
6568
*functions for system types that are used as cache key fields.
69+
*See also GetCCHashFunc, which should support the same set of types.
6670
*
6771
*XXX this should be replaced by catalog lookups,
6872
*but that seems to pose considerable risk of circularity...
6973
* ----------------
7074
*/
7175
staticconstOideqproc[]= {
7276
F_BOOLEQ,InvalidOid,F_CHAREQ,F_NAMEEQ,InvalidOid,
73-
F_INT2EQ,F_KEYFIRSTEQ,F_INT4EQ,F_OIDEQ,F_TEXTEQ,
77+
F_INT2EQ,F_INT2VECTOREQ,F_INT4EQ,F_OIDEQ,F_TEXTEQ,
7478
F_OIDEQ,InvalidOid,InvalidOid,InvalidOid,F_OIDVECTOREQ
7579
};
7680

@@ -80,6 +84,54 @@ static const Oid eqproc[] = {
8084
*internal support functions
8185
* ----------------------------------------------------------------
8286
*/
87+
88+
staticCCHashFunc
89+
GetCCHashFunc(Oidkeytype)
90+
{
91+
switch (keytype)
92+
{
93+
caseBOOLOID:
94+
caseCHAROID:
95+
return (CCHashFunc)hashchar;
96+
caseNAMEOID:
97+
return (CCHashFunc)cc_hashname;
98+
caseINT2OID:
99+
return (CCHashFunc)hashint2;
100+
caseINT2VECTOROID:
101+
return (CCHashFunc)hashint2vector;
102+
caseINT4OID:
103+
return (CCHashFunc)hashint4;
104+
caseTEXTOID:
105+
return (CCHashFunc)hashtext;
106+
caseREGPROCOID:
107+
caseOIDOID:
108+
return (CCHashFunc)hashoid;
109+
caseOIDVECTOROID:
110+
return (CCHashFunc)hashoidvector;
111+
default:
112+
elog(FATAL,"GetCCHashFunc: type %u unsupported as catcache key",
113+
keytype);
114+
returnNULL;
115+
}
116+
}
117+
118+
staticuint32
119+
cc_hashname(NameData*n)
120+
{
121+
/*
122+
* We need our own variant of hashname because we want to accept
123+
* null-terminated C strings as search values for name fields.
124+
* So, we have to make sure the data is correctly padded before
125+
* we compute the hash value.
126+
*/
127+
NameDatamy_n;
128+
129+
namestrcpy(&my_n,NameStr(*n));
130+
131+
returnhashname(&my_n);
132+
}
133+
134+
83135
/* --------------------------------
84136
*CatalogCacheInitializeCache
85137
* --------------------------------
@@ -190,31 +242,20 @@ CatalogCacheInitializeCache(struct catcache * cache,
190242

191243
if (cache->cc_key[i]>0)
192244
{
245+
Oidkeytype=tupdesc->attrs[cache->cc_key[i]-1]->atttypid;
193246

194-
/*
195-
* Yoiks. The implementation of the hashing code and the
196-
* implementation of int2vector's are at loggerheads. The right
197-
* thing to do is to throw out the implementation of int2vector's
198-
* altogether; until that happens, we do the right thing here
199-
* to guarantee that the hash key generator doesn't try to
200-
* dereference an int2 by mistake.
201-
*/
247+
cache->cc_hashfunc[i]=GetCCHashFunc(keytype);
202248

203-
if (tupdesc->attrs[cache->cc_key[i]-1]->atttypid==INT2VECTOROID)
204-
cache->cc_klen[i]=sizeof(short);
205-
else
206-
cache->cc_klen[i]=tupdesc->attrs[cache->cc_key[i]-1]->attlen;
207-
208-
cache->cc_skey[i].sk_procedure=EQPROC(tupdesc->attrs[cache->cc_key[i]-1]->atttypid);
249+
/* If GetCCHashFunc liked the type, safe to index into eqproc[] */
250+
cache->cc_skey[i].sk_procedure=EQPROC(keytype);
209251

210252
fmgr_info(cache->cc_skey[i].sk_procedure,
211253
&cache->cc_skey[i].sk_func);
212254
cache->cc_skey[i].sk_nargs=cache->cc_skey[i].sk_func.fn_nargs;
213255

214-
CACHE5_elog(DEBUG,"CatalogCacheInit %s %d %d %x",
256+
CACHE4_elog(DEBUG,"CatalogCacheInit %s %d %x",
215257
RelationGetRelationName(relation),
216258
i,
217-
tupdesc->attrs[cache->cc_key[i]-1]->attlen,
218259
cache);
219260
}
220261
}
@@ -255,94 +296,44 @@ CatalogCacheInitializeCache(struct catcache * cache,
255296
MemoryContextSwitchTo(oldcxt);
256297
}
257298

258-
/* ----------------
259-
* comphash
260-
*Compute a hash value, somehow.
261-
*
262-
* XXX explain algorithm here.
263-
*
264-
* l is length of the attribute value, v
265-
* v is the attribute value ("Datum")
266-
* ----------------
267-
*/
268-
staticlong
269-
comphash(longl,char*v)
270-
{
271-
longi;
272-
NameDatan;
273-
274-
CACHE3_elog(DEBUG,"comphash (%d,%x)",l,v);
275-
276-
switch (l)
277-
{
278-
case1:
279-
case2:
280-
case4:
281-
return (long)v;
282-
}
283-
284-
if (l==NAMEDATALEN)
285-
{
286-
287-
/*
288-
* if it's a name, make sure that the values are null-padded.
289-
*
290-
* Note that this other fixed-length types can also have the same
291-
* typelen so this may break them - XXX
292-
*/
293-
namestrcpy(&n,v);
294-
v=NameStr(n);
295-
}
296-
elseif (l<0)
297-
l=VARSIZE(v);
298-
299-
i=0;
300-
while (l--)
301-
i+=*v++;
302-
returni;
303-
}
304-
305299
/* --------------------------------
306300
*CatalogCacheComputeHashIndex
307301
* --------------------------------
308302
*/
309303
staticIndex
310304
CatalogCacheComputeHashIndex(structcatcache*cacheInP)
311305
{
312-
IndexhashIndex;
306+
uint32hashIndex=0;
313307

314-
hashIndex=0x0;
315-
CACHE6_elog(DEBUG,"CatalogCacheComputeHashIndex %s %d %d %d %x",
308+
CACHE4_elog(DEBUG,"CatalogCacheComputeHashIndex %s %d %x",
316309
cacheInP->cc_relname,
317310
cacheInP->cc_nkeys,
318-
cacheInP->cc_klen[0],
319-
cacheInP->cc_klen[1],
320311
cacheInP);
321312

322313
switch (cacheInP->cc_nkeys)
323314
{
324315
case4:
325-
hashIndex ^=comphash(cacheInP->cc_klen[3],
326-
(char*)cacheInP->cc_skey[3].sk_argument) <<9;
316+
hashIndex ^=
317+
(*cacheInP->cc_hashfunc[3])(cacheInP->cc_skey[3].sk_argument) <<9;
327318
/* FALLTHROUGH */
328319
case3:
329-
hashIndex ^=comphash(cacheInP->cc_klen[2],
330-
(char*)cacheInP->cc_skey[2].sk_argument) <<6;
320+
hashIndex ^=
321+
(*cacheInP->cc_hashfunc[2])(cacheInP->cc_skey[2].sk_argument) <<6;
331322
/* FALLTHROUGH */
332323
case2:
333-
hashIndex ^=comphash(cacheInP->cc_klen[1],
334-
(char*)cacheInP->cc_skey[1].sk_argument) <<3;
324+
hashIndex ^=
325+
(*cacheInP->cc_hashfunc[1])(cacheInP->cc_skey[1].sk_argument) <<3;
335326
/* FALLTHROUGH */
336327
case1:
337-
hashIndex ^=comphash(cacheInP->cc_klen[0],
338-
(char*)cacheInP->cc_skey[0].sk_argument);
328+
hashIndex ^=
329+
(*cacheInP->cc_hashfunc[0])(cacheInP->cc_skey[0].sk_argument);
339330
break;
340331
default:
341332
elog(FATAL,"CCComputeHashIndex: %d cc_nkeys",cacheInP->cc_nkeys);
342333
break;
343334
}
344-
hashIndex %=cacheInP->cc_size;
345-
returnhashIndex;
335+
hashIndex %=(uint32)cacheInP->cc_size;
336+
return(Index)hashIndex;
346337
}
347338

348339
/* --------------------------------
@@ -645,8 +636,8 @@ do { \
645636
cp->relationId, cp->id, cp->cc_nkeys, cp->cc_size); \
646637
for (i = 0; i < nkeys; i += 1) \
647638
{ \
648-
elog(DEBUG, "InitSysCache: key=%dlen=%dskey=[%d %d %d %d]\n", \
649-
cp->cc_key[i],cp->cc_klen[i],\
639+
elog(DEBUG, "InitSysCache: key=%d skey=[%d %d %d %d]\n", \
640+
cp->cc_key[i], \
650641
cp->cc_skey[i].sk_flags, \
651642
cp->cc_skey[i].sk_attno, \
652643
cp->cc_skey[i].sk_procedure, \
@@ -742,7 +733,8 @@ InitSysCache(char *relname,
742733
cp->cc_iscanfunc=iScanfuncP;
743734

744735
/* ----------------
745-
*initialize the cache's key information
736+
*partially initialize the cache's key information
737+
*CatalogCacheInitializeCache() will do the rest
746738
* ----------------
747739
*/
748740
for (i=0;i<nkeys;++i)
@@ -756,15 +748,7 @@ InitSysCache(char *relname,
756748
elog(FATAL,"InitSysCache: called with %d key[%d]",key[i],i);
757749
else
758750
{
759-
cp->cc_klen[i]=sizeof(Oid);
760-
761-
/*
762-
* ScanKeyEntryData and struct skey are equivalent. It
763-
* looks like a move was made to obsolete struct skey, but
764-
* it didn't reach this file. Someday we should clean up
765-
* this code and consolidate to ScanKeyEntry - mer 10 Nov
766-
* 1991
767-
*/
751+
cp->cc_hashfunc[i]=GetCCHashFunc(OIDOID);
768752
ScanKeyEntryInitialize(&cp->cc_skey[i],
769753
(bits16)0,
770754
(AttrNumber)key[i],

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp