| /*****************************************************************************\ |
| * xahash.h - functions used for arbitrary hash table |
| ***************************************************************************** |
| * Copyright (C) SchedMD LLC. |
| * |
| * This file is part of Slurm, a resource management program. |
| * For details, see <https://slurm.schedmd.com/>. |
| * Please also read the included file: DISCLAIMER. |
| * |
| * Slurm 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 2 of the License, or (at your option) |
| * any later version. |
| * |
| * In addition, as a special exception, the copyright holders give permission |
| * to link the code of portions of this program with the OpenSSL library under |
| * certain conditions as described in each individual source file, and |
| * distribute linked combinations including the two. You must obey the GNU |
| * General Public License in all respects for all of the code used other than |
| * OpenSSL. If you modify file(s) with this exception, you may extend this |
| * exception to your version of the file(s), but you are not obligated to do |
| * so. If you do not wish to do so, delete this exception statement from your |
| * version. If you delete this exception statement from all source files in |
| * the program, then also delete it here. |
| * |
| * Slurm 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 Slurm; if not, write to the Free Software Foundation, Inc., |
| * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| \*****************************************************************************/ |
| |
| #ifndef _XAHASH_H |
| #define _XAHASH_H |
| |
| #include <inttypes.h> |
| #include <stdbool.h> |
| #include <stddef.h> |
| |
| #include "src/common/macros.h" |
| |
| /* |
| * Arbitrary hash table: |
| * Meant to not be limited to hashed cstrings |
| */ |
| |
| typedef void xahash_table_t; |
| typedef uint32_t xahash_hash_t; |
| |
| /* |
| * Create hash for a given key |
| * IN key - pointer to key |
| * IN key_bytes - Number of bytes in key |
| * IN state - arbitrary bytes to hand to function for state tracking |
| * RET hash for given key |
| * WARNING: returned hash should be unique for a given key as much as possible |
| */ |
| typedef xahash_hash_t (*xahash_func_t)(const void *key, const size_t key_bytes, |
| void *state); |
| |
| /* |
| * Match hash table pointer to a given key |
| * IN entry - pointer to bytes for entry in hash table |
| * Pointer is only guaranteed to be valid until the next operation on the |
| * table. Place pointers in the entry's bytes instead of using the entry |
| * pointer for logic. |
| * IN key - pointer to key |
| * IN key_bytes - Number of bytes in key |
| * IN state - arbitrary bytes to hand to function for state tracking |
| * RET true if entry matches key |
| * WARNING: only 1 entry must ever match to key at a time |
| */ |
| typedef bool (*xahash_match_func_t)(void *entry, const void *key, |
| const size_t key_bytes, void *state); |
| |
| /* |
| * On insert of new key into hash table. |
| * IN entry - pointer to bytes for entry in hash table |
| * Pointer is only guaranteed to be valid until the next operation on the |
| * table. Place pointers in the entry's bytes instead of using the entry |
| * pointer for logic. |
| * IN key - pointer to key |
| * IN key_bytes - Number of bytes in key |
| * IN state - arbitrary bytes to hand to function for state tracking |
| */ |
| typedef void (*xahash_on_insert_func_t)(void *entry, const void *key, |
| const size_t key_bytes, void *state); |
| |
| typedef enum { |
| XAHASH_FOREACH_INVALID = 0, |
| XAHASH_FOREACH_CONT, /* continue for each processing */ |
| XAHASH_FOREACH_STOP, /* stop for each processing */ |
| XAHASH_FOREACH_FAIL, /* stop for each processing due to failure */ |
| XAHASH_FOREACH_INVALID_MAX /* assertion only value on max value */ |
| } xahash_foreach_control_t; |
| |
| /* |
| * Callback for when walking each entry in hashtable |
| * IN entry - pointer to bytes for entry in hash table |
| * Pointer is only guaranteed to be valid until the next operation on the |
| * table. Place pointers in the entry's bytes instead of using the entry |
| * pointer for logic. |
| * IN state - arbitrary bytes to hand to function for state tracking |
| * IN arg - arbitrary pointer from caller |
| * RET control walking hashtable |
| */ |
| typedef xahash_foreach_control_t (*xahash_foreach_func_t)(void *entry, |
| void *state, |
| void *arg); |
| |
| /* |
| * Free anything related to entry's bytes |
| * IN entry - pointer to bytes for entry in hash table |
| * IN state - arbitrary bytes to hand to function for state tracking |
| */ |
| typedef void (*xahash_on_free_func_t)(void *entry, void *state); |
| |
| /* |
| * Create arbitrary hash table |
| * |
| * IN hash_func - hash function to be used during operations |
| * IN match_func - function to verify key matches to an entry |
| * IN on_insert_func - function called every time a new entry is inserted |
| * IN on_free_func - function called every time an entry is released |
| * IN state_bytes - Arbitrary number of bytes to store as state |
| * bytes held as state are only modified by client. |
| * hash table tracks state independently of these bytes. |
| * Bytes are provided to avoid needing an xmalloc() per table. |
| * IN bytes_per_entry - Arbitrary number of bytes needed per entry |
| * bytes for each entry are only modified by client. |
| * hash table tracks state independently of these bytes. |
| * Bytes are provided to avoid needing an xmalloc() per entry. |
| * IN fixed_table_size - Fixed number of entries in hash table or |
| * 0 for dynamic sizing (TODO: NOT IMPLEMENTED YET) |
| * RET new hash table pointer to call other xhahash_*(). |
| * Must be released by calling FREE_NULL_XAHASH_TABLE(). |
| * |
| */ |
| #define xahash_new_table(hash_func, match_func, on_insert_func, on_free_func, \ |
| state_bytes, bytes_per_entry, fixed_table_size) \ |
| xahash_new_table_funcname(hash_func, XSTRINGIFY(hash_func), \ |
| match_func, XSTRINGIFY(match_func), \ |
| on_insert_func, XSTRINGIFY(on_insert_func), \ |
| on_free_func, XSTRINGIFY(on_free_func), \ |
| state_bytes, bytes_per_entry, \ |
| fixed_table_size) |
| |
| extern xahash_table_t *xahash_new_table_funcname(xahash_func_t hash_func, |
| const char *hash_func_string, xahash_match_func_t match_func, |
| const char *match_func_string, xahash_on_insert_func_t on_insert_func, |
| const char *on_insert_func_string, xahash_on_free_func_t on_free_func, |
| const char *on_free_func_string, const size_t state_bytes, |
| const size_t bytes_per_entry, const size_t fixed_table_size); |
| |
| /* |
| * Release arbitrary hash table |
| * WARNING: call FREE_NULL_XAHASH_TABLE() instead |
| */ |
| extern void xahash_free_table(xahash_table_t *ht); |
| |
| #define FREE_NULL_XAHASH_TABLE(_X) \ |
| do { \ |
| if (_X) \ |
| xahash_free_table(_X); \ |
| _X = NULL; \ |
| } while (0) |
| |
| /* |
| * Get pointer to arbirtarty state held in hashtable |
| * N |
| * OTE: re-entrant w/r to ht. Not thread safe. |
| */ |
| extern void *xahash_get_state_ptr(xahash_table_t *ht); |
| |
| /* |
| * Get entry from hash table (but don't insert if not found) |
| * NOTE: re-entrant w/r to ht. Not thread safe. |
| * IN ht - hashtable ptr created by init_xahash_table() |
| * IN key - key to identify entry |
| * IN key_bytes - Number of bytes in key |
| * RET pointer to entry bytes for use. |
| * Pointer is only guaranteed to be valid until the next operation on the |
| * table. Place pointers in the entry's bytes instead of using the entry |
| * pointer for logic. |
| */ |
| extern void *xahash_find_entry(const xahash_table_t *ht, const void *key, |
| const size_t key_bytes); |
| |
| /* |
| * Get entry from hash table and insert if not found |
| * NOTE: re-entrant w/r to ht. Not thread safe. |
| * IN ht - hashtable ptr created by init_xahash_table() |
| * IN key - key to identify entry |
| * IN key_bytes - Number of bytes in key |
| * RET pointer to entry bytes for use |
| * Pointer is only guaranteed to be valid until the next operation on the |
| * table. Place pointers in the entry's bytes instead of using the entry |
| * pointer for logic. |
| * WARNING: Do not assume entry bytes has been zeroed |
| */ |
| extern void *xahash_insert_entry(xahash_table_t *ht, const void *key, |
| const size_t key_bytes); |
| |
| /* |
| * Walk every entry in hashtable |
| * NOTE: re-entrant w/r to ht. Not thread safe. |
| * IN ht - hashtable ptr created by init_xahash_table() |
| * IN callback - function to call on every entry |
| * IN arg - arbitrary pointer to hand to callback function |
| * RET number of entries walked, negative on failure |
| */ |
| #define xahash_foreach_entry(ht, callback, arg) \ |
| xahash_foreach_entry_funcname(ht, callback, XSTRINGIFY(callback), arg) |
| |
| extern int xahash_foreach_entry_funcname(xahash_table_t *ht, |
| xahash_foreach_func_t callback, |
| const char *callback_string, |
| void *arg); |
| |
| /* |
| * Release hash entry for key |
| * NOTE: re-entrant w/r to ht. Not thread safe. |
| * IN ht - hashtable ptr created by init_xahash_table() |
| * IN key - key to identify entry |
| * IN key_bytes - Number of bytes in key |
| * RET true if found and released or false if not found |
| */ |
| extern bool xahash_free_entry(xahash_table_t *ht, const void *key, |
| const size_t key_bytes); |
| |
| #endif /* _XAHASH_H */ |