@@ -241,7 +241,8 @@ static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames,
241
241
*
242
242
* The search path cache is based on a wrapper around a simplehash hash table
243
243
* (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.
245
246
*/
246
247
247
248
static inline uint32
@@ -281,6 +282,7 @@ spcachekey_equal(SearchPathCacheKey a, SearchPathCacheKey b)
281
282
#define SPCACHE_RESET_THRESHOLD 256
282
283
283
284
static nsphash_hash * SearchPathCache = NULL ;
285
+ static SearchPathCacheEntry * LastSearchPathCacheEntry = NULL ;
284
286
285
287
/*
286
288
* Create or reset search_path cache as necessary.
@@ -295,6 +297,7 @@ spcache_init(void)
295
297
return ;
296
298
297
299
MemoryContextReset (SearchPathCacheContext );
300
+ LastSearchPathCacheEntry = NULL ;
298
301
/* arbitrary initial starting size of 16 elements */
299
302
SearchPathCache = nsphash_create (SearchPathCacheContext , 16 , NULL );
300
303
searchPathCacheValid = true;
@@ -307,12 +310,25 @@ spcache_init(void)
307
310
static SearchPathCacheEntry *
308
311
spcache_lookup (const char * searchPath , Oid roleid )
309
312
{
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 );
314
328
315
- return nsphash_lookup (SearchPathCache , cachekey );
329
+ LastSearchPathCacheEntry = entry ;
330
+ return entry ;
331
+ }
316
332
}
317
333
318
334
/*
@@ -324,35 +340,45 @@ spcache_lookup(const char *searchPath, Oid roleid)
324
340
static SearchPathCacheEntry *
325
341
spcache_insert (const char * searchPath , Oid roleid )
326
342
{
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 )
340
346
{
341
- bool found ;
347
+ return LastSearchPathCacheEntry ;
348
+ }
349
+ else
350
+ {
351
+ SearchPathCacheEntry * entry ;
352
+ SearchPathCacheKey cachekey = {
353
+ .searchPath = searchPath ,
354
+ .roleid = roleid
355
+ };
342
356
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 );
346
362
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
+ }
354
378
355
- return entry ;
379
+ LastSearchPathCacheEntry = entry ;
380
+ return entry ;
381
+ }
356
382
}
357
383
358
384
/*
0 commit comments