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