NeoMutt  2025-12-11-980-ge38c27
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
hash.h File Reference

Hash Table data structure. More...

#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "array.h"
+ Include dependency graph for hash.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

union  HashKey
 The data item stored in a HashElem. More...
 
struct  HashElem
 The item stored in a Hash Table. More...
 
struct  HashTable
 A Hash Table. More...
 
struct  HashWalkState
 Cursor to iterate through a Hash Table. More...
 

Typedefs

typedef void(* hash_hdata_free_t) (int type, void *obj, intptr_t data)
 
typedef size_t(* hash_gen_hash_t) (union HashKey key, size_t num_elems)
 
typedef int(* hash_cmp_key_t) (union HashKey a, union HashKey b)
 
typedef uint8_t HashFlags
 

Enumerations

enum  HashFlag { MUTT_HASH_NONE = 0 , MUTT_HASH_STRCASECMP = 1U << 0 , MUTT_HASH_STRDUP_KEYS = 1U << 1 , MUTT_HASH_ALLOW_DUPS = 1U << 2 }
 Flags for mutt_hash_new(), e.g. More...
 

Functions

 ARRAY_HEAD (HashElemArray, struct HashElem *)
 
void mutt_hash_delete (struct HashTable *table, const char *strkey, const void *data)
 Remove an element from a Hash Table.
 
struct HashElemmutt_hash_find_bucket (const struct HashTable *table, const char *strkey)
 Find the HashElem in a Hash Table element using a key.
 
void * mutt_hash_find (const struct HashTable *table, const char *strkey)
 Find the HashElem data in a Hash Table element using a key.
 
struct HashElemmutt_hash_find_elem (const struct HashTable *table, const char *strkey)
 Find the HashElem in a Hash Table element using a key.
 
void mutt_hash_free (struct HashTable **ptr)
 Free a hash table.
 
struct HashElemmutt_hash_insert (struct HashTable *table, const char *strkey, void *data)
 Add a new element to the Hash Table (with string keys)
 
void mutt_hash_int_delete (struct HashTable *table, unsigned int intkey, const void *data)
 Remove an element from a Hash Table.
 
void * mutt_hash_int_find (const struct HashTable *table, unsigned int intkey)
 Find the HashElem data in a Hash Table element using a key.
 
struct HashElemmutt_hash_int_insert (struct HashTable *table, unsigned int intkey, void *data)
 Add a new element to the Hash Table (with integer keys)
 
struct HashTablemutt_hash_int_new (size_t num_elems, HashFlags flags)
 Create a new Hash Table (with integer keys)
 
struct HashTablemutt_hash_new (size_t num_elems, HashFlags flags)
 Create a new Hash Table (with string keys)
 
void mutt_hash_set_destructor (struct HashTable *table, hash_hdata_free_t fn, intptr_t fn_data)
 Set the destructor for a Hash Table.
 
struct HashElemmutt_hash_typed_insert (struct HashTable *table, const char *strkey, int type, void *data)
 Insert a string with type info into a Hash Table.
 
struct HashElemmutt_hash_walk (const struct HashTable *table, struct HashWalkState *state)
 Iterate through all the HashElem's in a Hash Table.
 

Detailed Description

Hash Table data structure.

Authors
  • Richard Russon

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 http://www.gnu.org/licenses/.

Definition in file hash.h.

Typedef Documentation

◆ hash_hdata_free_t

typedef void(* hash_hdata_free_t) (int type, void *obj, intptr_t data)

Definition at line 63 of file hash.h.

◆ hash_gen_hash_t

typedef size_t(* hash_gen_hash_t) (union HashKey key, size_t num_elems)

Definition at line 76 of file hash.h.

◆ hash_cmp_key_t

typedef int(* hash_cmp_key_t) (union HashKey a, union HashKey b)

Definition at line 91 of file hash.h.

◆ HashFlags

typedef uint8_t HashFlags

Definition at line 120 of file hash.h.

Enumeration Type Documentation

◆ HashFlag

enum HashFlag

Flags for mutt_hash_new(), e.g.

MUTT_HASH_STRCASECMP

Enumerator
MUTT_HASH_NONE 

No flags are set.

MUTT_HASH_STRCASECMP 

use strcasecmp() to compare keys

