67 lines
2.2 KiB
Diff
67 lines
2.2 KiB
Diff
From d295e4b1da6d223242eb43bfae10479616c5236d Mon Sep 17 00:00:00 2001
|
|
From: Pauli <pauli@openssl.org>
|
|
Date: Fri, 20 May 2022 10:15:55 +1000
|
|
Subject: [PATCH] performance: improve ossl_lh_strcasehash
|
|
|
|
This improvement seems to roughly halve the time it takes to run the
|
|
ossl_lh_strcasehash function.
|
|
|
|
It should have no impact on the strings we hash and search for often (algorithm
|
|
names, property strings).
|
|
|
|
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
|
|
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
|
(Merged from https://github.com/openssl/openssl/pull/18354)
|
|
|
|
(cherry picked from commit a4e21d18d5b7cb4fef66c10f13b1b3b55945439f)
|
|
---
|
|
crypto/lhash/lhash.c | 21 ++++++++++++++++++++-
|
|
1 file changed, 20 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/crypto/lhash/lhash.c b/crypto/lhash/lhash.c
|
|
index 1cd988f01f..c319a44c7b 100644
|
|
--- a/crypto/lhash/lhash.c
|
|
+++ b/crypto/lhash/lhash.c
|
|
@@ -344,18 +344,37 @@ unsigned long OPENSSL_LH_strhash(const char *c)
|
|
return (ret >> 16) ^ ret;
|
|
}
|
|
|
|
+/*
|
|
+ * Case insensitive string hashing.
|
|
+ *
|
|
+ * The lower/upper case bit is masked out (forcing all letters to be capitals).
|
|
+ * The major side effect on non-alpha characters is mapping the symbols and
|
|
+ * digits into the control character range (which should be harmless).
|
|
+ * The duplication (with respect to the hash value) of printable characters
|
|
+ * are that '`', '{', '|', '}' and '~' map to '@', '[', '\', ']' and '^'
|
|
+ * respectively (which seems tolerable).
|
|
+ *
|
|
+ * For EBCDIC, the alpha mapping is to lower case, most symbols go to control
|
|
+ * characters. The only duplication is '0' mapping to '^', which is better
|
|
+ * than for ASCII.
|
|
+ */
|
|
unsigned long ossl_lh_strcasehash(const char *c)
|
|
{
|
|
unsigned long ret = 0;
|
|
long n;
|
|
unsigned long v;
|
|
int r;
|
|
+#if defined(CHARSET_EBCDIC) && !defined(CHARSET_EBCDIC_TEST)
|
|
+ const long int case_adjust = ~0x40;
|
|
+#else
|
|
+ const long int case_adjust = ~0x20;
|
|
+#endif
|
|
|
|
if (c == NULL || *c == '\0')
|
|
return ret;
|
|
|
|
for (n = 0x100; *c != '\0'; n += 0x100) {
|
|
- v = n | ossl_tolower(*c);
|
|
+ v = n | (case_adjust & *c);
|
|
r = (int)((v >> 2) ^ v) & 0x0f;
|
|
/* cast to uint64_t to avoid 32 bit shift of 32 bit value */
|
|
ret = (ret << r) | (unsigned long)((uint64_t)ret >> (32 - r));
|
|
--
|
|
2.33.0
|
|
|