Home | History | Annotate | Line # | Download | only in isc
      1 /*	$NetBSD: hashmap.h,v 1.2 2025/01/26 16:25:41 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * SPDX-License-Identifier: MPL-2.0
      7  *
      8  * This Source Code Form is subject to the terms of the Mozilla Public
      9  * License, v. 2.0. If a copy of the MPL was not distributed with this
     10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  *
     12  * See the COPYRIGHT file distributed with this work for additional
     13  * information regarding copyright ownership.
     14  */
     15 
     16 /* ! \file */
     17 
     18 #pragma once
     19 
     20 #include <inttypes.h>
     21 #include <string.h>
     22 
     23 #include <isc/result.h>
     24 #include <isc/types.h>
     25 
     26 typedef struct isc_hashmap	isc_hashmap_t;
     27 typedef struct isc_hashmap_iter isc_hashmap_iter_t;
     28 
     29 typedef bool (*isc_hashmap_match_fn)(void *node, const void *key);
     30 
     31 /*%
     32  * Create hashmap at *hashmapp, using memory context and size of (1<<bits)
     33  *
     34  * Requires:
     35  * \li	'hashmapp' is not NULL and '*hashmapp' is NULL.
     36  * \li	'mctx' is a valid memory context.
     37  * \li	'bits' >=1 and 'bits' <=32
     38  *
     39  */
     40 void
     41 isc_hashmap_create(isc_mem_t *mctx, uint8_t bits, isc_hashmap_t **hashmapp);
     42 
     43 /*%
     44  * Destroy hashmap, freeing everything
     45  *
     46  * Requires:
     47  * \li	'*hashmapp' is valid hashmap
     48  */
     49 void
     50 isc_hashmap_destroy(isc_hashmap_t **hashmapp);
     51 
     52 /*%
     53  * Add a node to hashmap, pointed by binary key 'key' of size 'keysize';
     54  * set its value to 'value'
     55  *
     56  * Requires:
     57  * \li	'hashmap' is a valid hashmap
     58  * \li	'hashval' is a precomputed hash value of 'key'
     59  * \li	'key' is non-null key of size 'keysize'
     60  *
     61  * Returns:
     62  * \li	#ISC_R_EXISTS		-- node of the same key already exists
     63  * \li	#ISC_R_SUCCESS		-- all is well.
     64  */
     65 isc_result_t
     66 isc_hashmap_add(isc_hashmap_t *hashmap, const uint32_t hashval,
     67 		isc_hashmap_match_fn match, const void *key, void *value,
     68 		void **foundp);
     69 
     70 /*%
     71  * Find a node matching 'key'/'keysize' in hashmap 'hashmap';
     72  * if found, set '*valuep' to its value. (If 'valuep' is NULL,
     73  * then simply return SUCCESS or NOTFOUND to indicate whether the
     74  * key exists in the hashmap.)
     75  *
     76  * Requires:
     77  * \li	'hashmap' is a valid hashmap
     78  * \li	'hashval' is a precomputed hash value of 'key'
     79  * \li	'key' is non-null key of size 'keysize'
     80  *
     81  * Returns:
     82  * \li	#ISC_R_SUCCESS		-- success
     83  * \li	#ISC_R_NOTFOUND		-- key not found
     84  */
     85 isc_result_t
     86 isc_hashmap_find(const isc_hashmap_t *hashmap, const uint32_t hashval,
     87 		 isc_hashmap_match_fn match, const void *key, void **valuep);
     88 
     89 /*%
     90  * Delete node from hashmap
     91  *
     92  * Requires:
     93  * \li	'hashmap' is a valid hashmap
     94  * \li	'hashval' is a precomputed hash value of 'key'
     95  * \li	'key' is non-null key
     96  *
     97  * Returns:
     98  * \li	#ISC_R_NOTFOUND		-- key not found
     99  * \li	#ISC_R_SUCCESS		-- all is well
    100  */
    101 isc_result_t
    102 isc_hashmap_delete(isc_hashmap_t *hashmap, const uint32_t hashval,
    103 		   isc_hashmap_match_fn match, const void *key);
    104 
    105 /*%
    106  * Create an iterator for the hashmap; point '*itp' to it.
    107  *
    108  * Requires:
    109  * \li	'hashmap' is a valid hashmap
    110  * \li	'itp' is non NULL and '*itp' is NULL.
    111  */
    112 void
    113 isc_hashmap_iter_create(isc_hashmap_t *hashmap, isc_hashmap_iter_t **itp);
    114 
    115 /*%
    116  * Destroy the iterator '*itp', set it to NULL
    117  *
    118  * Requires:
    119  * \li	'itp' is non NULL and '*itp' is non NULL.
    120  */
    121 void
    122 isc_hashmap_iter_destroy(isc_hashmap_iter_t **itp);
    123 
    124 /*%
    125  * Set an iterator to the first entry.
    126  *
    127  * Requires:
    128  * \li	'it' is non NULL.
    129  *
    130  * Returns:
    131  * \li	#ISC_R_SUCCESS	-- success
    132  * \li	#ISC_R_NOMORE	-- no data in the hashmap
    133  */
    134 isc_result_t
    135 isc_hashmap_iter_first(isc_hashmap_iter_t *it);
    136 
    137 /*%
    138  * Set an iterator to the next entry.
    139  *
    140  * Requires:
    141  * \li	'it' is non NULL.
    142  *
    143  * Returns:
    144  * \li	#ISC_R_SUCCESS	-- success
    145  * \li	#ISC_R_NOMORE	-- end of hashmap reached
    146  */
    147 isc_result_t
    148 isc_hashmap_iter_next(isc_hashmap_iter_t *it);
    149 
    150 /*%
    151  * Delete current entry and set an iterator to the next entry.
    152  *
    153  * Requires:
    154  * \li	'it' is non NULL.
    155  *
    156  * Returns:
    157  * \li	#ISC_R_SUCCESS	-- success
    158  * \li	#ISC_R_NOMORE	-- end of hashmap reached
    159  */
    160 isc_result_t
    161 isc_hashmap_iter_delcurrent_next(isc_hashmap_iter_t *it);
    162 
    163 /*%
    164  * Set 'value' to the current value under the iterator
    165  *
    166  * Requires:
    167  * \li	'it' is non NULL.
    168  * \li   'valuep' is non NULL and '*valuep' is NULL.
    169  */
    170 void
    171 isc_hashmap_iter_current(isc_hashmap_iter_t *it, void **valuep);
    172 
    173 /*%
    174  * Set 'key' to the current key for the value under the iterator
    175  *
    176  * Requires:
    177  * \li	'it' is non NULL.
    178  * \li   'key' is non NULL and '*key' is NULL.
    179  * \li	'keysize' is non NULL.
    180  */
    181 void
    182 isc_hashmap_iter_currentkey(isc_hashmap_iter_t *it, const unsigned char **key);
    183 
    184 /*%
    185  * Returns the number of items in the hashmap.
    186  *
    187  * Requires:
    188  * \li	'hashmap' is a valid hashmap
    189  */
    190 unsigned int
    191 isc_hashmap_count(isc_hashmap_t *hashmap);
    192