solidc
Robust collection of general-purpose cross-platform C libraries and data structures designed for rapid and safe development in C
Loading...
Searching...
No Matches
map.h
Go to the documentation of this file.
1
6#ifndef SOLIDC_MAP_H
7#define A02E572A_DDD85_4D77_AC81_41037EDE290A
8
9#include "./cmp.h"
10
11#include <float.h>
12#include <stdbool.h>
13#include <stddef.h>
14#include <stdint.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18
19#ifdef __cplusplus
20extern "C" {
21#endif
22
23// Allow user to customize initial map size and load factor threshold
24#ifndef INITIAL_MAP_SIZE
25#define INITIAL_MAP_SIZE (size_t)16
26#endif
27
28#ifndef LOAD_FACTOR_THRESHOLD
29#define LOAD_FACTOR_THRESHOLD (double)0.75
30#endif
31
32// Define alignment for cache line optimization
33#define CACHE_LINE_SIZE 64
34
35// Cross-platform prefetch macros
36#if defined(__GNUC__) || defined(__clang__)
37#define PREFETCH_READ(addr) __builtin_prefetch((addr), 0, 3)
38#define PREFETCH_WRITE(addr) __builtin_prefetch((addr), 1, 3)
39#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
40#include <intrin.h>
41#define PREFETCH_READ(addr) _mm_prefetch((char*)(addr), _MM_HINT_T0)
42#define PREFETCH_WRITE(addr) _mm_prefetch((char*)(addr), _MM_HINT_T0)
43#elif defined(__has_builtin)
44#if __has_builtin(__builtin_prefetch)
45#define PREFETCH_READ(addr) __builtin_prefetch((addr), 0, 3)
46#define PREFETCH_WRITE(addr) __builtin_prefetch((addr), 1, 3)
47#else
48#define PREFETCH_READ(addr) ((void)0)
49#define PREFETCH_WRITE(addr) ((void)0)
50#endif
51#else
52#define PREFETCH_READ(addr) ((void)0)
53#define PREFETCH_WRITE(addr) ((void)0)
54#endif
55
56typedef size_t (*HashFunction)(const void* key, size_t size);
57typedef bool (*KeyCmpFunction)(const void* key1, const void* key2);
58typedef void (*KeyFreeFunction)(void* key);
59typedef void (*ValueFreeFunction)(void* value);
60
61typedef struct {
62 size_t initial_capacity; // Initial size of the map. If zero, the default size
63 // is used.
64 KeyCmpFunction key_compare; // Required: Key comparison function
65 KeyFreeFunction key_free; // Optional: Key cleanup function. Default is free from libc.
66 ValueFreeFunction value_free; // Optional: Value cleanup function. Default is
67 // free from libc.
68 float max_load_factor; // Optional: When to resize (default 0.75)
69 HashFunction hash_func; // Optional: Custom hash function
70} MapConfig;
71
72#define MapConfigInt (&(MapConfig){.key_compare = key_compare_int})
73#define MapConfigFloat (&(MapConfig){.key_compare = key_compare_float})
74#define MapConfigDouble (&(MapConfig){.key_compare = key_compare_double})
75#define MapConfigStr (&(MapConfig){.key_compare = key_compare_char_ptr})
76
77// Generic map implementation using xxhash as the hash function.
78typedef struct hash_map HashMap;
79
80// Create a new map and initialize it. If the initial capacity is 0, a default
81// capacity is used, otherwise its used as it.
82// key_compare is a function pointer used to compare 2 keys for equality.
83// If free_entries is true, the keys and values are also freed.
84HashMap* map_create(const MapConfig* config);
85
86// Destroy the map and free the memory.
87void map_destroy(HashMap* m);
88
89// Set a key-value pair in the map
90// This is idempotent. Returns true on success, false on failure.
91bool map_set(HashMap* m, void* key, size_t key_len, void* value);
92
93// A thread-safe version of map_set. Returns true on success, false on failure.
94bool map_set_safe(HashMap* m, void* key, size_t key_len, void* value);
95
96// Get the value for a key in the map without locking
97void* map_get(HashMap* m, void* key, size_t key_len);
98
99// Get the value for a key in the map with locking
100void* map_get_safe(HashMap* m, void* key, size_t key_len);
101
102// Remove a key from the map without locking. Returns true if key was found and removed.
103bool map_remove(HashMap* m, void* key, size_t key_len);
104
105// Remove a key from the map with locking. Returns true if key was found and removed.
106bool map_remove_safe(HashMap* m, void* key, size_t key_len);
107
108// Iterator implementation
109typedef struct {
110 HashMap* map;
111 size_t index;
112} map_iterator;
113
114// Create a map iterator.
115map_iterator map_iter(HashMap* m);
116
117// Advance to the next valid entry in the map.
118bool map_next(map_iterator* it, void** key, void** value);
119
120// Get the number of key-value pairs in the map
121size_t map_length(HashMap* m);
122
123// Get the capacity of the map
124size_t map_capacity(HashMap* m);
125
126static inline bool key_compare_int(const void* a, const void* b) { return a && b && *(const int*)a == *(const int*)b; }
127
128static inline bool key_compare_char_ptr(const void* a, const void* b) {
129 return a && b && strcmp((const char*)a, (const char*)b) == 0;
130}
131
132static inline bool key_compare_float(const void* a, const void* b) {
133 return a && b && cmp_float(*(const float*)a, *(const float*)b, (cmp_config_t){.epsilon = FLT_EPSILON});
134}
135
136static inline bool key_compare_double(const void* a, const void* b) {
137 return a && b && cmp_double(*(const double*)a, *(const double*)b, (cmp_config_t){.epsilon = DBL_EPSILON});
138}
139
140#if defined(__cplusplus)
141}
142#endif
143
144#endif /* SOLIDC_MAP_H */
Floating-point comparison library for precise and robust comparisons.
Default configuration for each floating-point type.
Definition cmp.h:62