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

Commit0a5d5a4

Browse files
committed
Cache the result of makesign() across calls of gtrgm_penalty().
Since gtrgm_penalty() is usually called many times in a row with the same"newval" (to determine which item on an index page newval fits into best),the makesign() calculation is repetitious. It's expensive enough to makeit worth caching the result, so do so. On my machine this is good formore than a 40% savings in the time needed to build a trigram index on/usr/share/dict/words. This is all per a suggestion of Heikki's.In passing, make some mostly-cosmetic improvements in the caching logic inthe other functions in this file that rely on caching info in fn_extra.
1 parentd22a09d commit0a5d5a4

File tree

1 file changed

+90
-44
lines changed

1 file changed

+90
-44
lines changed

‎contrib/pg_trgm/trgm_gist.c

Lines changed: 90 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -190,54 +190,63 @@ gtrgm_consistent(PG_FUNCTION_ARGS)
190190
TRGM*key= (TRGM*)DatumGetPointer(entry->key);
191191
TRGM*qtrg;
192192
boolres;
193+
Sizequerysize=VARSIZE(query);
193194
char*cache= (char*)fcinfo->flinfo->fn_extra,
194-
*cacheContents=cache+MAXALIGN(sizeof(StrategyNumber));
195+
*cachedQuery=cache+MAXALIGN(sizeof(StrategyNumber));
195196

196197
/*
197198
* Store both the strategy number and extracted trigrams in cache, because
198199
* trigram extraction is relatively CPU-expensive.We must include
199200
* strategy number because trigram extraction depends on strategy.
201+
*
202+
* The cached structure contains the strategy number, then the input
203+
* query (starting at a MAXALIGN boundary), then the TRGM value (also
204+
* starting at a MAXALIGN boundary).
200205
*/
201-
if (cache==NULL||strategy!=*((StrategyNumber*)cache)||
202-
VARSIZE(cacheContents)!=VARSIZE(query)||
203-
memcmp(cacheContents,query,VARSIZE(query))!=0)
206+
if (cache==NULL||
207+
strategy!=*((StrategyNumber*)cache)||
208+
VARSIZE(cachedQuery)!=querysize||
209+
memcmp(cachedQuery,query,querysize)!=0)
204210
{
211+
char*newcache;
212+
205213
switch (strategy)
206214
{
207215
caseSimilarityStrategyNumber:
208-
qtrg=generate_trgm(VARDATA(query),VARSIZE(query)-VARHDRSZ);
216+
qtrg=generate_trgm(VARDATA(query),
217+
querysize-VARHDRSZ);
209218
break;
210219
caseILikeStrategyNumber:
211220
#ifndefIGNORECASE
212221
elog(ERROR,"cannot handle ~~* with case-sensitive trigrams");
213222
#endif
214223
/* FALL THRU */
215224
caseLikeStrategyNumber:
216-
qtrg=generate_wildcard_trgm(VARDATA(query),VARSIZE(query)-VARHDRSZ);
225+
qtrg=generate_wildcard_trgm(VARDATA(query),
226+
querysize-VARHDRSZ);
217227
break;
218228
default:
219229
elog(ERROR,"unrecognized strategy number: %d",strategy);
220230
qtrg=NULL;/* keep compiler quiet */
221231
break;
222232
}
223233

234+
newcache=MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
235+
MAXALIGN(sizeof(StrategyNumber))+
236+
MAXALIGN(querysize)+
237+
VARSIZE(qtrg));
238+
cachedQuery=newcache+MAXALIGN(sizeof(StrategyNumber));
239+
240+
*((StrategyNumber*)newcache)=strategy;
241+
memcpy(cachedQuery,query,querysize);
242+
memcpy(cachedQuery+MAXALIGN(querysize),qtrg,VARSIZE(qtrg));
243+
224244
if (cache)
225245
pfree(cache);
226-
227-
fcinfo->flinfo->fn_extra=
228-
MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
229-
MAXALIGN(sizeof(StrategyNumber))+
230-
MAXALIGN(VARSIZE(query))+
231-
VARSIZE(qtrg));
232-
cache= (char*)fcinfo->flinfo->fn_extra;
233-
cacheContents=cache+MAXALIGN(sizeof(StrategyNumber));
234-
235-
*((StrategyNumber*)cache)=strategy;
236-
memcpy(cacheContents,query,VARSIZE(query));
237-
memcpy(cacheContents+MAXALIGN(VARSIZE(query)),qtrg,VARSIZE(qtrg));
246+
fcinfo->flinfo->fn_extra=newcache;
238247
}
239248

240-
qtrg= (TRGM*) (cacheContents+MAXALIGN(VARSIZE(query)));
249+
qtrg= (TRGM*) (cachedQuery+MAXALIGN(querysize));
241250

242251
switch (strategy)
243252
{
@@ -328,24 +337,35 @@ gtrgm_distance(PG_FUNCTION_ARGS)
328337
TRGM*key= (TRGM*)DatumGetPointer(entry->key);
329338
TRGM*qtrg;
330339
float8res;
340+
Sizequerysize=VARSIZE(query);
331341
char*cache= (char*)fcinfo->flinfo->fn_extra;
332342

333-
if (cache==NULL||VARSIZE(cache)!=VARSIZE(query)||memcmp(cache,query,VARSIZE(query))!=0)
343+
/*
344+
* Cache the generated trigrams across multiple calls with the same
345+
* query.
346+
*/
347+
if (cache==NULL||
348+
VARSIZE(cache)!=querysize||
349+
memcmp(cache,query,querysize)!=0)
334350
{
335-
qtrg=generate_trgm(VARDATA(query),VARSIZE(query)-VARHDRSZ);
351+
char*newcache;
336352

337-
if (cache)
338-
pfree(cache);
353+
qtrg=generate_trgm(VARDATA(query),querysize-VARHDRSZ);
354+
355+
newcache=MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
356+
MAXALIGN(querysize)+
357+
VARSIZE(qtrg));
339358

340-
fcinfo->flinfo->fn_extra=MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
341-
MAXALIGN(VARSIZE(query))+VARSIZE(qtrg));
342-
cache= (char*)fcinfo->flinfo->fn_extra;
359+
memcpy(newcache,query,querysize);
360+
memcpy(newcache+MAXALIGN(querysize),qtrg,VARSIZE(qtrg));
343361

344-
memcpy(cache,query,VARSIZE(query));
345-
memcpy(cache+MAXALIGN(VARSIZE(query)),qtrg,VARSIZE(qtrg));
362+
if (cache)
363+
pfree(cache);
364+
fcinfo->flinfo->fn_extra=newcache;
365+
cache=newcache;
346366
}
347367

348-
qtrg= (TRGM*) (cache+MAXALIGN(VARSIZE(query)));
368+
qtrg= (TRGM*) (cache+MAXALIGN(querysize));
349369

350370
switch (strategy)
351371
{
@@ -552,9 +572,36 @@ gtrgm_penalty(PG_FUNCTION_ARGS)
552572

553573
if (ISARRKEY(newval))
554574
{
555-
BITVECsign;
575+
char*cache= (char*)fcinfo->flinfo->fn_extra;
576+
TRGM*cachedVal= (TRGM*) (cache+MAXALIGN(sizeof(BITVEC)));
577+
Sizenewvalsize=VARSIZE(newval);
578+
BITVECPsign;
579+
580+
/*
581+
* Cache the sign data across multiple calls with the same newval.
582+
*/
583+
if (cache==NULL||
584+
VARSIZE(cachedVal)!=newvalsize||
585+
memcmp(cachedVal,newval,newvalsize)!=0)
586+
{
587+
char*newcache;
588+
589+
newcache=MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
590+
MAXALIGN(sizeof(BITVEC))+
591+
newvalsize);
592+
593+
makesign((BITVECP)newcache,newval);
556594

557-
makesign(sign,newval);
595+
cachedVal= (TRGM*) (newcache+MAXALIGN(sizeof(BITVEC)));
596+
memcpy(cachedVal,newval,newvalsize);
597+
598+
if (cache)
599+
pfree(cache);
600+
fcinfo->flinfo->fn_extra=newcache;
601+
cache=newcache;
602+
}
603+
604+
sign= (BITVECP)cache;
558605

559606
if (ISALLTRUE(origval))
560607
*penalty= ((float) (SIGLENBIT-sizebitvec(sign))) / (float) (SIGLENBIT+1);
@@ -643,20 +690,16 @@ gtrgm_picksplit(PG_FUNCTION_ARGS)
643690
CACHESIGN*cache;
644691
SPLITCOST*costvector;
645692

646-
nbytes= (maxoff+2)*sizeof(OffsetNumber);
647-
v->spl_left= (OffsetNumber*)palloc(nbytes);
648-
v->spl_right= (OffsetNumber*)palloc(nbytes);
649-
693+
/* cache the sign data for each existing item */
650694
cache= (CACHESIGN*)palloc(sizeof(CACHESIGN)* (maxoff+2));
651-
fillcache(&cache[FirstOffsetNumber],GETENTRY(entryvec,FirstOffsetNumber));
695+
for (k=FirstOffsetNumber;k <=maxoff;k=OffsetNumberNext(k))
696+
fillcache(&cache[k],GETENTRY(entryvec,k));
652697

698+
/* now find the two furthest-apart items */
653699
for (k=FirstOffsetNumber;k<maxoff;k=OffsetNumberNext(k))
654700
{
655701
for (j=OffsetNumberNext(k);j <=maxoff;j=OffsetNumberNext(j))
656702
{
657-
if (k==FirstOffsetNumber)
658-
fillcache(&cache[j],GETENTRY(entryvec,j));
659-
660703
size_waste=hemdistcache(&(cache[j]),&(cache[k]));
661704
if (size_waste>waste)
662705
{
@@ -667,17 +710,20 @@ gtrgm_picksplit(PG_FUNCTION_ARGS)
667710
}
668711
}
669712

670-
left=v->spl_left;
671-
v->spl_nleft=0;
672-
right=v->spl_right;
673-
v->spl_nright=0;
674-
713+
/* just in case we didn't make a selection ... */
675714
if (seed_1==0||seed_2==0)
676715
{
677716
seed_1=1;
678717
seed_2=2;
679718
}
680719

720+
/* initialize the result vectors */
721+
nbytes= (maxoff+2)*sizeof(OffsetNumber);
722+
v->spl_left=left= (OffsetNumber*)palloc(nbytes);
723+
v->spl_right=right= (OffsetNumber*)palloc(nbytes);
724+
v->spl_nleft=0;
725+
v->spl_nright=0;
726+
681727
/* form initial .. */
682728
if (cache[seed_1].allistrue)
683729
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp