bind9/lib/isc/include/isc/hashmap.h
Ondřej Surý e270266627
Refactor isc_hashmap to accept custom match function
Refactor isc_hashmap to allow custom matching functions.  This allows us
to have better tailored keys that don't require fixed uint8_t arrays,
but can be composed of more fields from the stored data structure.
2023-09-16 07:20:48 +02:00

189 lines
4.5 KiB
C

/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/* ! \file */
#pragma once
#include <inttypes.h>
#include <string.h>
#include <isc/result.h>
#include <isc/types.h>
typedef struct isc_hashmap isc_hashmap_t;
typedef struct isc_hashmap_iter isc_hashmap_iter_t;
typedef bool (*isc_hashmap_match_fn)(void *node, const void *key);
/*%
* Create hashmap at *hashmapp, using memory context and size of (1<<bits)
*
* Requires:
* \li 'hashmapp' is not NULL and '*hashmapp' is NULL.
* \li 'mctx' is a valid memory context.
* \li 'bits' >=1 and 'bits' <=32
*
*/
void
isc_hashmap_create(isc_mem_t *mctx, uint8_t bits, isc_hashmap_t **hashmapp);
/*%
* Destroy hashmap, freeing everything
*
* Requires:
* \li '*hashmapp' is valid hashmap
*/
void
isc_hashmap_destroy(isc_hashmap_t **hashmapp);
/*%
* Add a node to hashmap, pointed by binary key 'key' of size 'keysize';
* set its value to 'value'
*
* Requires:
* \li 'hashmap' is a valid hashmap
* \li 'hashval' is a precomputed hash value of 'key'
* \li 'key' is non-null key of size 'keysize'
*
* Returns:
* \li #ISC_R_EXISTS -- node of the same key already exists
* \li #ISC_R_SUCCESS -- all is well.
*/
isc_result_t
isc_hashmap_add(isc_hashmap_t *hashmap, const uint32_t hashval,
isc_hashmap_match_fn match, const void *key, void *value,
void **foundp);
/*%
* Find a node matching 'key'/'keysize' in hashmap 'hashmap';
* if found, set '*valuep' to its value. (If 'valuep' is NULL,
* then simply return SUCCESS or NOTFOUND to indicate whether the
* key exists in the hashmap.)
*
* Requires:
* \li 'hashmap' is a valid hashmap
* \li 'hashval' is a precomputed hash value of 'key'
* \li 'key' is non-null key of size 'keysize'
*
* Returns:
* \li #ISC_R_SUCCESS -- success
* \li #ISC_R_NOTFOUND -- key not found
*/
isc_result_t
isc_hashmap_find(const isc_hashmap_t *hashmap, const uint32_t hashval,
isc_hashmap_match_fn match, const void *key, void **valuep);
/*%
* Delete node from hashmap
*
* Requires:
* \li 'hashmap' is a valid hashmap
* \li 'hashval' is a precomputed hash value of 'key'
* \li 'key' is non-null key
*
* Returns:
* \li #ISC_R_NOTFOUND -- key not found
* \li #ISC_R_SUCCESS -- all is well
*/
isc_result_t
isc_hashmap_delete(isc_hashmap_t *hashmap, const uint32_t hashval,
isc_hashmap_match_fn match, const void *key);
/*%
* Create an iterator for the hashmap; point '*itp' to it.
*
* Requires:
* \li 'hashmap' is a valid hashmap
* \li 'itp' is non NULL and '*itp' is NULL.
*/
void
isc_hashmap_iter_create(isc_hashmap_t *hashmap, isc_hashmap_iter_t **itp);
/*%
* Destroy the iterator '*itp', set it to NULL
*
* Requires:
* \li 'itp' is non NULL and '*itp' is non NULL.
*/
void
isc_hashmap_iter_destroy(isc_hashmap_iter_t **itp);
/*%
* Set an iterator to the first entry.
*
* Requires:
* \li 'it' is non NULL.
*
* Returns:
* \li #ISC_R_SUCCESS -- success
* \li #ISC_R_NOMORE -- no data in the hashmap
*/
isc_result_t
isc_hashmap_iter_first(isc_hashmap_iter_t *it);
/*%
* Set an iterator to the next entry.
*
* Requires:
* \li 'it' is non NULL.
*
* Returns:
* \li #ISC_R_SUCCESS -- success
* \li #ISC_R_NOMORE -- end of hashmap reached
*/
isc_result_t
isc_hashmap_iter_next(isc_hashmap_iter_t *it);
/*%
* Delete current entry and set an iterator to the next entry.
*
* Requires:
* \li 'it' is non NULL.
*
* Returns:
* \li #ISC_R_SUCCESS -- success
* \li #ISC_R_NOMORE -- end of hashmap reached
*/
isc_result_t
isc_hashmap_iter_delcurrent_next(isc_hashmap_iter_t *it);
/*%
* Set 'value' to the current value under the iterator
*
* Requires:
* \li 'it' is non NULL.
* \li 'valuep' is non NULL and '*valuep' is NULL.
*/
void
isc_hashmap_iter_current(isc_hashmap_iter_t *it, void **valuep);
/*%
* Set 'key' to the current key for the value under the iterator
*
* Requires:
* \li 'it' is non NULL.
* \li 'key' is non NULL and '*key' is NULL.
* \li 'keysize' is non NULL.
*/
void
isc_hashmap_iter_currentkey(isc_hashmap_iter_t *it, const unsigned char **key);
/*%
* Returns the number of items in the hashmap.
*
* Requires:
* \li 'hashmap' is a valid hashmap
*/
unsigned int
isc_hashmap_count(isc_hashmap_t *hashmap);