MUTT_HASH_STRDUP_KEYS 

make a copy of the keys

MUTT_HASH_ALLOW_DUPS 

allow duplicate keys to be inserted

Definition at line 113 of file hash.h.

114{
115 MUTT_HASH_NONE = 0,
116 MUTT_HASH_STRCASECMP = 1U << 0,
117 MUTT_HASH_STRDUP_KEYS = 1U << 1,
118 MUTT_HASH_ALLOW_DUPS = 1U << 2,
119};
@ MUTT_HASH_NONE
No flags are set.
Definition hash.h:115
@ MUTT_HASH_ALLOW_DUPS
allow duplicate keys to be inserted
Definition hash.h:118
@ MUTT_HASH_STRCASECMP
use strcasecmp() to compare keys
Definition hash.h:116
@ MUTT_HASH_STRDUP_KEYS
make a copy of the keys
Definition hash.h:117

Function Documentation

◆ ARRAY_HEAD()

ARRAY_HEAD ( HashElemArray ,
struct HashElem *  )

◆ mutt_hash_delete()

void mutt_hash_delete ( struct HashTable * table,
const char * strkey,
const void * data )

Remove an element from a Hash Table.

Parameters
tableHash Table to use
strkeyString key to match
dataPrivate data to match (or NULL for any match)

Definition at line 430 of file hash.c.

431{
432 if (!table || !strkey || (strkey[0] == '\0'))
433 return;
434 union HashKey key = { 0 };
435 // Copy the key because union_hash_delete() may use it after the HashElem is freed.
437 union_hash_delete(table, key, data);
438 FREE(&key.strkey);
439}
static void union_hash_delete(struct HashTable *table, union HashKey key, const void *data)
Remove an element from a Hash Table.
Definition hash.c:226
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
The data item stored in a HashElem.
Definition hash.h:35
const char * strkey
String key.
Definition hash.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hash_find_bucket()

struct HashElem * mutt_hash_find_bucket ( const struct HashTable * table,
const char * strkey )

Find the HashElem in a Hash Table element using a key.

Parameters
tableHash Table to search
strkeyString key to search for
Return values
ptrHashElem matching the key

Unlike mutt_hash_find_elem(), this will return the first matching entry.

Definition at line 412 of file hash.c.

413{
414 if (!table || !strkey)
415 return NULL;
416
417 union HashKey key = { 0 };
418
419 key.strkey = strkey;
420 size_t hash = table->gen_hash(key, table->num_elems);
421 return table->table[hash];
422}
hash_gen_hash_t gen_hash
Function to generate hash id from the key.
Definition hash.h:104
struct HashElem ** table
Array of Hash keys.
Definition hash.h:103
size_t num_elems
Number of buckets in the Hash Table.
Definition hash.h:100
+ Here is the caller graph for this function:

◆ mutt_hash_find()

void * mutt_hash_find ( const struct HashTable * table,
const char * strkey )

Find the HashElem data in a Hash Table element using a key.

Parameters
tableHash Table to search
strkeyString key to search for
Return values
ptrData attached to the HashElem matching the key

Definition at line 365 of file hash.c.

366{
367 if (!table || !strkey)
368 return NULL;
369 union HashKey key = { 0 };
370 key.strkey = strkey;
371 return union_hash_find(table, key);
372}
static void * union_hash_find(const struct HashTable *table, union HashKey key)
Find the HashElem data in a Hash Table element using a key.
Definition hash.c:210
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hash_find_elem()

struct HashElem * mutt_hash_find_elem ( const struct HashTable * table,
const char * strkey )

Find the HashElem in a Hash Table element using a key.

Parameters
tableHash Table to search
strkeyString key to search for
Return values
ptrHashElem matching the key

Definition at line 380 of file hash.c.

381{
382 if (!table || !strkey)
383 return NULL;
384 union HashKey key = { 0 };
385 key.strkey = strkey;
386 return union_hash_find_elem(table, key);
387}
static struct HashElem * union_hash_find_elem(const struct HashTable *table, union HashKey key)
Find a HashElem in a Hash Table element using a key.
Definition hash.c:189
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hash_free()

void mutt_hash_free ( struct HashTable ** ptr)

Free a hash table.

Parameters
[out]ptrHash Table to be freed

