v18-0002-Use-fasthash-for-guc_name_hash.patch
text/x-patch
Filename: v18-0002-Use-fasthash-for-guc_name_hash.patch
Type: text/x-patch
Part: 1
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v18-0002
Subject: Use fasthash for guc_name_hash
| File | + | − |
|---|---|---|
| src/backend/utils/misc/guc.c | 27 | 9 |
From aa8d1f727b20f65b0506380c318ee823c0657849 Mon Sep 17 00:00:00 2001
From: John Naylor <john.naylor@postgresql.org>
Date: Sun, 21 Jan 2024 17:49:22 +0700
Subject: [PATCH v18 2/3] Use fasthash for guc_name_hash
---
src/backend/utils/misc/guc.c | 36 +++++++++++++++++++++++++++---------
1 file changed, 27 insertions(+), 9 deletions(-)
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 8f65ef3d89..67859baf69 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -33,6 +33,7 @@
#include "catalog/objectaccess.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_parameter_acl.h"
+#include "common/hashfn_unstable.h"
#include "guc_internal.h"
#include "libpq/pqformat.h"
#include "parser/scansup.h"
@@ -1324,22 +1325,39 @@ guc_name_compare(const char *namea, const char *nameb)
static uint32
guc_name_hash(const void *key, Size keysize)
{
- uint32 result = 0;
const char *name = *(const char *const *) key;
+ const char *const start = name;
+ fasthash_state hs;
+
+ fasthash_init(&hs, 0);
while (*name)
{
- char ch = *name++;
+ int chunk_len = 0;
- /* Case-fold in the same way as guc_name_compare */
- if (ch >= 'A' && ch <= 'Z')
- ch += 'a' - 'A';
+ while (chunk_len < FH_SIZEOF_ACCUM && name[chunk_len] != '\0')
+ {
+ chunk_len++;
+ hs.accum <<= BITS_PER_BYTE;
+ hs.accum |= name[chunk_len];
+ }
- /* Merge into hash ... not very bright, but it needn't be */
- result = pg_rotate_left32(result, 5);
- result ^= (uint32) ch;
+ /*
+ * Quick ASCII-only downcasing. Note: This effectively pads spaces
+ * when the input is not a multiple of 8. This would be okay even if
+ * space were a valid name character, since the actual length acts as
+ * a tiebreaker for the finalizer.
+ */
+ hs.accum |= 0x2020202020202020;
+
+ /* merge into hash and reset for next iteration */
+ fasthash_combine(&hs);
+ hs.accum = 0;
+
+ name += chunk_len;
}
- return result;
+
+ return fasthash_final32(&hs, name - start);
}
/*
--
2.43.0