Skip to content

Commit

Permalink
Optimize SearchPathCache by saving the last entry.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jeff-davis committed Dec 5, 2023
1 parent b14b1eb commit a86c61c
Showing 1 changed file with 57 additions and 31 deletions.
88 changes: 57 additions & 31 deletions src/backend/catalog/namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames,
*
* The search path cache is based on a wrapper around a simplehash hash table
* (nsphash, defined below). The spcache wrapper deals with OOM while trying
* to initialize a key, and also offers a more convenient API.
* to initialize a key, optimizes repeated lookups of the same key, and also
* offers a more convenient API.
*/

static inline uint32
Expand Down Expand Up @@ -281,6 +282,7 @@ spcachekey_equal(SearchPathCacheKey a, SearchPathCacheKey b)
#define SPCACHE_RESET_THRESHOLD 256

static nsphash_hash * SearchPathCache = NULL;
static SearchPathCacheEntry * LastSearchPathCacheEntry = NULL;

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

MemoryContextReset(SearchPathCacheContext);
LastSearchPathCacheEntry = NULL;
/* arbitrary initial starting size of 16 elements */
SearchPathCache = nsphash_create(SearchPathCacheContext, 16, NULL);
searchPathCacheValid = true;
Expand All @@ -307,12 +310,25 @@ spcache_init(void)
static SearchPathCacheEntry *
spcache_lookup(const char *searchPath, Oid roleid)
{
SearchPathCacheKey cachekey = {
.searchPath = searchPath,
.roleid = roleid
};
if (LastSearchPathCacheEntry &&
LastSearchPathCacheEntry->key.roleid == roleid &&
strcmp(LastSearchPathCacheEntry->key.searchPath, searchPath) == 0)
{
return LastSearchPathCacheEntry;
}
else
{
SearchPathCacheEntry *entry;
SearchPathCacheKey cachekey = {
.searchPath = searchPath,
.roleid = roleid
};

entry = nsphash_lookup(SearchPathCache, cachekey);

return nsphash_lookup(SearchPathCache, cachekey);
LastSearchPathCacheEntry = entry;
return entry;
}
}

/*
Expand All @@ -324,35 +340,45 @@ spcache_lookup(const char *searchPath, Oid roleid)
static SearchPathCacheEntry *
spcache_insert(const char *searchPath, Oid roleid)
{
SearchPathCacheEntry *entry;
SearchPathCacheKey cachekey = {
.searchPath = searchPath,
.roleid = roleid
};

/*
* searchPath is not saved in SearchPathCacheContext. First perform a
* lookup, and copy searchPath only if we need to create a new entry.
*/
entry = nsphash_lookup(SearchPathCache, cachekey);

if (!entry)
if (LastSearchPathCacheEntry &&
LastSearchPathCacheEntry->key.roleid == roleid &&
strcmp(LastSearchPathCacheEntry->key.searchPath, searchPath) == 0)
{
bool found;
return LastSearchPathCacheEntry;
}
else
{
SearchPathCacheEntry *entry;
SearchPathCacheKey cachekey = {
.searchPath = searchPath,
.roleid = roleid
};

cachekey.searchPath = MemoryContextStrdup(SearchPathCacheContext, searchPath);
entry = nsphash_insert(SearchPathCache, cachekey, &found);
Assert(!found);
/*
* searchPath is not saved in SearchPathCacheContext. First perform a
* lookup, and copy searchPath only if we need to create a new entry.
*/
entry = nsphash_lookup(SearchPathCache, cachekey);

entry->oidlist = NIL;
entry->finalPath = NIL;
entry->firstNS = InvalidOid;
entry->temp_missing = false;
entry->forceRecompute = false;
/* do not touch entry->status, used by simplehash */
}
if (!entry)
{
bool found;

cachekey.searchPath = MemoryContextStrdup(SearchPathCacheContext, searchPath);
entry = nsphash_insert(SearchPathCache, cachekey, &found);
Assert(!found);

entry->oidlist = NIL;
entry->finalPath = NIL;
entry->firstNS = InvalidOid;
entry->temp_missing = false;
entry->forceRecompute = false;
/* do not touch entry->status, used by simplehash */
}

return entry;
LastSearchPathCacheEntry = entry;
return entry;
}
}

/*
Expand Down

0 comments on commit a86c61c

Please sign in to comment.