Yesterday I did:
>       Rename module hash-pjw to hashcode-string.

It's not that easy: We have 3 different implementations of hash codes
for strings:
  (1) glibc/intl/hash-string.[hc] = gettext-runtime/intl/hash-string.[hc]
  (2) inside lib/hash.c
  (3) in lib/hashcode-string.[hc].

I don't want to change the implementation of any of these; each package
has validated the performance of their existing choice.

Ideally, (2) and (3) should be available upon request, each through
a specific header file, so that the programmer can pick the one they
prefer.

Also (2) conflicts with (1), since both define a function named 'hash_string'.
Therefore (2) should be omittable through an --avoid option. That means,
(2) should really be a separate module.

Done through these patches.


2025-04-30  Bruno Haible  <br...@clisp.org>

        New module hashcode-string1.
        * lib/hashcode-string1.h: New file.
        * lib/hashcode-string1.c: New file, based on lib/hash.c.
        * modules/hashcode-string1: New file.
        * lib/hash.h: Include hashcode-string1.h.
        (hash_string): Remove declaration.
        * lib/hash.c (hash_string): Remove function.
        * modules/hash (Depends-on): Add hashcode-string1.
        * lib/exclude.c: Include hashcode-string1.h.
        * modules/exclude (Depends-on): Add hashcode-string1.

2025-04-30  Bruno Haible  <br...@clisp.org>

        Rename module hashcode-string to hashcode-string2.
        * lib/hashcode-string2.h: Renamed from lib/hashcode-string.h.
        * lib/hashcode-string2.c: Renamed from lib/hashcode-string.c.
        * modules/hashcode-string2: Renamed from modules/hashcode-string.
        * MODULES.html.sh: Update.
        * top/maint.mk: Update.
        * lib/hash-pjw.h: Update.
        * modules/hash-pjw: Update.
        * lib/hashcode-named-file.c: Update.
        * modules/hashcode-named-file (Depends-on): Update.
        * tests/test-hash.c: Update.
        * modules/hash-tests (Depends-on): Update.

2025-04-30  Bruno Haible  <br...@clisp.org>

        clean-temp: Fix link error (regression yesterday).
        * lib/clean-temp.c: Include hashkey-string.h.
        (create_temp_dir): Use hashkey_string_* functions instead of
        clean_temp_string_*.
        * lib/clean-temp-private.h (clean_temp_string_equals,
        clean_temp_string_hash): Remove declarations.
        * modules/clean-temp (Depends-on): Add hashkey-string.

2025-04-30  Bruno Haible  <br...@clisp.org>

        hashcode-named-file: Fix mistake (regression yesterday).
        * lib/hash-triple.h: Include the correct header.

>From 0b6939d6ac1f6e4158772522fc2a0f2ae254e930 Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
Date: Wed, 30 Apr 2025 12:24:49 +0200
Subject: [PATCH 1/4] hashcode-named-file: Fix mistake (regression yesterday).

* lib/hash-triple.h: Include the correct header.
---
 ChangeLog         | 5 +++++
 lib/hash-triple.h | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index fc772d1f95..810d6af489 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2025-04-30  Bruno Haible  <br...@clisp.org>
+
+	hashcode-named-file: Fix mistake (regression yesterday).
+	* lib/hash-triple.h: Include the correct header.
+
 2025-04-30  Bruno Haible  <br...@clisp.org>
 
 	obstack: Make it easier to sync back with glibc.
diff --git a/lib/hash-triple.h b/lib/hash-triple.h
index 708835f22f..72f9ee6b51 100644
--- a/lib/hash-triple.h
+++ b/lib/hash-triple.h
@@ -14,7 +14,7 @@
    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
 
-#include "hashcode-string.h"
+#include "hashcode-file.h"
 
 #if __GNUC__ || (__clang_major__ >= 4)
 # warning "The include file hash-triple.h is deprecated. Use hashcode-file.h instead."
-- 
2.43.0

>From f47c5f2e21d0ccedb271b406e35b6963b23a64c4 Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
Date: Wed, 30 Apr 2025 13:11:01 +0200
Subject: [PATCH 2/4] clean-temp: Fix link error (regression yesterday).

* lib/clean-temp.c: Include hashkey-string.h.
(create_temp_dir): Use hashkey_string_* functions instead of
clean_temp_string_*.
* lib/clean-temp-private.h (clean_temp_string_equals,
clean_temp_string_hash): Remove declarations.
* modules/clean-temp (Depends-on): Add hashkey-string.
---
 ChangeLog                | 10 ++++++++++
 lib/clean-temp-private.h |  3 ---
 lib/clean-temp.c         |  5 +++--
 modules/clean-temp       |  1 +
 4 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 810d6af489..4d3ba4d7b8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2025-04-30  Bruno Haible  <br...@clisp.org>
+
+	clean-temp: Fix link error (regression yesterday).
+	* lib/clean-temp.c: Include hashkey-string.h.
+	(create_temp_dir): Use hashkey_string_* functions instead of
+	clean_temp_string_*.
+	* lib/clean-temp-private.h (clean_temp_string_equals,
+	clean_temp_string_hash): Remove declarations.
+	* modules/clean-temp (Depends-on): Add hashkey-string.
+
 2025-04-30  Bruno Haible  <br...@clisp.org>
 
 	hashcode-named-file: Fix mistake (regression yesterday).
diff --git a/lib/clean-temp-private.h b/lib/clean-temp-private.h
index f94c0d9192..468771b98e 100644
--- a/lib/clean-temp-private.h
+++ b/lib/clean-temp-private.h
@@ -68,9 +68,6 @@ struct closeable_fd
 #define descriptors clean_temp_descriptors
 extern gl_list_t /* <closeable_fd *> */ volatile descriptors;
 
-extern bool clean_temp_string_equals (const void *x1, const void *x2);
-extern size_t clean_temp_string_hash (const void *x);
-
 extern _GL_ASYNC_SAFE int clean_temp_asyncsafe_close (struct closeable_fd *element);
 extern void clean_temp_init_asyncsafe_close (void);
 
diff --git a/lib/clean-temp.c b/lib/clean-temp.c
index 5d85e4c848..f477e7719e 100644
--- a/lib/clean-temp.c
+++ b/lib/clean-temp.c
@@ -45,6 +45,7 @@
 #include "xmalloca.h"
 #include "glthread/lock.h"
 #include "thread-optim.h"
+#include "hashkey-string.h"
 #include "gl_xlist.h"
 #include "gl_linkedhash_list.h"
 #include "gl_linked_list.h"
@@ -219,11 +220,11 @@ create_temp_dir (const char *prefix, const char *parentdir,
   tmpdir->cleanup_verbose = cleanup_verbose;
   tmpdir->subdirs =
     gl_list_create_empty (GL_LINKEDHASH_LIST,
-                          clean_temp_string_equals, clean_temp_string_hash,
+                          hashkey_string_equals, hashkey_string_hash,
                           NULL, false);
   tmpdir->files =
     gl_list_create_empty (GL_LINKEDHASH_LIST,
-                          clean_temp_string_equals, clean_temp_string_hash,
+                          hashkey_string_equals, hashkey_string_hash,
                           NULL, false);
 
   /* Create the temporary directory.  */
diff --git a/modules/clean-temp b/modules/clean-temp
index 1b0dfd349c..bb36caec99 100644
--- a/modules/clean-temp
+++ b/modules/clean-temp
@@ -24,6 +24,7 @@ rmdir
 xalloc
 xalloc-die
 xmalloca
+hashkey-string
 linkedhash-list
 linked-list
 xlist
-- 
2.43.0

>From a7785e699ab31dc0d2a51b8dbdedde4e82389201 Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
Date: Wed, 30 Apr 2025 12:28:42 +0200
Subject: [PATCH 3/4] Rename module hashcode-string to hashcode-string2.

* lib/hashcode-string2.h: Renamed from lib/hashcode-string.h.
* lib/hashcode-string2.c: Renamed from lib/hashcode-string.c.
* modules/hashcode-string2: Renamed from modules/hashcode-string.
* MODULES.html.sh: Update.
* top/maint.mk: Update.
* lib/hash-pjw.h: Update.
* modules/hash-pjw: Update.
* lib/hashcode-named-file.c: Update.
* modules/hashcode-named-file (Depends-on): Update.
* tests/test-hash.c: Update.
* modules/hash-tests (Depends-on): Update.
---
 ChangeLog                                     | 15 +++++++++++++++
 MODULES.html.sh                               |  2 +-
 lib/hash-pjw.h                                |  4 ++--
 lib/hashcode-named-file.c                     |  2 +-
 lib/{hashcode-string.c => hashcode-string2.c} |  4 ++--
 lib/{hashcode-string.h => hashcode-string2.h} |  2 +-
 modules/hash-pjw                              |  6 +++---
 modules/hash-tests                            |  2 +-
 modules/hashcode-named-file                   |  2 +-
 modules/{hashcode-string => hashcode-string2} |  8 ++++----
 tests/test-hash.c                             |  2 +-
 top/maint.mk                                  |  4 ++--
 12 files changed, 34 insertions(+), 19 deletions(-)
 rename lib/{hashcode-string.c => hashcode-string2.c} (91%)
 rename lib/{hashcode-string.h => hashcode-string2.h} (95%)
 rename modules/{hashcode-string => hashcode-string2} (60%)

diff --git a/ChangeLog b/ChangeLog
index 4d3ba4d7b8..8d8567413b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2025-04-30  Bruno Haible  <br...@clisp.org>
+
+	Rename module hashcode-string to hashcode-string2.
+	* lib/hashcode-string2.h: Renamed from lib/hashcode-string.h.
+	* lib/hashcode-string2.c: Renamed from lib/hashcode-string.c.
+	* modules/hashcode-string2: Renamed from modules/hashcode-string.
+	* MODULES.html.sh: Update.
+	* top/maint.mk: Update.
+	* lib/hash-pjw.h: Update.
+	* modules/hash-pjw: Update.
+	* lib/hashcode-named-file.c: Update.
+	* modules/hashcode-named-file (Depends-on): Update.
+	* tests/test-hash.c: Update.
+	* modules/hash-tests (Depends-on): Update.
+
 2025-04-30  Bruno Haible  <br...@clisp.org>
 
 	clean-temp: Fix link error (regression yesterday).
diff --git a/MODULES.html.sh b/MODULES.html.sh
index baee4f95fd..d57d76531e 100755
--- a/MODULES.html.sh
+++ b/MODULES.html.sh
@@ -2095,7 +2095,7 @@ func_all_modules ()
   func_module obstack
   func_module obstack-printf
   func_module obstack-printf-posix
-  func_module hashcode-string
+  func_module hashcode-string2
   func_module hashcode-mem
   func_module hash
   func_module hamt
diff --git a/lib/hash-pjw.h b/lib/hash-pjw.h
index 14af42a891..0b143f2934 100644
--- a/lib/hash-pjw.h
+++ b/lib/hash-pjw.h
@@ -14,8 +14,8 @@
    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
 
-#include "hashcode-string.h"
+#include "hashcode-string2.h"
 
 #if __GNUC__ || (__clang_major__ >= 4)
-# warning "The include file hash-pjw.h is deprecated. Use hashcode-string.h instead."
+# warning "The include file hash-pjw.h is deprecated. Use hashcode-string2.h instead."
 #endif
diff --git a/lib/hashcode-named-file.c b/lib/hashcode-named-file.c
index a488147edd..1611cb5138 100644
--- a/lib/hashcode-named-file.c
+++ b/lib/hashcode-named-file.c
@@ -24,7 +24,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "hashcode-string.h"
+#include "hashcode-string2.h"
 #include "same-inode.h"
 
 #define STREQ(a, b) (strcmp (a, b) == 0)
diff --git a/lib/hashcode-string.c b/lib/hashcode-string2.c
similarity index 91%
rename from lib/hashcode-string.c
rename to lib/hashcode-string2.c
index 6943d7b17b..5a44762723 100644
--- a/lib/hashcode-string.c
+++ b/lib/hashcode-string2.c
@@ -1,4 +1,4 @@
-/* hashcode-string.c -- compute a hash value from a NUL-terminated string.
+/* hashcode-string2.c -- compute a hash value from a NUL-terminated string.
 
    Copyright (C) 2001, 2003, 2006, 2009-2025 Free Software Foundation, Inc.
 
@@ -18,7 +18,7 @@
 #include <config.h>
 
 /* Specification.  */
-#include "hashcode-string.h"
+#include "hashcode-string2.h"
 
 #include <limits.h>
 
diff --git a/lib/hashcode-string.h b/lib/hashcode-string2.h
similarity index 95%
rename from lib/hashcode-string.h
rename to lib/hashcode-string2.h
index af99f4e74c..9c10951222 100644
--- a/lib/hashcode-string.h
+++ b/lib/hashcode-string2.h
@@ -1,4 +1,4 @@
-/* hashcode-string.h -- declaration for a simple hash function
+/* hashcode-string2.h -- declaration for a simple hash function
    Copyright (C) 2001, 2003, 2009-2025 Free Software Foundation, Inc.
 
    This file is free software: you can redistribute it and/or modify
diff --git a/modules/hash-pjw b/modules/hash-pjw
index 56193fa2d1..d1905ed4f2 100644
--- a/modules/hash-pjw
+++ b/modules/hash-pjw
@@ -5,19 +5,19 @@ Status:
 deprecated
 
 Notice:
-This module is deprecated. Use the module 'hashcode-string' instead.
+This module is deprecated. Use the module 'hashcode-string2' instead.
 
 Files:
 
 Depends-on:
-hashcode-string
+hashcode-string2
 
 configure.ac:
 
 Makefile.am:
 
 Include:
-"hashcode-string.h"
+"hashcode-string2.h"
 
 License:
 LGPLv2+
diff --git a/modules/hash-tests b/modules/hash-tests
index c9593f347d..b9f99d9900 100644
--- a/modules/hash-tests
+++ b/modules/hash-tests
@@ -3,7 +3,7 @@ tests/test-hash.c
 tests/macros.h
 
 Depends-on:
-hashcode-string
+hashcode-string2
 inttostr
 bool
 
diff --git a/modules/hashcode-named-file b/modules/hashcode-named-file
index bdc68502f8..7e5eebf763 100644
--- a/modules/hashcode-named-file
+++ b/modules/hashcode-named-file
@@ -7,7 +7,7 @@ lib/hashcode-file.h
 lib/hash-triple.h
 
 Depends-on:
-hashcode-string
+hashcode-string2
 same-inode
 bool
 
diff --git a/modules/hashcode-string b/modules/hashcode-string2
similarity index 60%
rename from modules/hashcode-string
rename to modules/hashcode-string2
index a9484514db..7a26702471 100644
--- a/modules/hashcode-string
+++ b/modules/hashcode-string2
@@ -2,8 +2,8 @@ Description:
 Compute a hash value for a NUL-terminated string.
 
 Files:
-lib/hashcode-string.h
-lib/hashcode-string.c
+lib/hashcode-string2.h
+lib/hashcode-string2.c
 lib/hash-pjw.h
 
 Depends-on:
@@ -11,10 +11,10 @@ Depends-on:
 configure.ac:
 
 Makefile.am:
-lib_SOURCES += hashcode-string.h hashcode-string.c
+lib_SOURCES += hashcode-string2.h hashcode-string2.c
 
 Include:
-"hashcode-string.h"
+"hashcode-string2.h"
 
 License:
 LGPLv2+
diff --git a/tests/test-hash.c b/tests/test-hash.c
index e7735684be..78a1bff37c 100644
--- a/tests/test-hash.c
+++ b/tests/test-hash.c
@@ -18,7 +18,7 @@
 #include <config.h>
 
 #include "hash.h"
-#include "hashcode-string.h"
+#include "hashcode-string2.h"
 #include "inttostr.h"
 
 #include <stdio.h>
diff --git a/top/maint.mk b/top/maint.mk
index a5392fc938..e03e887cba 100644
--- a/top/maint.mk
+++ b/top/maint.mk
@@ -728,8 +728,8 @@ sc_prohibit_posixver_without_use:
 sc_prohibit_same_without_use:
 	@h='same.h' re='\<same_name(at)? *\(' $(_sc_header_without_use)
 
-sc_prohibit_hashcode_string_without_use:
-	@h='hashcode-string.h' \
+sc_prohibit_hashcode_string2_without_use:
+	@h='hashcode-string2.h' \
 	re='\<hash_pjw\>' \
 	  $(_sc_header_without_use)
 
-- 
2.43.0

>From 64042bb91aea5f854ca8a8938e2b3f7d1935e4f1 Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
Date: Wed, 30 Apr 2025 12:47:37 +0200
Subject: [PATCH 4/4] New module hashcode-string1.

* lib/hashcode-string1.h: New file.
* lib/hashcode-string1.c: New file, based on lib/hash.c.
* modules/hashcode-string1: New file.
* lib/hash.h: Include hashcode-string1.h.
(hash_string): Remove declaration.
* lib/hash.c (hash_string): Remove function.
* modules/hash (Depends-on): Add hashcode-string1.
* lib/exclude.c: Include hashcode-string1.h.
* modules/exclude (Depends-on): Add hashcode-string1.
---
 ChangeLog                | 13 +++++++++
 lib/exclude.c            |  1 +
 lib/hash.c               | 59 ++++++--------------------------------
 lib/hash.h               | 11 +++----
 lib/hashcode-string1.c   | 62 ++++++++++++++++++++++++++++++++++++++++
 lib/hashcode-string1.h   | 38 ++++++++++++++++++++++++
 modules/exclude          |  1 +
 modules/hash             |  1 +
 modules/hashcode-string1 | 24 ++++++++++++++++
 9 files changed, 154 insertions(+), 56 deletions(-)
 create mode 100644 lib/hashcode-string1.c
 create mode 100644 lib/hashcode-string1.h
 create mode 100644 modules/hashcode-string1

diff --git a/ChangeLog b/ChangeLog
index 8d8567413b..463cd83a9c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2025-04-30  Bruno Haible  <br...@clisp.org>
+
+	New module hashcode-string1.
+	* lib/hashcode-string1.h: New file.
+	* lib/hashcode-string1.c: New file, based on lib/hash.c.
+	* modules/hashcode-string1: New file.
+	* lib/hash.h: Include hashcode-string1.h.
+	(hash_string): Remove declaration.
+	* lib/hash.c (hash_string): Remove function.
+	* modules/hash (Depends-on): Add hashcode-string1.
+	* lib/exclude.c: Include hashcode-string1.h.
+	* modules/exclude (Depends-on): Add hashcode-string1.
+
 2025-04-30  Bruno Haible  <br...@clisp.org>
 
 	Rename module hashcode-string to hashcode-string2.
diff --git a/lib/exclude.c b/lib/exclude.c
index 485beb64f5..cdc57d9df8 100644
--- a/lib/exclude.c
+++ b/lib/exclude.c
@@ -36,6 +36,7 @@
 #include "filename.h"
 #include <fnmatch.h>
 #include "hash.h"
+#include "hashcode-string1.h"
 #if GNULIB_MCEL_PREFER
 # include "mcel.h"
 #else
diff --git a/lib/hash.c b/lib/hash.c
index fd761730b1..f5518a7f43 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -345,57 +345,6 @@ hash_do_for_each (const Hash_table *table, Hash_processor processor,
   return counter;
 }
 
-/* Allocation and clean-up.  */
-
-#if USE_DIFF_HASH
-
-/* About hashings, Paul Eggert writes to me (FP), on 1994-01-01: "Please see
-   B. J. McKenzie, R. Harries & T. Bell, Selecting a hashing algorithm,
-   Software--practice & experience 20, 2 (Feb 1990), 209-224.  Good hash
-   algorithms tend to be domain-specific, so what's good for [diffutils'] io.c
-   may not be good for your application."  */
-
-size_t
-hash_string (const char *string, size_t n_buckets)
-{
-# define HASH_ONE_CHAR(Value, Byte) \
-  ((Byte) + rotl_sz (Value, 7))
-
-  size_t value = 0;
-  unsigned char ch;
-
-  for (; (ch = *string); string++)
-    value = HASH_ONE_CHAR (value, ch);
-  return value % n_buckets;
-
-# undef HASH_ONE_CHAR
-}
-
-#else /* not USE_DIFF_HASH */
-
-/* This one comes from 'recode', and performs a bit better than the above as
-   per a few experiments.  It is inspired from a hashing routine found in the
-   very old Cyber 'snoop', itself written in typical Greg Mansfield style.
-   (By the way, what happened to this excellent man?  Is he still alive?)  */
-
-size_t
-hash_string (const char *string, size_t n_buckets)
-{
-  size_t value = 0;
-  unsigned char ch;
-
-  for (; (ch = *string); string++)
-    value = (value * 31 + ch) % n_buckets;
-  return value;
-}
-
-#endif /* not USE_DIFF_HASH */
-
-void
-hash_reset_tuning (Hash_tuning *tuning)
-{
-  *tuning = default_tuning;
-}
 
 /* If the user passes a NULL hasher, we hash the raw pointer.  */
 static size_t
@@ -418,6 +367,14 @@ raw_comparator (const void *a, const void *b)
 }
 
 
+/* Allocation and clean-up.  */
+
+void
+hash_reset_tuning (Hash_tuning *tuning)
+{
+  *tuning = default_tuning;
+}
+
 /* For the given hash TABLE, check the user supplied tuning structure for
    reasonable values, and return true if there is no gross error with it.
    Otherwise, definitively reset the TUNING field to some acceptable default
diff --git a/lib/hash.h b/lib/hash.h
index 3cff33244f..626880a125 100644
--- a/lib/hash.h
+++ b/lib/hash.h
@@ -130,11 +130,6 @@ typedef bool (*Hash_processor) (void *entry, void *processor_data);
 extern size_t hash_do_for_each (const Hash_table *table,
                                 Hash_processor processor, void *processor_data);
 
-/* Return a hash index for a NUL-terminated STRING between 0 and N_BUCKETS-1.
-   This is a convenience routine for constructing other hashing functions.  */
-extern size_t hash_string (const char *string, size_t n_buckets)
-       _GL_ATTRIBUTE_PURE;
-
 /* Return a hash code of ENTRY, in the range 0..TABLE_SIZE-1.
    This hash code function must have the property that if the comparator of
    ENTRY1 and ENTRY2 returns true, the hasher returns the same value for ENTRY1
@@ -276,6 +271,12 @@ extern int hash_insert_if_absent (Hash_table *table, const void *entry,
    table, don't modify the table and return NULL.  */
 extern void *hash_remove (Hash_table *table, const void *entry);
 
+
+# if GNULIB_HASHCODE_STRING1
+/* Include declarations of module 'hashcode-string1'.  */
+#  include "hashcode-string1.h"
+# endif
+
 # ifdef __cplusplus
 }
 # endif
diff --git a/lib/hashcode-string1.c b/lib/hashcode-string1.c
new file mode 100644
index 0000000000..84d6ccf2fc
--- /dev/null
+++ b/lib/hashcode-string1.c
@@ -0,0 +1,62 @@
+/* hashcode-string1.c -- compute a hash value from a NUL-terminated string.
+
+   Copyright (C) 1998-2004, 2006-2007, 2009-2025 Free Software Foundation, Inc.
+
+   This file is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   This file is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "hashcode-string1.h"
+
+#if USE_DIFF_HASH
+
+# include "bitrotate.h"
+
+/* About hashings, Paul Eggert writes to me (FP), on 1994-01-01: "Please see
+   B. J. McKenzie, R. Harries & T. Bell, Selecting a hashing algorithm,
+   Software--practice & experience 20, 2 (Feb 1990), 209-224.  Good hash
+   algorithms tend to be domain-specific, so what's good for [diffutils'] io.c
+   may not be good for your application."  */
+
+size_t
+hash_string (const char *string, size_t tablesize)
+{
+  size_t value = 0;
+  unsigned char ch;
+
+  for (; (ch = *string); string++)
+    value = ch + rotl_sz (value, 7);
+  return value % tablesize;
+}
+
+#else /* not USE_DIFF_HASH */
+
+/* This one comes from 'recode', and performs a bit better than the above as
+   per a few experiments.  It is inspired from a hashing routine found in the
+   very old Cyber 'snoop', itself written in typical Greg Mansfield style.
+   (By the way, what happened to this excellent man?  Is he still alive?)  */
+
+size_t
+hash_string (const char *string, size_t tablesize)
+{
+  size_t value = 0;
+  unsigned char ch;
+
+  for (; (ch = *string); string++)
+    value = (value * 31 + ch) % tablesize;
+  return value;
+}
+
+#endif /* not USE_DIFF_HASH */
diff --git a/lib/hashcode-string1.h b/lib/hashcode-string1.h
new file mode 100644
index 0000000000..3eb7ba0b3c
--- /dev/null
+++ b/lib/hashcode-string1.h
@@ -0,0 +1,38 @@
+/* hashcode-string1.h -- declaration for a simple hash function
+   Copyright (C) 1998-2004, 2006-2007, 2009-2025 Free Software Foundation, Inc.
+
+   This file is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   This file is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* This file uses _GL_ATTRIBUTE_PURE.  */
+#if !_GL_CONFIG_H_INCLUDED
+ #error "Please include config.h first."
+#endif
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Compute a hash code for a NUL-terminated string S,
+   and return the hash code modulo TABLESIZE.
+   The result is platform dependent: it depends on the size of the 'size_t'
+   type.  */
+extern size_t hash_string (char const *s, size_t tablesize) _GL_ATTRIBUTE_PURE;
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/exclude b/modules/exclude
index 5defb0aa0c..3f2491bc49 100644
--- a/modules/exclude
+++ b/modules/exclude
@@ -12,6 +12,7 @@ filename
 fnmatch
 fopen-gnu
 hash
+hashcode-string1
 mbscasecmp
 mbuiter               [test "$GNULIB_MCEL_PREFER" != yes]
 nullptr
diff --git a/modules/hash b/modules/hash
index fa1b9852a5..60ec6b4b56 100644
--- a/modules/hash
+++ b/modules/hash
@@ -14,6 +14,7 @@ next-prime
 bool
 stdint-h
 xalloc-oversized
+hashcode-string1
 
 configure.ac:
 
diff --git a/modules/hashcode-string1 b/modules/hashcode-string1
new file mode 100644
index 0000000000..49cf3f3fbe
--- /dev/null
+++ b/modules/hashcode-string1
@@ -0,0 +1,24 @@
+Description:
+Compute a hash value for a NUL-terminated string.
+
+Files:
+lib/hashcode-string1.h
+lib/hashcode-string1.c
+
+Depends-on:
+bitrotate
+
+configure.ac:
+gl_MODULE_INDICATOR([hashcode-string1])
+
+Makefile.am:
+lib_SOURCES += hashcode-string1.h hashcode-string1.c
+
+Include:
+"hashcode-string1.h"
+
+License:
+LGPLv2+
+
+Maintainer:
+Jim Meyering
-- 
2.43.0

Reply via email to