This is analogous to dictionaries and ensures that no circular references can be created when using the exported API in apfl.h. This also changes apfl_value_copy into apfl_value_incref to better reflect what it does and to reflect that it is no longer an operation that can fail.
72 lines
2.4 KiB
C
72 lines
2.4 KiB
C
#ifndef APFL_HASHMAP_H
|
|
#define APFL_HASHMAP_H
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
|
|
#define APFL_HASH_FNV1A_INIT 14695981039346656037U // offset_basis for 64bit FNV-1(a)
|
|
|
|
// TODO: <stdint.h> is not required to provide uint64_t
|
|
typedef uint64_t apfl_hash;
|
|
|
|
typedef struct apfl_hashmap_struct *apfl_hashmap;
|
|
|
|
typedef struct apfl_hashmap_cursor_struct *apfl_hashmap_cursor;
|
|
|
|
struct apfl_hashmap_callbacks {
|
|
void *opaque;
|
|
|
|
// Compare keys a and b. If not provided, they will be compared with memcmp
|
|
bool (*keys_eq) (void *opaque, const void *a, const void *b);
|
|
|
|
// Calculate a hash value of a key.
|
|
// If not provided, a hash will be calculated based on the bytes of the key.
|
|
apfl_hash (*calc_hash) (void *opaque, const void *key);
|
|
|
|
// Destroy a key. Does nothing, if not provided.
|
|
void (*destroy_key) (void *opaque, void *key);
|
|
|
|
// Destroy a value. Does nothing, if not provided.
|
|
void (*destroy_value)(void *opaque, void *value);
|
|
|
|
// Copies a key. Returns true on success, false on failure.
|
|
// If not provided, the bytes will be copied with memcpy.
|
|
bool (*copy_key) (void *opaque, void *dest, void *src);
|
|
|
|
// Copies a value. Returns true on success, false on failure.
|
|
// If not provided, the bytes will be copied with memcpy.
|
|
bool (*copy_value) (void *opaque, void *dest, void *src);
|
|
};
|
|
|
|
apfl_hash apfl_hash_fnv1a_add(const void *, size_t len, apfl_hash);
|
|
apfl_hash apfl_hash_fnv1a(const void *, size_t len);
|
|
|
|
apfl_hashmap apfl_hashmap_new(struct apfl_hashmap_callbacks, size_t keysize, size_t valsize);
|
|
void apfl_hashmap_delete(apfl_hashmap, const void *key);
|
|
bool apfl_hashmap_get(const apfl_hashmap, const void *key, void *value);
|
|
bool apfl_hashmap_set(apfl_hashmap, void *key, void *value);
|
|
size_t apfl_hashmap_count(const apfl_hashmap);
|
|
void apfl_hashmap_destroy(apfl_hashmap);
|
|
|
|
apfl_hashmap apfl_hashmap_copy(apfl_hashmap src);
|
|
|
|
#define apfl_hashmap_isset(m, k) (apfl_hashmap_get((m), (k), NULL))
|
|
|
|
apfl_hashmap_cursor apfl_hashmap_get_cursor(apfl_hashmap);
|
|
bool apfl_hashmap_cursor_is_end(apfl_hashmap_cursor);
|
|
void apfl_hashmap_cursor_next(apfl_hashmap_cursor);
|
|
bool apfl_hashmap_cursor_get_key(apfl_hashmap_cursor, void *key);
|
|
bool apfl_hashmap_cursor_get_value(apfl_hashmap_cursor, void *value);
|
|
|
|
#define apfl_hashmap_cursor_destroy(cur) (free(cur))
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|