This patch refactors the next_prime() function from hash.c, so that it can be
used in other hash table implementation. (Note that gl_anyhash_primes.h uses
another technique.)


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

        next-prime: Add tests.
        * tests/test-next-prime.c: New file.
        * modules/next-prime-tests: New file.

        New module next-prime.
        * lib/next-prime.h: New file, based on lib/hash.c.
        * lib/next-prime.c: New file, based on lib/hash.c.
        * modules/next-prime: New file.
        * lib/hash.c: Include next-prime.h.
        (is_prime, next_prime): Remove functions.
        * modules/hash (Depends-on): Add next-prime.

>From 0b953ba82830f51ce9b939700705d238f9b0c0ba Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
Date: Wed, 30 Apr 2025 01:52:17 +0200
Subject: [PATCH 1/2] New module next-prime.

* lib/next-prime.h: New file, based on lib/hash.c.
* lib/next-prime.c: New file, based on lib/hash.c.
* modules/next-prime: New file.
* lib/hash.c: Include next-prime.h.
(is_prime, next_prime): Remove functions.
* modules/hash (Depends-on): Add next-prime.
---
 ChangeLog          | 10 +++++++++
 lib/hash.c         | 39 +-------------------------------
 lib/next-prime.c   | 56 ++++++++++++++++++++++++++++++++++++++++++++++
 lib/next-prime.h   | 41 +++++++++++++++++++++++++++++++++
 modules/hash       |  1 +
 modules/next-prime | 24 ++++++++++++++++++++
 6 files changed, 133 insertions(+), 38 deletions(-)
 create mode 100644 lib/next-prime.c
 create mode 100644 lib/next-prime.h
 create mode 100644 modules/next-prime

diff --git a/ChangeLog b/ChangeLog
index 6314db2094..60fbb0c0d0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2025-04-29  Bruno Haible  <br...@clisp.org>
+
+	New module next-prime.
+	* lib/next-prime.h: New file, based on lib/hash.c.
+	* lib/next-prime.c: New file, based on lib/hash.c.
+	* modules/next-prime: New file.
+	* lib/hash.c: Include next-prime.h.
+	(is_prime, next_prime): Remove functions.
+	* modules/hash (Depends-on): Add next-prime.
+
 2025-04-29  Bruno Haible  <br...@clisp.org>
 
 	New module hashkey-string.
diff --git a/lib/hash.c b/lib/hash.c
index 556c82d5b8..74d016fde3 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -27,6 +27,7 @@
 #include "hash.h"
 
 #include "bitrotate.h"
+#include "next-prime.h"
 #include "xalloc-oversized.h"
 
 #include <errno.h>
@@ -390,44 +391,6 @@ hash_string (const char *string, size_t n_buckets)
 
 #endif /* not USE_DIFF_HASH */
 
-/* Return true if CANDIDATE is a prime number.  CANDIDATE should be an odd
-   number at least equal to 11.  */
-
-static bool _GL_ATTRIBUTE_CONST
-is_prime (size_t candidate)
-{
-  size_t divisor = 3;
-  size_t square = divisor * divisor;
-
-  while (square < candidate && (candidate % divisor))
-    {
-      divisor++;
-      square += 4 * divisor;
-      divisor++;
-    }
-
-  return (candidate % divisor ? true : false);
-}
-
-/* Round a given CANDIDATE number up to the nearest prime, and return that
-   prime.  Primes lower than 10 are merely skipped.  */
-
-static size_t _GL_ATTRIBUTE_CONST
-next_prime (size_t candidate)
-{
-  /* Skip small primes.  */
-  if (candidate < 10)
-    candidate = 10;
-
-  /* Make it definitely odd.  */
-  candidate |= 1;
-
-  while (SIZE_MAX != candidate && !is_prime (candidate))
-    candidate += 2;
-
-  return candidate;
-}
-
 void
 hash_reset_tuning (Hash_tuning *tuning)
 {
diff --git a/lib/next-prime.c b/lib/next-prime.c
new file mode 100644
index 0000000000..52cebc48d1
--- /dev/null
+++ b/lib/next-prime.c
@@ -0,0 +1,56 @@
+/* Finding the next prime >= a given small integer.
+   Copyright (C) 1995-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 "next-prime.h"
+
+#include <stdint.h> /* for SIZE_MAX */
+
+/* Return true if CANDIDATE is a prime number.  CANDIDATE should be an odd
+   number at least equal to 11.  */
+static bool _GL_ATTRIBUTE_CONST
+is_prime (size_t candidate)
+{
+  size_t divisor = 3;
+  size_t square = divisor * divisor;
+
+  while (square < candidate && (candidate % divisor))
+    {
+      divisor++;
+      square += 4 * divisor;
+      divisor++;
+    }
+
+  return (candidate % divisor ? true : false);
+}
+
+size_t _GL_ATTRIBUTE_CONST
+next_prime (size_t candidate)
+{
+  /* Skip small primes.  */
+  if (candidate < 10)
+    candidate = 10;
+
+  /* Make it definitely odd.  */
+  candidate |= 1;
+
+  while (SIZE_MAX != candidate && !is_prime (candidate))
+    candidate += 2;
+
+  return candidate;
+}
diff --git a/lib/next-prime.h b/lib/next-prime.h
new file mode 100644
index 0000000000..c5ab78e318
--- /dev/null
+++ b/lib/next-prime.h
@@ -0,0 +1,41 @@
+/* Finding the next prime >= a given small integer.
+   Copyright (C) 1995-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/>.  */
+
+#ifndef _GL_NEXT_PRIME_H
+#define _GL_NEXT_PRIME_H
+
+/* This file uses _GL_ATTRIBUTE_CONST.  */
+#if !_GL_CONFIG_H_INCLUDED
+ #error "Please include config.h first."
+#endif
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Round a given CANDIDATE number up to the nearest prime, and return that
+   prime.  Primes lower than 10 are merely skipped.  */
+extern size_t _GL_ATTRIBUTE_CONST next_prime (size_t candidate);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GL_NEXT_PRIME_H */
diff --git a/modules/hash b/modules/hash
index da477d8887..fa1b9852a5 100644
--- a/modules/hash
+++ b/modules/hash
@@ -10,6 +10,7 @@ bitrotate
 calloc-posix
 free-posix
 malloc-posix
+next-prime
 bool
 stdint-h
 xalloc-oversized
diff --git a/modules/next-prime b/modules/next-prime
new file mode 100644
index 0000000000..259db8846e
--- /dev/null
+++ b/modules/next-prime
@@ -0,0 +1,24 @@
+Description:
+Finding the next prime >= a given small integer.
+
+Files:
+lib/next-prime.h
+lib/next-prime.c
+
+Depends-on:
+bool
+stdint-h
+
+configure.ac:
+
+Makefile.am:
+lib_SOURCES += next-prime.h next-prime.c
+
+Include:
+"next-prime.h"
+
+License:
+LGPLv2+
+
+Maintainer:
+all
-- 
2.43.0

>From 0b9a45e16a6a7913edf818c79c834eb863b89ccd Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
Date: Wed, 30 Apr 2025 02:50:58 +0200
Subject: [PATCH 2/2] next-prime: Add tests.

* tests/test-next-prime.c: New file.
* modules/next-prime-tests: New file.
---
 ChangeLog                |  4 ++++
 modules/next-prime-tests |  9 ++++++++
 tests/test-next-prime.c  | 46 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 59 insertions(+)
 create mode 100644 modules/next-prime-tests
 create mode 100644 tests/test-next-prime.c

diff --git a/ChangeLog b/ChangeLog
index 60fbb0c0d0..ee6295754d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
 2025-04-29  Bruno Haible  <br...@clisp.org>
 
+	next-prime: Add tests.
+	* tests/test-next-prime.c: New file.
+	* modules/next-prime-tests: New file.
+
 	New module next-prime.
 	* lib/next-prime.h: New file, based on lib/hash.c.
 	* lib/next-prime.c: New file, based on lib/hash.c.
diff --git a/modules/next-prime-tests b/modules/next-prime-tests
new file mode 100644
index 0000000000..cab1e5227d
--- /dev/null
+++ b/modules/next-prime-tests
@@ -0,0 +1,9 @@
+Files:
+tests/test-next-prime.c
+tests/macros.h
+
+configure.ac:
+
+Makefile.am:
+TESTS += test-next-prime
+check_PROGRAMS += test-next-prime
diff --git a/tests/test-next-prime.c b/tests/test-next-prime.c
new file mode 100644
index 0000000000..4a6a25e054
--- /dev/null
+++ b/tests/test-next-prime.c
@@ -0,0 +1,46 @@
+/* Test of next_prime() function.
+   Copyright (C) 2025 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <br...@clisp.org>, 2025.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "next-prime.h"
+
+#include "macros.h"
+
+int
+main ()
+{
+  ASSERT (next_prime (1) == 11);
+  ASSERT (next_prime (3) == 11);
+  ASSERT (next_prime (7) == 11);
+  ASSERT (next_prime (10) == 11);
+  ASSERT (next_prime (11) == 11);
+  ASSERT (next_prime (12) == 13);
+  ASSERT (next_prime (640) == 641);
+
+  ASSERT (next_prime (9551) == 9551);
+  ASSERT (next_prime (9552) == 9587);
+
+  ASSERT (next_prime (43331) == 43331);
+  ASSERT (next_prime (43332) == 43391);
+
+  ASSERT (next_prime (1000000) == 1000003);
+
+  return test_exit_status;
+}
-- 
2.43.0

Reply via email to