Definition at line 460 of file hash.c.

461{
462 if (!ptr || !*ptr)
463 return;
464
465 struct HashTable *table = *ptr;
466 struct HashElem *he = NULL;
467 struct HashElem *tmp = NULL;
468
469 for (size_t i = 0; i < table->num_elems; i++)
470 {
471 for (he = table->table[i]; he;)
472 {
473 tmp = he;
474 he = he->next;
475 if (table->hdata_free && tmp->data)
476 table->hdata_free(tmp->type, tmp->data, table->hdata);
477 if (table->strdup_keys)
478 FREE(&tmp->key.strkey);
479 FREE(&tmp);
480 }
481 }
482 FREE(&table->table);
483 FREE(ptr);
484}
The item stored in a Hash Table.
Definition hash.h:44
struct HashElem * next
Linked List.
Definition hash.h:48
union HashKey key
Key representing the data.
Definition hash.h:46
int type
Type of data stored in Hash Table, e.g. DT_STRING.
Definition hash.h:45
void * data
User-supplied data.
Definition hash.h:47
A Hash Table.
Definition hash.h:99
bool strdup_keys
if set, the key->strkey is strdup()'d
Definition hash.h:101
intptr_t hdata
Data to pass to the hdata_free() function.
Definition hash.h:106
hash_hdata_free_t hdata_free
Function to free a Hash element.
Definition hash.h:107
+ Here is the caller graph for this function:

◆ mutt_hash_insert()

struct HashElem * mutt_hash_insert ( struct HashTable * table,
const char * strkey,
void * data )

Add a new element to the Hash Table (with string keys)

Parameters
tableHash Table (with string keys)
strkeyString key
dataPrivate data associated with the key
Return values
ptrNewly inserted HashElem

Definition at line 338 of file hash.c.

339{
340 return mutt_hash_typed_insert(table, strkey, -1, data);
341}
struct HashElem * mutt_hash_typed_insert(struct HashTable *table, const char *strkey, int type, void *data)
Insert a string with type info into a Hash Table.
Definition hash.c:320
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hash_int_delete()

void mutt_hash_int_delete ( struct HashTable * table,
unsigned int intkey,
const void * data )

Remove an element from a Hash Table.

Parameters
tableHash Table to use
intkeyInteger key to match
dataPrivate data to match (or NULL for any match)

Definition at line 447 of file hash.c.

448{
449 if (!table)
450 return;
451 union HashKey key = { 0 };
452 key.intkey = intkey;
453 union_hash_delete(table, key, data);
454}
unsigned int intkey
Integer key.
Definition hash.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hash_int_find()

void * mutt_hash_int_find ( const struct HashTable * table,
unsigned int intkey )

Find the HashElem data in a Hash Table element using a key.

Parameters
tableHash Table to search
intkeyInteger key
Return values
ptrData attached to the HashElem matching the key

Definition at line 395 of file hash.c.

396{
397 if (!table)
398 return NULL;
399 union HashKey key = { 0 };
400 key.intkey = intkey;
401 return union_hash_find(table, key);
402}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hash_int_insert()

struct HashElem * mutt_hash_int_insert ( struct HashTable * table,
unsigned int intkey,
void * data )

Add a new element to the Hash Table (with integer keys)

Parameters
tableHash Table (with integer keys)
intkeyInteger key
dataPrivate data associated with the key
Return values
ptrNewly inserted HashElem

Definition at line 350 of file hash.c.

351{
352 if (!table)
353 return NULL;
354 union HashKey key = { 0 };
355 key.intkey = intkey;
356 return union_hash_insert(table, key, -1, data);
357}
static struct HashElem * union_hash_insert(struct HashTable *table, union HashKey key, int type, void *data)
Insert into a hash table using a union as a key.
Definition hash.c:141
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hash_int_new()

struct HashTable * mutt_hash_int_new ( size_t num_elems,
HashFlags flags )

Create a new Hash Table (with integer keys)

Parameters
num_elemsNumber of elements it should contain
flagsFlags, see HashFlags
Return values
ptrNew Hash Table

Definition at line 288 of file hash.c.

