Skip to content

Commit 753d119

Browse files
jeff-davispull[bot]
authored andcommitted
Optimize SearchPathCache by saving the last entry.
Repeated lookups are common, so it's worth it to check the last entry before doing another hash lookup. Discussion: https://postgr.es/m/04c8592dbd694e4114a3ed87139a7a04e4363030.camel%40j-davis.com
1 parent 27ce9ad commit 753d119

File tree

1 file changed

+57
-31
lines changed

1 file changed

+57
-31
lines changed

src/backend/catalog/namespace.c

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,8 @@ static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames,
241241
*
242242
* The search path cache is based on a wrapper around a simplehash hash table
243243
* (nsphash, defined below). The spcache wrapper deals with OOM while trying
244-
* to initialize a key, and also offers a more convenient API.
244+
* to initialize a key, optimizes repeated lookups of the same key, and also
245+
* offers a more convenient API.
245246
*/
246247

247248
static inline uint32
@@ -281,6 +282,7 @@ spcachekey_equal(SearchPathCacheKey a, SearchPathCacheKey b)
281282
#define SPCACHE_RESET_THRESHOLD 256
282283

283284
static nsphash_hash * SearchPathCache = NULL;
285+
static SearchPathCacheEntry * LastSearchPathCacheEntry = NULL;
284286

285287
/*
286288
* Create or reset search_path cache as necessary.
@@ -295,6 +297,7 @@ spcache_init(void)
295297
return;
296298

297299
MemoryContextReset(SearchPathCacheContext);
300+
LastSearchPathCacheEntry = NULL;
298301
/* arbitrary initial starting size of 16 elements */
299302
SearchPathCache = nsphash_create(SearchPathCacheContext, 16, NULL);
300303
searchPathCacheValid = true;
@@ -307,12 +310,25 @@ spcache_init(void)
307310
static SearchPathCacheEntry *
308311
spcache_lookup(const char *searchPath, Oid roleid)
309312
{
310-
SearchPathCacheKey cachekey = {
311-
.searchPath = searchPath,
312-
.roleid = roleid
313-
};
313+
if (LastSearchPathCacheEntry &&
314+
LastSearchPathCacheEntry->key.roleid == roleid &&
315+
strcmp(LastSearchPathCacheEntry->key.searchPath, searchPath) == 0)
316+
{
317+
return LastSearchPathCacheEntry;
318+
}
319+
else
320+
{
321+
SearchPathCacheEntry *entry;
322+
SearchPathCacheKey cachekey = {
323+
.searchPath = searchPath,
324+
.roleid = roleid
325+
};
326+
327+
entry = nsphash_lookup(SearchPathCache, cachekey);
314328

315-
return nsphash_lookup(SearchPathCache, cachekey);
329+
LastSearchPathCacheEntry = entry;
330+
return entry;
331+
}
316332
}
317333

318334
/*
@@ -324,35 +340,45 @@ spcache_lookup(const char *searchPath, Oid roleid)
324340
static SearchPathCacheEntry *
325341
spcache_insert(const char *searchPath, Oid roleid)
326342
{
327-
SearchPathCacheEntry *entry;
328-
SearchPathCacheKey cachekey = {
329-
.searchPath = searchPath,
330-
.roleid = roleid
331-
};
332-
333-
/*
334-
* searchPath is not saved in SearchPathCacheContext. First perform a
335-
* lookup, and copy searchPath only if we need to create a new entry.
336-
*/
337-
entry = nsphash_lookup(SearchPathCache, cachekey);
338-
339-
if (!entry)
343+
if (LastSearchPathCacheEntry &&
344+
LastSearchPathCacheEntry->key.roleid == roleid &&
345+
strcmp(LastSearchPathCacheEntry->key.searchPath, searchPath) == 0)
340346
{
341-
bool found;
347+
return LastSearchPathCacheEntry;
348+
}
349+
else
350+
{
351+
SearchPathCacheEntry *entry;
352+
SearchPathCacheKey cachekey = {
353+
.searchPath = searchPath,
354+
.roleid = roleid
355+
};
342356

343-
cachekey.searchPath = MemoryContextStrdup(SearchPathCacheContext, searchPath);
344-
entry = nsphash_insert(SearchPathCache, cachekey, &found);
345-
Assert(!found);
357+
/*
358+
* searchPath is not saved in SearchPathCacheContext. First perform a
359+
* lookup, and copy searchPath only if we need to create a new entry.
360+
*/
361+
entry = nsphash_lookup(SearchPathCache, cachekey);
346362

347-
entry->oidlist = NIL;
348-
entry->finalPath = NIL;
349-
entry->firstNS = InvalidOid;
350-
entry->temp_missing = false;
351-
entry->forceRecompute = false;
352-
/* do not touch entry->status, used by simplehash */
353-
}
363+
if (!entry)
364+
{
365+
bool found;
366+
367+
cachekey.searchPath = MemoryContextStrdup(SearchPathCacheContext, searchPath);
368+
entry = nsphash_insert(SearchPathCache, cachekey, &found);
369+
Assert(!found);
370+
371+
entry->oidlist = NIL;
372+
entry->finalPath = NIL;
373+
entry->firstNS = InvalidOid;
374+
entry->temp_missing = false;
375+
entry->forceRecompute = false;
376+
/* do not touch entry->status, used by simplehash */
377+
}
354378

355-
return entry;
379+
LastSearchPathCacheEntry = entry;
380+
return entry;
381+
}
356382
}
357383

358384
/*

0 commit comments

Comments
 (0)