mirror of
https://github.com/containers/fuse-overlayfs.git
synced 2025-08-03 09:55:57 -04:00
lib: update hash module from gnulib
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
parent
3af99f6552
commit
ce8d185c16
26
lib/hash.c
26
lib/hash.c
@ -1,6 +1,6 @@
|
||||
/* hash - hashing table processing.
|
||||
|
||||
Copyright (C) 1998-2004, 2006-2007, 2009-2023 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998-2004, 2006-2007, 2009-2025 Free Software Foundation, Inc.
|
||||
|
||||
Written by Jim Meyering, 1992.
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
#include "bitrotate.h"
|
||||
#include "xalloc-oversized.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -499,13 +500,17 @@ compute_bucket_size (size_t candidate, const Hash_tuning *tuning)
|
||||
{
|
||||
float new_candidate = candidate / tuning->growth_threshold;
|
||||
if ((float) SIZE_MAX <= new_candidate)
|
||||
return 0;
|
||||
goto nomem;
|
||||
candidate = new_candidate;
|
||||
}
|
||||
candidate = next_prime (candidate);
|
||||
if (xalloc_oversized (candidate, sizeof (struct hash_entry *)))
|
||||
return 0;
|
||||
goto nomem;
|
||||
return candidate;
|
||||
|
||||
nomem:
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Hash_table *
|
||||
@ -534,6 +539,7 @@ hash_initialize (size_t candidate, const Hash_tuning *tuning,
|
||||
if the user provides invalid tuning options, we silently revert to
|
||||
using the defaults, and ignore further request to change the tuning
|
||||
options. */
|
||||
errno = EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -607,6 +613,7 @@ hash_free (Hash_table *table)
|
||||
struct hash_entry *bucket;
|
||||
struct hash_entry *cursor;
|
||||
struct hash_entry *next;
|
||||
int err = errno;
|
||||
|
||||
/* Call the user data_freer function. */
|
||||
if (table->data_freer && table->n_entries)
|
||||
@ -649,6 +656,8 @@ hash_free (Hash_table *table)
|
||||
/* Free the remainder of the hash table structure. */
|
||||
free (table->bucket);
|
||||
free (table);
|
||||
|
||||
errno = err;
|
||||
}
|
||||
|
||||
/* Insertion and deletion. */
|
||||
@ -762,8 +771,8 @@ hash_find_entry (Hash_table *table, const void *entry,
|
||||
/* Internal helper, to move entries from SRC to DST. Both tables must
|
||||
share the same free entry list. If SAFE, only move overflow
|
||||
entries, saving bucket heads for later, so that no allocations will
|
||||
occur. Return false if the free entry list is exhausted and an
|
||||
allocation fails. */
|
||||
occur. Return false (setting errno) if the free entry list is
|
||||
exhausted and an allocation fails. */
|
||||
|
||||
static bool
|
||||
transfer_entries (Hash_table *dst, Hash_table *src, bool safe)
|
||||
@ -910,12 +919,14 @@ hash_rehash (Hash_table *table, size_t candidate)
|
||||
passes. Two passes give worse cache performance and takes
|
||||
longer, but at this point, we're already out of memory, so slow
|
||||
and safe is better than failure. */
|
||||
int err = errno;
|
||||
table->free_entry_list = new_table->free_entry_list;
|
||||
if (! (transfer_entries (table, new_table, true)
|
||||
&& transfer_entries (table, new_table, false)))
|
||||
abort ();
|
||||
/* table->n_entries already holds its value. */
|
||||
free (new_table->bucket);
|
||||
errno = err;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -962,7 +973,10 @@ hash_insert_if_absent (Hash_table *table, void const *entry,
|
||||
* tuning->growth_threshold));
|
||||
|
||||
if ((float) SIZE_MAX <= candidate)
|
||||
return -1;
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If the rehash fails, arrange to return NULL. */
|
||||
if (!hash_rehash (table, candidate))
|
||||
|
82
lib/hash.h
82
lib/hash.h
@ -1,5 +1,5 @@
|
||||
/* hash - hashing table processing.
|
||||
Copyright (C) 1998-1999, 2001, 2003, 2009-2023 Free Software Foundation,
|
||||
Copyright (C) 1998-1999, 2001, 2003, 2009-2025 Free Software Foundation,
|
||||
Inc.
|
||||
Written by Jim Meyering <meyering@ascend.com>, 1998.
|
||||
|
||||
@ -61,24 +61,24 @@ typedef struct hash_table Hash_table;
|
||||
number of buckets (used plus unused), or the maximum number of slots, are
|
||||
the same quantity. */
|
||||
extern size_t hash_get_n_buckets (const Hash_table *table)
|
||||
;
|
||||
_GL_ATTRIBUTE_PURE;
|
||||
|
||||
/* Return the number of slots in use (non-empty buckets). */
|
||||
extern size_t hash_get_n_buckets_used (const Hash_table *table)
|
||||
;
|
||||
_GL_ATTRIBUTE_PURE;
|
||||
|
||||
/* Return the number of active entries. */
|
||||
extern size_t hash_get_n_entries (const Hash_table *table)
|
||||
;
|
||||
_GL_ATTRIBUTE_PURE;
|
||||
|
||||
/* Return the length of the longest chain (bucket). */
|
||||
extern size_t hash_get_max_bucket_length (const Hash_table *table)
|
||||
;
|
||||
_GL_ATTRIBUTE_PURE;
|
||||
|
||||
/* Do a mild validation of a hash table, by traversing it and checking two
|
||||
statistics. */
|
||||
extern bool hash_table_ok (const Hash_table *table)
|
||||
;
|
||||
_GL_ATTRIBUTE_PURE;
|
||||
|
||||
extern void hash_print_statistics (const Hash_table *table, FILE *stream);
|
||||
|
||||
@ -99,7 +99,7 @@ extern void *hash_lookup (const Hash_table *table, const void *entry);
|
||||
|
||||
/* Return the first data in the table, or NULL if the table is empty. */
|
||||
extern void *hash_get_first (const Hash_table *table)
|
||||
;
|
||||
_GL_ATTRIBUTE_PURE;
|
||||
|
||||
/* Return the user data for the entry following ENTRY, where ENTRY has been
|
||||
returned by a previous call to either 'hash_get_first' or 'hash_get_next'.
|
||||
@ -124,25 +124,40 @@ 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
|
||||
and for ENTRY2.
|
||||
The hash code function typically computes an unsigned integer and at the end
|
||||
performs a % TABLE_SIZE modulo operation. This modulo operation is performed
|
||||
as part of this hash code function, not by the caller, because in some cases
|
||||
the unsigned integer will be a 'size_t', in other cases an 'uintmax_t' or
|
||||
even larger. */
|
||||
typedef size_t (*Hash_hasher) (const void *entry, size_t table_size);
|
||||
|
||||
/* Compare two entries, ENTRY1 (being looked up or being inserted) and
|
||||
ENTRY2 (already in the table) for equality. Return true for equal,
|
||||
false otherwise. */
|
||||
typedef bool (*Hash_comparator) (const void *entry1, const void *entry2);
|
||||
|
||||
/* This function is invoked when an ENTRY is removed from the hash table. */
|
||||
typedef void (*Hash_data_freer) (void *entry);
|
||||
|
||||
/*
|
||||
* Allocation and clean-up.
|
||||
*/
|
||||
|
||||
/* 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)
|
||||
;
|
||||
|
||||
extern void hash_reset_tuning (Hash_tuning *tuning);
|
||||
|
||||
typedef size_t (*Hash_hasher) (const void *entry, size_t table_size);
|
||||
typedef bool (*Hash_comparator) (const void *entry1, const void *entry2);
|
||||
typedef void (*Hash_data_freer) (void *entry);
|
||||
|
||||
/* Reclaim all storage associated with a hash table. If a data_freer
|
||||
function has been supplied by the user when the hash table was created,
|
||||
this function applies it to the data of each entry before freeing that
|
||||
entry. */
|
||||
entry. This function preserves errno, like 'free'. */
|
||||
extern void hash_free (Hash_table *table);
|
||||
|
||||
/* Allocate and return a new hash table, or NULL upon failure. The initial
|
||||
@ -177,23 +192,30 @@ extern void hash_free (Hash_table *table);
|
||||
You should specify this function only if you want these functions to free
|
||||
all of your 'data' data. This is typically the case when your data is
|
||||
simply an auxiliary struct that you have malloc'd to aggregate several
|
||||
values. */
|
||||
values.
|
||||
|
||||
Set errno on failure; otherwise errno is unspecified. */
|
||||
_GL_ATTRIBUTE_NODISCARD
|
||||
extern Hash_table *hash_initialize (size_t candidate,
|
||||
const Hash_tuning *tuning,
|
||||
Hash_hasher hasher,
|
||||
Hash_comparator comparator,
|
||||
Hash_data_freer data_freer);
|
||||
Hash_data_freer data_freer)
|
||||
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (hash_free, 1);
|
||||
|
||||
/* Same as hash_initialize, but invokes xalloc_die on memory exhaustion. */
|
||||
/* Like hash_initialize, but invokes xalloc_die instead of returning NULL. */
|
||||
/* This function is defined by module 'xhash'. */
|
||||
_GL_ATTRIBUTE_NODISCARD
|
||||
extern Hash_table *hash_xinitialize (size_t candidate,
|
||||
const Hash_tuning *tuning,
|
||||
Hash_hasher hasher,
|
||||
Hash_comparator comparator,
|
||||
Hash_data_freer data_freer);
|
||||
Hash_data_freer data_freer)
|
||||
_GL_ATTRIBUTE_MALLOC _GL_ATTRIBUTE_DEALLOC (hash_free, 1)
|
||||
_GL_ATTRIBUTE_RETURNS_NONNULL;
|
||||
|
||||
/* Make all buckets empty, placing any chained entries on the free list.
|
||||
Apply the user-specified function data_freer (if any) to the datas of any
|
||||
Apply the user-specified function data_freer (if any) to the data of any
|
||||
affected entries. */
|
||||
extern void hash_clear (Hash_table *table);
|
||||
|
||||
@ -207,23 +229,26 @@ extern void hash_clear (Hash_table *table);
|
||||
the table may receive at least CANDIDATE different user entries, including
|
||||
those already in the table, before any other growth of the hash table size
|
||||
occurs. If TUNING->IS_N_BUCKETS is true, then CANDIDATE specifies the
|
||||
exact number of buckets desired. Return true iff the rehash succeeded. */
|
||||
exact number of buckets desired. Return true iff the rehash succeeded,
|
||||
false (setting errno) otherwise. */
|
||||
_GL_ATTRIBUTE_NODISCARD
|
||||
extern bool hash_rehash (Hash_table *table, size_t candidate);
|
||||
|
||||
/* If ENTRY matches an entry already in the hash table, return the pointer
|
||||
to the entry from the table. Otherwise, insert ENTRY and return ENTRY.
|
||||
Return NULL if the storage required for insertion cannot be allocated.
|
||||
This implementation does not support duplicate entries or insertion of
|
||||
NULL. */
|
||||
Return NULL (setting errno) if the storage required for insertion
|
||||
cannot be allocated. This implementation does not support
|
||||
duplicate entries or insertion of NULL. */
|
||||
_GL_ATTRIBUTE_NODISCARD
|
||||
extern void *hash_insert (Hash_table *table, const void *entry);
|
||||
|
||||
/* Same as hash_insert, but invokes xalloc_die on memory exhaustion. */
|
||||
/* Same as hash_insert, but invokes xalloc_die instead of returning NULL. */
|
||||
/* This function is defined by module 'xhash'. */
|
||||
extern void *hash_xinsert (Hash_table *table, const void *entry);
|
||||
|
||||
/* Insert ENTRY into hash TABLE if there is not already a matching entry.
|
||||
|
||||
Return -1 upon memory allocation failure.
|
||||
Return -1 (setting errno) upon memory allocation failure.
|
||||
Return 1 if insertion succeeded.
|
||||
Return 0 if there is already a matching entry in the table,
|
||||
and in that case, if MATCHED_ENT is non-NULL, set *MATCHED_ENT
|
||||
@ -247,6 +272,7 @@ extern void *hash_remove (Hash_table *table, const void *entry);
|
||||
|
||||
/* Same as hash_remove. This interface is deprecated.
|
||||
FIXME: Remove in 2022. */
|
||||
_GL_ATTRIBUTE_DEPRECATED
|
||||
extern void *hash_delete (Hash_table *table, const void *entry);
|
||||
|
||||
# ifdef __cplusplus
|
||||
|
109
m4/00gnulib.m4
109
m4/00gnulib.m4
@ -1,43 +1,84 @@
|
||||
# 00gnulib.m4 serial 3
|
||||
dnl Copyright (C) 2009-2019 Free Software Foundation, Inc.
|
||||
# 00gnulib.m4
|
||||
# serial 9
|
||||
dnl Copyright (C) 2009-2025 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
dnl This file is offered as-is, without any warranty.
|
||||
|
||||
dnl This file must be named something that sorts before all other
|
||||
dnl gnulib-provided .m4 files. It is needed until such time as we can
|
||||
dnl assume Autoconf 2.64, with its improved AC_DEFUN_ONCE and
|
||||
dnl m4_divert semantics.
|
||||
dnl gnulib-provided .m4 files. It is needed until the clang fix has
|
||||
dnl been included in Autoconf.
|
||||
|
||||
# Until autoconf 2.63, handling of the diversion stack required m4_init
|
||||
# to be called first; but this does not happen with aclocal. Wrapping
|
||||
# the entire execution in another layer of the diversion stack fixes this.
|
||||
# Worse, prior to autoconf 2.62, m4_wrap depended on the underlying m4
|
||||
# for whether it was FIFO or LIFO; in order to properly balance with
|
||||
# m4_init, we need to undo our push just before anything wrapped within
|
||||
# the m4_init body. The way to ensure this is to wrap both sides of
|
||||
# m4_init with a one-shot macro that does the pop at the right time.
|
||||
m4_ifndef([_m4_divert_diversion],
|
||||
[m4_divert_push([KILL])
|
||||
m4_define([gl_divert_fixup], [m4_divert_pop()m4_define([$0])])
|
||||
m4_define([m4_init],
|
||||
[gl_divert_fixup()]m4_defn([m4_init])[gl_divert_fixup()])])
|
||||
|
||||
|
||||
# AC_DEFUN_ONCE([NAME], VALUE)
|
||||
# ----------------------------
|
||||
# Define NAME to expand to VALUE on the first use (whether by direct
|
||||
# expansion, or by AC_REQUIRE), and to nothing on all subsequent uses.
|
||||
# Avoid bugs in AC_REQUIRE in Autoconf 2.63 and earlier. This
|
||||
# definition is slower than the version in Autoconf 2.64, because it
|
||||
# can only use interfaces that existed since 2.59; but it achieves the
|
||||
# same effect. Quoting is necessary to avoid confusing Automake.
|
||||
m4_version_prereq([2.63.263], [],
|
||||
[m4_define([AC][_DEFUN_ONCE],
|
||||
[AC][_DEFUN([$1],
|
||||
[AC_REQUIRE([_gl_DEFUN_ONCE([$1])],
|
||||
[m4_indir([_gl_DEFUN_ONCE([$1])])])])]dnl
|
||||
[AC][_DEFUN([_gl_DEFUN_ONCE([$1])], [$2])])])
|
||||
# The following definitions arrange to use a compiler option
|
||||
# -Werror=implicit-function-declaration in AC_CHECK_DECL, when the
|
||||
# compiler is clang. Without it, clang implicitly declares "known"
|
||||
# library functions in C mode, but not in C++ mode, which would cause
|
||||
# Gnulib to omit a declaration and thus later produce an error in C++
|
||||
# mode. As of clang 9.0, these "known" functions are identified through
|
||||
# LIBBUILTIN invocations in the LLVM source file
|
||||
# llvm/tools/clang/include/clang/Basic/Builtins.def.
|
||||
# It's not possible to AC_REQUIRE the extra tests from AC_CHECK_DECL,
|
||||
# because AC_CHECK_DECL, like other Autoconf built-ins, is not supposed
|
||||
# to AC_REQUIRE anything: some configure.ac files have their first
|
||||
# AC_CHECK_DECL executed conditionally. Therefore append the extra tests
|
||||
# to AC_PROG_CC.
|
||||
AC_DEFUN([gl_COMPILER_CLANG],
|
||||
[
|
||||
dnl AC_REQUIRE([AC_PROG_CC])
|
||||
AC_CACHE_CHECK([whether the compiler is clang],
|
||||
[gl_cv_compiler_clang],
|
||||
[dnl Use _AC_COMPILE_IFELSE instead of AC_EGREP_CPP, to avoid error
|
||||
dnl "circular dependency of AC_LANG_COMPILER(C)" if AC_PROG_CC has
|
||||
dnl not yet been invoked.
|
||||
_AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([[
|
||||
#ifdef __clang__
|
||||
barfbarf
|
||||
#endif
|
||||
]],[[]])
|
||||
],
|
||||
[gl_cv_compiler_clang=no],
|
||||
[gl_cv_compiler_clang=yes])
|
||||
])
|
||||
])
|
||||
AC_DEFUN([gl_COMPILER_PREPARE_CHECK_DECL],
|
||||
[
|
||||
dnl AC_REQUIRE([AC_PROG_CC])
|
||||
dnl AC_REQUIRE([gl_COMPILER_CLANG])
|
||||
AC_CACHE_CHECK([for compiler option needed when checking for declarations],
|
||||
[gl_cv_compiler_check_decl_option],
|
||||
[if test $gl_cv_compiler_clang = yes; then
|
||||
dnl Test whether the compiler supports the option
|
||||
dnl '-Werror=implicit-function-declaration'.
|
||||
saved_ac_compile="$ac_compile"
|
||||
ac_compile="$ac_compile -Werror=implicit-function-declaration"
|
||||
dnl Use _AC_COMPILE_IFELSE instead of AC_COMPILE_IFELSE, to avoid a
|
||||
dnl warning "AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS".
|
||||
_AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],[[]])],
|
||||
[gl_cv_compiler_check_decl_option='-Werror=implicit-function-declaration'],
|
||||
[gl_cv_compiler_check_decl_option=none])
|
||||
ac_compile="$saved_ac_compile"
|
||||
else
|
||||
gl_cv_compiler_check_decl_option=none
|
||||
fi
|
||||
])
|
||||
if test "x$gl_cv_compiler_check_decl_option" != xnone; then
|
||||
ac_compile_for_check_decl="$ac_compile $gl_cv_compiler_check_decl_option"
|
||||
else
|
||||
ac_compile_for_check_decl="$ac_compile"
|
||||
fi
|
||||
])
|
||||
dnl Redefine _AC_CHECK_DECL_BODY so that it references ac_compile_for_check_decl
|
||||
dnl instead of ac_compile. If, for whatever reason, the override of AC_PROG_CC
|
||||
dnl in zzgnulib.m4 is inactive, use the original ac_compile.
|
||||
m4_define([_AC_CHECK_DECL_BODY],
|
||||
[ ac_saved_ac_compile="$ac_compile"
|
||||
if test -n "$ac_compile_for_check_decl"; then
|
||||
ac_compile="$ac_compile_for_check_decl"
|
||||
fi]
|
||||
m4_defn([_AC_CHECK_DECL_BODY])[ ac_compile="$ac_saved_ac_compile"
|
||||
])
|
||||
|
||||
# gl_00GNULIB
|
||||
# -----------
|
||||
|
1546
m4/gnulib-common.m4
1546
m4/gnulib-common.m4
File diff suppressed because it is too large
Load Diff
25
m4/zzgnulib.m4
Normal file
25
m4/zzgnulib.m4
Normal file
@ -0,0 +1,25 @@
|
||||
# zzgnulib.m4
|
||||
# serial 1
|
||||
dnl Copyright (C) 2020-2025 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
dnl with or without modifications, as long as this notice is preserved.
|
||||
dnl This file is offered as-is, without any warranty.
|
||||
|
||||
dnl This file must be named something that sorts after all other
|
||||
dnl package- or gnulib-provided .m4 files - at least for those packages
|
||||
dnl that redefine AC_PROG_CC.
|
||||
|
||||
dnl Redefine AC_PROG_CC so that it ends with invocations of gl_COMPILER_CLANG
|
||||
dnl and gl_COMPILER_PREPARE_CHECK_DECL.
|
||||
m4_define([AC_PROG_CC],
|
||||
m4_defn([AC_PROG_CC])[
|
||||
gl_COMPILER_CLANG
|
||||
gl_COMPILER_PREPARE_CHECK_DECL
|
||||
])
|
||||
|
||||
# gl_ZZGNULIB
|
||||
# -----------
|
||||
# Witness macro that this file has been included. Needed to force
|
||||
# Automake to include this file after all other gnulib .m4 files.
|
||||
AC_DEFUN([gl_ZZGNULIB])
|
Loading…
x
Reference in New Issue
Block a user