Skip to content

Commit a86c61c

Browse files
committed
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 b14b1eb commit a86c61c

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)