289{
291 table->gen_hash = gen_hash_int;
292 table->cmp_key = cmp_key_int;
293 if (flags & MUTT_HASH_ALLOW_DUPS)
294 table->allow_dups = true;
295 return table;
296}
static int cmp_key_int(union HashKey a, union HashKey b)
Compare two integer keys - Implements hash_cmp_key_t -.
Definition hash.c:106
static size_t gen_hash_int(union HashKey key, size_t num_elems)
Generate a hash from an integer - Implements hash_gen_hash_t -.
Definition hash.c:98
static struct HashTable * hash_new(size_t num_elems)
Create a new Hash Table.
Definition hash.c:123
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hash_new()

struct HashTable * mutt_hash_new ( size_t num_elems,
HashFlags flags )

Create a new Hash Table (with string keys)

Parameters
num_elemsNumber of elements it should contain
flagsFlags, see HashFlags
Return values
ptrNew Hash Table

Definition at line 262 of file hash.c.

263{
265 if (flags & MUTT_HASH_STRCASECMP)
266 {
267 table->gen_hash = gen_hash_case_string;
268 table->cmp_key = cmp_key_case_string;
269 }
270 else
271 {
272 table->gen_hash = gen_hash_string;
273 table->cmp_key = cmp_key_string;
274 }
275 if (flags & MUTT_HASH_STRDUP_KEYS)
276 table->strdup_keys = true;
277 if (flags & MUTT_HASH_ALLOW_DUPS)
278 table->allow_dups = true;
279 return table;
280}
static int cmp_key_case_string(union HashKey a, union HashKey b)
Compare two string keys (ignore case) - Implements hash_cmp_key_t -.
Definition hash.c:90
static int cmp_key_string(union HashKey a, union HashKey b)
Compare two string keys - Implements hash_cmp_key_t -.
Definition hash.c:63
static size_t gen_hash_string(union HashKey key, size_t num_elems)
Generate a hash from a string - Implements hash_gen_hash_t -.
Definition hash.c:46
static size_t gen_hash_case_string(union HashKey key, size_t num_elems)
Generate a hash from a string (ignore the case) - Implements hash_gen_hash_t -.
Definition hash.c:73
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hash_set_destructor()

void mutt_hash_set_destructor ( struct HashTable * table,
hash_hdata_free_t fn,
intptr_t fn_data )

Set the destructor for a Hash Table.

Parameters
tableHash Table to use
fnCallback function to free Hash Table's resources
fn_dataData to pass to the callback function

Definition at line 304 of file hash.c.

305{
306 if (!table)
307 return;
308 table->hdata_free = fn;
309 table->hdata = fn_data;
310}
+ Here is the caller graph for this function:

◆ mutt_hash_typed_insert()

struct HashElem * mutt_hash_typed_insert ( struct HashTable * table,
const char * strkey,
int type,
void * data )

Insert a string with type info into a Hash Table.

Parameters
tableHash Table to use
strkeyString key
typeType to associate with the key
dataPrivate data associated with the key
Return values
ptrNewly inserted HashElem

Definition at line 320 of file hash.c.

322{
323 if (!table || !strkey)
324 return NULL;
325
326 union HashKey key = { 0 };
327 key.strkey = table->strdup_keys ? mutt_str_dup(strkey) : strkey;
328 return union_hash_insert(table, key, type, data);
329}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_hash_walk()

struct HashElem * mutt_hash_walk ( const struct HashTable * table,
struct HashWalkState * state )

Iterate through all the HashElem's in a Hash Table.

Parameters
tableHash Table to search
stateCursor to keep track
Return values
ptrNext HashElem in the Hash Table
NULLWhen the last HashElem has been seen

Definition at line 493 of file hash.c.

494{
495 if (!table || !state)
496 return NULL;
497
498 if (state->last && state->last->next)
499 {
500 state->last = state->last->next;
501 return state->last;
502 }
503
504 if (state->last)
505 state->index++;
506
507 while (state->index < table->num_elems)
508 {
509 if (table->table[state->index])
510 {
511 state->last = table->table[state->index];
512 return state->last;
513 }
514 state->index++;
515 }
516
517 state->index = 0;
518 state->last = NULL;
519 return NULL;
520}
size_t index
Current position in table.
Definition hash.h:141
struct HashElem * last
Current element in linked list.
Definition hash.h:142
+ Here is the caller graph for this function: