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

Commit40064a8

Browse files
committed
Optimize InvalidateAttoptCacheCallback() and TypeCacheTypCallback()
These callbacks are receiving hash values as arguments, which doesn't allowdirect lookups for AttoptCacheHash and TypeCacheHash. This is why subjectcallbacks currently use full iteration over corresponding hashes.This commit avoids full hash iteration in InvalidateAttoptCacheCallback(),and TypeCacheTypCallback(). At first, we switch AttoptCacheHash andTypeCacheHash to use same hash function as syscache. As second, weuse hash_seq_init_with_hash_value() to iterate only hash entries with matchinghash value.Discussion:https://postgr.es/m/5812a6e5-68ae-4d84-9d85-b443176966a1%40sigaev.ruAuthor: Teodor SigaevReviewed-by: Aleksander Alekseev, Tom Lane, Michael Paquier, Roman ZharkovReviewed-by: Andrei Lepikhov
1 parentd0f0200 commit40064a8

File tree

2 files changed

+73
-21
lines changed

2 files changed

+73
-21
lines changed

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

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,27 @@ typedef struct
4444

4545
/*
4646
* InvalidateAttoptCacheCallback
47-
*Flushallcache entries when pg_attribute is updated.
47+
*Flush cacheentry (orentries) when pg_attribute is updated.
4848
*
4949
* When pg_attribute is updated, we must flush the cache entry at least
50-
* for that attribute. Currently, we just flush them all. Since attribute
51-
* options are not currently used in performance-critical paths (such as
52-
* query execution), this seems OK.
50+
* for that attribute.
5351
*/
5452
staticvoid
5553
InvalidateAttoptCacheCallback(Datumarg,intcacheid,uint32hashvalue)
5654
{
5755
HASH_SEQ_STATUSstatus;
5856
AttoptCacheEntry*attopt;
5957

60-
hash_seq_init(&status,AttoptCacheHash);
58+
/*
59+
* By convention, zero hash value is passed to the callback as a sign that
60+
* it's time to invalidate the whole cache. See sinval.c, inval.c and
61+
* InvalidateSystemCachesExtended().
62+
*/
63+
if (hashvalue==0)
64+
hash_seq_init(&status,AttoptCacheHash);
65+
else
66+
hash_seq_init_with_hash_value(&status,AttoptCacheHash,hashvalue);
67+
6168
while ((attopt= (AttoptCacheEntry*)hash_seq_search(&status))!=NULL)
6269
{
6370
if (attopt->opts)
@@ -70,6 +77,18 @@ InvalidateAttoptCacheCallback(Datum arg, int cacheid, uint32 hashvalue)
7077
}
7178
}
7279

80+
/*
81+
* Hash function compatible with two-arg system cache hash function.
82+
*/
83+
staticuint32
84+
relatt_cache_syshash(constvoid*key,Sizekeysize)
85+
{
86+
constAttoptCacheKey*ckey=key;
87+
88+
Assert(keysize==sizeof(*ckey));
89+
returnGetSysCacheHashValue2(ATTNUM,ckey->attrelid,ckey->attnum);
90+
}
91+
7392
/*
7493
* InitializeAttoptCache
7594
*Initialize the attribute options cache.
@@ -82,9 +101,17 @@ InitializeAttoptCache(void)
82101
/* Initialize the hash table. */
83102
ctl.keysize=sizeof(AttoptCacheKey);
84103
ctl.entrysize=sizeof(AttoptCacheEntry);
104+
105+
/*
106+
* AttoptCacheEntry takes hash value from the system cache. For
107+
* AttoptCacheHash we use the same hash in order to speedup search by hash
108+
* value. This is used by hash_seq_init_with_hash_value().
109+
*/
110+
ctl.hash=relatt_cache_syshash;
111+
85112
AttoptCacheHash=
86113
hash_create("Attopt cache",256,&ctl,
87-
HASH_ELEM |HASH_BLOBS);
114+
HASH_ELEM |HASH_FUNCTION);
88115

89116
/* Make sure we've initialized CacheMemoryContext. */
90117
if (!CacheMemoryContext)

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

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,16 @@ static dsa_pointer share_tupledesc(dsa_area *area, TupleDesc tupdesc,
331331
uint32typmod);
332332

333333

334+
/*
335+
* Hash function compatible with one-arg system cache hash function.
336+
*/
337+
staticuint32
338+
type_cache_syshash(constvoid*key,Sizekeysize)
339+
{
340+
Assert(keysize==sizeof(Oid));
341+
returnGetSysCacheHashValue1(TYPEOID,ObjectIdGetDatum(*(constOid*)key));
342+
}
343+
334344
/*
335345
* lookup_type_cache
336346
*
@@ -355,8 +365,16 @@ lookup_type_cache(Oid type_id, int flags)
355365

356366
ctl.keysize=sizeof(Oid);
357367
ctl.entrysize=sizeof(TypeCacheEntry);
368+
369+
/*
370+
* TypeEntry takes hash value from the system cache. For TypeCacheHash
371+
* we use the same hash in order to speedup search by hash value. This
372+
* is used by hash_seq_init_with_hash_value().
373+
*/
374+
ctl.hash=type_cache_syshash;
375+
358376
TypeCacheHash=hash_create("Type information cache",64,
359-
&ctl,HASH_ELEM |HASH_BLOBS);
377+
&ctl,HASH_ELEM |HASH_FUNCTION);
360378

361379
/* Also set up callbacks for SI invalidations */
362380
CacheRegisterRelcacheCallback(TypeCacheRelCallback, (Datum)0);
@@ -407,8 +425,7 @@ lookup_type_cache(Oid type_id, int flags)
407425

408426
/* These fields can never change, by definition */
409427
typentry->type_id=type_id;
410-
typentry->type_id_hash=GetSysCacheHashValue1(TYPEOID,
411-
ObjectIdGetDatum(type_id));
428+
typentry->type_id_hash=get_hash_value(TypeCacheHash,&type_id);
412429

413430
/* Keep this part in sync with the code below */
414431
typentry->typlen=typtup->typlen;
@@ -2358,20 +2375,28 @@ TypeCacheTypCallback(Datum arg, int cacheid, uint32 hashvalue)
23582375
TypeCacheEntry*typentry;
23592376

23602377
/* TypeCacheHash must exist, else this callback wouldn't be registered */
2361-
hash_seq_init(&status,TypeCacheHash);
2378+
2379+
/*
2380+
* By convention, zero hash value is passed to the callback as a sign that
2381+
* it's time to invalidate the whole cache. See sinval.c, inval.c and
2382+
* InvalidateSystemCachesExtended().
2383+
*/
2384+
if (hashvalue==0)
2385+
hash_seq_init(&status,TypeCacheHash);
2386+
else
2387+
hash_seq_init_with_hash_value(&status,TypeCacheHash,hashvalue);
2388+
23622389
while ((typentry= (TypeCacheEntry*)hash_seq_search(&status))!=NULL)
23632390
{
2364-
/* Is this the targeted type row (or it's a total cache flush)? */
2365-
if (hashvalue==0||typentry->type_id_hash==hashvalue)
2366-
{
2367-
/*
2368-
* Mark the data obtained directly from pg_type as invalid. Also,
2369-
* if it's a domain, typnotnull might've changed, so we'll need to
2370-
* recalculate its constraints.
2371-
*/
2372-
typentry->flags &= ~(TCFLAGS_HAVE_PG_TYPE_DATA |
2373-
TCFLAGS_CHECKED_DOMAIN_CONSTRAINTS);
2374-
}
2391+
Assert(hashvalue==0||typentry->type_id_hash==hashvalue);
2392+
2393+
/*
2394+
* Mark the data obtained directly from pg_type as invalid. Also, if
2395+
* it's a domain, typnotnull might've changed, so we'll need to
2396+
* recalculate its constraints.
2397+
*/
2398+
typentry->flags &= ~(TCFLAGS_HAVE_PG_TYPE_DATA |
2399+
TCFLAGS_CHECKED_DOMAIN_CONSTRAINTS);
23752400
}
23762401
}
23772402

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp