Zephyr API Documentation  3.6.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
hash_map.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 Meta
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
13#ifndef ZEPHYR_INCLUDE_SYS_HASH_MAP_H_
14#define ZEPHYR_INCLUDE_SYS_HASH_MAP_H_
15
16#include <stdbool.h>
17#include <stddef.h>
18#include <stdint.h>
19
20#include <zephyr/kernel.h>
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
46#define SYS_HASHMAP_DEFINE_ADVANCED(_name, _api, _config_type, _data_type, _hash_func, \
47 _alloc_func, ...) \
48 const struct _config_type _name##_config = __VA_ARGS__; \
49 struct _data_type _name##_data; \
50 struct sys_hashmap _name = { \
51 .api = (const struct sys_hashmap_api *)(_api), \
52 .config = (const struct sys_hashmap_config *)&_name##_config, \
53 .data = (struct sys_hashmap_data *)&_name##_data, \
54 .hash_func = (_hash_func), \
55 .alloc_func = (_alloc_func), \
56 }
57
74#define SYS_HASHMAP_DEFINE_STATIC_ADVANCED(_name, _api, _config_type, _data_type, _hash_func, \
75 _alloc_func, ...) \
76 static const struct _config_type _name##_config = __VA_ARGS__; \
77 static struct _data_type _name##_data; \
78 static struct sys_hashmap _name = { \
79 .api = (const struct sys_hashmap_api *)(_api), \
80 .config = (const struct sys_hashmap_config *)&_name##_config, \
81 .data = (struct sys_hashmap_data *)&_name##_data, \
82 .hash_func = (_hash_func), \
83 .alloc_func = (_alloc_func), \
84 }
85
93#define SYS_HASHMAP_DEFINE(_name) SYS_HASHMAP_DEFAULT_DEFINE(_name)
94
102#define SYS_HASHMAP_DEFINE_STATIC(_name) SYS_HASHMAP_DEFAULT_DEFINE_STATIC(_name)
103
104/*
105 * A safe wrapper for realloc(), invariant of which libc provides it.
106 */
107static inline void *sys_hashmap_default_allocator(void *ptr, size_t size)
108{
109 if (size == 0) {
110 free(ptr);
111 return NULL;
112 }
113
114 return realloc(ptr, size);
115}
116
118#define SYS_HASHMAP_DEFAULT_ALLOCATOR sys_hashmap_default_allocator
119
121#define SYS_HASHMAP_DEFAULT_LOAD_FACTOR 75
122
126 const struct sys_hashmap_api *api;
135};
136
144static inline void sys_hashmap_foreach(const struct sys_hashmap *map, sys_hashmap_callback_t cb,
145 void *cookie)
146{
147 struct sys_hashmap_iterator it = {0};
148
149 for (map->api->iter(map, &it); sys_hashmap_iterator_has_next(&it);) {
150 it.next(&it);
151 cb(it.key, it.value, cookie);
152 }
153}
154
165 void *cookie)
166{
167 map->api->clear(map, cb, cookie);
168}
169
186 uint64_t *old_value)
187{
188 return map->api->insert(map, key, value, old_value);
189}
190
204{
205 return map->api->remove(map, key, value);
206}
207
220static inline bool sys_hashmap_get(const struct sys_hashmap *map, uint64_t key, uint64_t *value)
221{
222 return map->api->get(map, key, value);
223}
224
234static inline bool sys_hashmap_contains_key(const struct sys_hashmap *map, uint64_t key)
235{
236 return sys_hashmap_get(map, key, NULL);
237}
238
246static inline size_t sys_hashmap_size(const struct sys_hashmap *map)
247{
248 return map->data->size;
249}
250
259static inline bool sys_hashmap_is_empty(const struct sys_hashmap *map)
260{
261 return map->data->size == 0;
262}
263
274static inline uint8_t sys_hashmap_load_factor(const struct sys_hashmap *map)
275{
276 if (map->data->n_buckets == 0) {
277 return 0;
278 }
279
280 return (map->data->size * 100) / map->data->n_buckets;
281}
282
289static inline size_t sys_hashmap_num_buckets(const struct sys_hashmap *map)
290{
291 return map->data->n_buckets;
292}
293
315static inline bool sys_hashmap_should_rehash(const struct sys_hashmap *map, bool grow,
316 size_t num_reserved, size_t *new_num_buckets)
317{
318 size_t size;
319 bool should_grow;
320 size_t n_buckets;
321 bool should_shrink;
322 const bool shrink = !grow;
323 struct sys_hashmap_oa_lp_data *const data = (struct sys_hashmap_oa_lp_data *)map->data;
324 const struct sys_hashmap_config *const config = map->config;
325
326 /* All branchless calculations, so very cache-friendly */
327
328 /* calculate new size */
329 size = data->size;
330 size += grow;
331 /* maximum size imposed by the implementation */
332 __ASSERT_NO_MSG(size < SIZE_MAX / 100);
333
334 /* calculate new number of buckets */
335 n_buckets = data->n_buckets;
336 /* initial number of buckets */
337 n_buckets += grow * (size == 1) * config->initial_n_buckets;
338 /* grow at a rate of 2x */
339 n_buckets <<= grow * (size != 1);
340 /* shrink at a rate of 2x */
341 n_buckets >>= shrink;
342
343 /* shrink to zero if empty */
344 n_buckets *= (size != 0);
345
346 __ASSERT_NO_MSG(new_num_buckets != NULL);
347 __ASSERT_NO_MSG(new_num_buckets != &data->n_buckets);
348 *new_num_buckets = n_buckets;
349
350 should_grow =
351 grow && (data->n_buckets == 0 ||
352 (size + num_reserved) * 100 / data->n_buckets > map->config->load_factor);
353 should_shrink =
354 shrink && (n_buckets == 0 || (size * 100) / n_buckets <= map->config->load_factor);
355
356 return should_grow || should_shrink;
357}
358
361#ifdef __cplusplus
362}
363#endif
364
365#endif /* ZEPHYR_INCLUDE_SYS_HASH_MAP_H_ */
uint32_t(* sys_hash_func32_t)(const void *str, size_t n)
32-bit Hash function interface
Definition: hash_function.h:41
static bool sys_hashmap_iterator_has_next(const struct sys_hashmap_iterator *it)
Check if a Hashmap iterator has a next entry.
Definition: hash_map_api.h:68
static bool sys_hashmap_remove(struct sys_hashmap *map, uint64_t key, uint64_t *value)
Remove an entry from a sys_hashmap.
Definition: hash_map.h:203
static int sys_hashmap_insert(struct sys_hashmap *map, uint64_t key, uint64_t value, uint64_t *old_value)
Insert a new entry into a sys_hashmap.
Definition: hash_map.h:185
static uint8_t sys_hashmap_load_factor(const struct sys_hashmap *map)
Query the load factor of map.
Definition: hash_map.h:274
static size_t sys_hashmap_size(const struct sys_hashmap *map)
Query the number of entries contained within map.
Definition: hash_map.h:246
static bool sys_hashmap_get(const struct sys_hashmap *map, uint64_t key, uint64_t *value)
Get a value from a sys_hashmap.
Definition: hash_map.h:220
static bool sys_hashmap_is_empty(const struct sys_hashmap *map)
Check if map is empty.
Definition: hash_map.h:259
void(* sys_hashmap_callback_t)(uint64_t key, uint64_t value, void *cookie)
Callback interface for sys_hashmap.
Definition: hash_map_api.h:106
static size_t sys_hashmap_num_buckets(const struct sys_hashmap *map)
Query the number of buckets used in map.
Definition: hash_map.h:289
void *(* sys_hashmap_allocator_t)(void *ptr, size_t new_size)
Allocator interface for sys_hashmap.
Definition: hash_map_api.h:84
static bool sys_hashmap_contains_key(const struct sys_hashmap *map, uint64_t key)
Check if map contains a value associated with key.
Definition: hash_map.h:234
static void * sys_hashmap_default_allocator(void *ptr, size_t size)
Definition: hash_map.h:107
static void sys_hashmap_clear(struct sys_hashmap *map, sys_hashmap_callback_t cb, void *cookie)
Clear all entries contained in a sys_hashmap.
Definition: hash_map.h:164
static void sys_hashmap_foreach(const struct sys_hashmap *map, sys_hashmap_callback_t cb, void *cookie)
Iterate over all values contained in a sys_hashmap.
Definition: hash_map.h:144
static bool sys_hashmap_should_rehash(const struct sys_hashmap *map, bool grow, size_t num_reserved, size_t *new_num_buckets)
Decide whether the Hashmap should be resized.
Definition: hash_map.h:315
C++ Hashmap.
Open-Addressing / Linear Probe Hashmap Implementation.
Separate Chaining Hashmap Implementation.
Public kernel APIs.
__UINT64_TYPE__ uint64_t
Definition: stdint.h:91
#define SIZE_MAX
Definition: stdint.h:70
__UINT8_TYPE__ uint8_t
Definition: stdint.h:88
void * realloc(void *ptr, size_t size)
void free(void *ptr)
Generic Hashmap API.
Definition: hash_map_api.h:168
sys_hashmap_iterator_t iter
Iterator constructor (in-place)
Definition: hash_map_api.h:170
sys_hashmap_remove_t remove
Remove a key-value pair from the Hashmap.
Definition: hash_map_api.h:176
sys_hashmap_clear_t clear
Clear the hash table, freeing all resources.
Definition: hash_map_api.h:172
sys_hashmap_insert_t insert
Insert a key-value pair into the Hashmap.
Definition: hash_map_api.h:174
sys_hashmap_get_t get
Retrieve the value associated with a given key from the Hashmap.
Definition: hash_map_api.h:178
Generic Hashmap configuration.
Definition: hash_map_api.h:197
uint8_t load_factor
Maximum load factor expressed in hundredths.
Definition: hash_map_api.h:201
Generic Hashmap data.
Definition: hash_map_api.h:225
size_t n_buckets
The number of buckets currently allocated.
Definition: hash_map_api.h:229
size_t size
The number of entries currently in the Hashmap.
Definition: hash_map_api.h:231
Generic Hashmap iterator interface.
Definition: hash_map_api.h:44
const struct sys_hashmap * map
Pointer to the associated Hashmap.
Definition: hash_map_api.h:46
const size_t size
Number of entries in the map.
Definition: hash_map_api.h:56
uint64_t key
Key associated with the current entry.
Definition: hash_map_api.h:52
void(* next)(struct sys_hashmap_iterator *it)
Modify the iterator in-place to point to the next Hashmap entry.
Definition: hash_map_api.h:48
uint64_t value
Value associated with the current entry.
Definition: hash_map_api.h:54
Definition: hash_map_oa_lp.h:27
size_t size
Definition: hash_map_oa_lp.h:30
size_t n_buckets
Definition: hash_map_oa_lp.h:29
Generic Hashmap.
Definition: hash_map.h:124
struct sys_hashmap_data * data
Hashmap data.
Definition: hash_map.h:130
sys_hash_func32_t hash_func
Hash function.
Definition: hash_map.h:132
const struct sys_hashmap_api * api
Hashmap API.
Definition: hash_map.h:126
sys_hashmap_allocator_t alloc_func
Allocator.
Definition: hash_map.h:134
const struct sys_hashmap_config * config
Hashmap configuration.
Definition: hash_map.h:128