From eacb3fccb25c10696334def8a8346257958ec3dd Mon Sep 17 00:00:00 2001 From: John Naylor Date: Sun, 10 Dec 2023 15:14:24 +0700 Subject: [PATCH v9 4/6] Assert that incremental fasthash variants give the same answer as the original Test that incremental hashing gives the right answer for strings. Use the initial length only for the init step. Test that we can ignore the length afterwards, and only use the presence of the NUL terminator to stop iterating. Assert that this results in the same hash. Based on "Use new hash APIs for search path cache" by Jeff Davis, rebased over v7. --- src/backend/catalog/namespace.c | 48 ++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index 5027efc91d..6bb28aecfc 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -41,7 +41,7 @@ #include "catalog/pg_ts_template.h" #include "catalog/pg_type.h" #include "commands/dbcommands.h" -#include "common/hashfn.h" +#include "common/hashfn_unstable.h" #include "funcapi.h" #include "mb/pg_wchar.h" #include "miscadmin.h" @@ -247,11 +247,51 @@ static bool MatchNamedCall(HeapTuple proctup, int nargs, List *argnames, static inline uint32 spcachekey_hash(SearchPathCacheKey key) { - const unsigned char *bytes = (const unsigned char *) key.searchPath; + const char *buf = key.searchPath; + fasthash_state hs; + + // XXX not for commit +#ifdef USE_ASSERT_CHECKING int blen = strlen(key.searchPath); - return hash_combine(hash_bytes(bytes, blen), - hash_uint32(key.roleid)); + uint64 h_orig = fasthash64_orig(buf, blen, key.roleid); + + // check full function that calls incremental interface + Assert(fasthash64((const unsigned char *) buf, blen, key.roleid) == h_orig); + + // Test that chunked interface can give the same answer, + // if we have length up front. We would typically use it + // for cases where we don't know, but let's try to make + // it as similar as conveniently possible. + fasthash_init(&hs, blen, key.roleid); + while (*buf) + { + int chunk_len = 0; + + while(chunk_len < FH_SIZEOF_ACCUM && buf[chunk_len] != '\0') + chunk_len++; + + fasthash_accum(&hs, (const unsigned char *) buf, chunk_len); + buf += chunk_len; + } + Assert(fasthash_final64(&hs) == h_orig); + buf = key.searchPath; /* reset */ +#endif + + // WIP: maybe roleid should be mixed in normally + // WIP: For now fake the length to preserve the internal seed + fasthash_init(&hs, 1, key.roleid); + while (*buf) + { + int chunk_len = 0; + + while(chunk_len < FH_SIZEOF_ACCUM && buf[chunk_len] != '\0') + chunk_len++; + + fasthash_accum(&hs, (const unsigned char *) buf, chunk_len); + buf += chunk_len; + } + return fasthash_final32(&hs); } static inline bool -- 2.43.0