@@ -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
247248static inline uint32
@@ -281,6 +282,7 @@ spcachekey_equal(SearchPathCacheKey a, SearchPathCacheKey b)
281282#define SPCACHE_RESET_THRESHOLD 256
282283
283284static 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)
307310static SearchPathCacheEntry *
308311spcache_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)
324340static SearchPathCacheEntry *
325341spcache_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