Zephyr Project API  3.4.0
A Scalable Open Source RTOS
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
15#ifndef ZEPHYR_INCLUDE_SYS_HASH_MAP_H_
16#define ZEPHYR_INCLUDE_SYS_HASH_MAP_H_
17
18#include <stdbool.h>
19#include <stddef.h>
20#include <stdint.h>
21
22#include <zephyr/kernel.h>
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
53#define SYS_HASHMAP_DEFINE_ADVANCED(_name, _api, _config_type, _data_type, _hash_func, \
54 _alloc_func, ...) \
55 const struct _config_type _name##_config = __VA_ARGS__; \
56 struct _data_type _name##_data; \
57 struct sys_hashmap _name = { \
58 .api = (const struct sys_hashmap_api *)(_api), \
59 .config = (const struct sys_hashmap_config *)&_name##_config, \
60 .data = (struct sys_hashmap_data *)&_name##_data, \
61 .hash_func = (_hash_func), \
62 .alloc_func = (_alloc_func), \
63 }
64
81#define SYS_HASHMAP_DEFINE_STATIC_ADVANCED(_name, _api, _config_type, _data_type, _hash_func, \
82 _alloc_func, ...) \
83 static const struct _config_type _name##_config = __VA_ARGS__; \
84 static struct _data_type _name##_data; \
85 static struct sys_hashmap _name = { \
86 .api = (const struct sys_hashmap_api *)(_api), \
87 .config = (const struct sys_hashmap_config *)&_name##_config, \
88 .data = (struct sys_hashmap_data *)&_name##_data, \
89 .hash_func = (_hash_func), \
90 .alloc_func = (_alloc_func), \
91 }
92
100#define SYS_HASHMAP_DEFINE(_name) SYS_HASHMAP_DEFAULT_DEFINE(_name)
101
109#define SYS_HASHMAP_DEFINE_STATIC(_name) SYS_HASHMAP_DEFAULT_DEFINE_STATIC(_name)
110
111/*
112 * A safe wrapper for realloc(), invariant of which libc provides it.
113 */
114static inline void *sys_hashmap_default_allocator(void *ptr, size_t size)
115{
116 if (size == 0) {
117 free(ptr);
118 return NULL;
119 }
120
121 return realloc(ptr, size);
122}
123
124#define SYS_HASHMAP_DEFAULT_ALLOCATOR sys_hashmap_default_allocator
125
127#define SYS_HASHMAP_DEFAULT_LOAD_FACTOR 75
128
131 const struct sys_hashmap_api *api;
136};
137
145static inline void sys_hashmap_foreach(const struct sys_hashmap *map, sys_hashmap_callback_t cb,
146 void *cookie)
147{
148 struct sys_hashmap_iterator it = {0};
149
150 for (map->api->iter(map, &it); sys_hashmap_iterator_has_next(&it);) {
151 it.next(&it);
152 cb(it.key, it.value, cookie);
153 }
154}
155
166 void *cookie)
167{
168 map->api->clear(map, cb, cookie);
169}
170
187 uint64_t *old_value)
188{
189 return map->api->insert(map, key, value, old_value);
190}
191
205{
206 return map->api->remove(map, key, value);
207}
208
221static inline bool sys_hashmap_get(const struct sys_hashmap *map, uint64_t key, uint64_t *value)
222{
223 return map->api->get(map, key, value);
224}
225
235static inline bool sys_hashmap_contains_key(const struct sys_hashmap *map, uint64_t key)
236{
237 return sys_hashmap_get(map, key, NULL);
238}
239
247static inline size_t sys_hashmap_size(const struct sys_hashmap *map)
248{
249 return map->data->size;
250}
251
260static inline bool sys_hashmap_is_empty(const struct sys_hashmap *map)
261{
262 return map->data->size == 0;
263}
264
275static inline uint8_t sys_hashmap_load_factor(const struct sys_hashmap *map)
276{
277 if (map->data->n_buckets == 0) {
278 return 0;
279 }
280
281 return (map->data->size * 100) / map->data->n_buckets;
282}
283
290static inline size_t sys_hashmap_num_buckets(const struct sys_hashmap *map)
291{
292 return map->data->n_buckets;
293}
294
316static inline bool sys_hashmap_should_rehash(const struct sys_hashmap *map, bool grow,
317 size_t num_reserved, size_t *new_num_buckets)
318{
319 size_t size;
320 bool should_grow;
321 size_t n_buckets;
322 bool should_shrink;
323 const bool shrink = !grow;
324 struct sys_hashmap_oa_lp_data *const data = (struct sys_hashmap_oa_lp_data *)map->data;
325 const struct sys_hashmap_config *const config = map->config;
326
327 /* All branchless calculations, so very cache-friendly */
328
329 /* calculate new size */
330 size = data->size;
331 size += grow;
332 /* maximum size imposed by the implementation */
333 __ASSERT_NO_MSG(size < SIZE_MAX / 100);
334
335 /* calculate new number of buckets */
336 n_buckets = data->n_buckets;
337 /* initial number of buckets */
338 n_buckets += grow * (size == 1) * config->initial_n_buckets;
339 /* grow at a rate of 2x */
340 n_buckets <<= grow * (size != 1);
341 /* shrink at a rate of 2x */
342 n_buckets >>= shrink;
343
344 /* shrink to zero if empty */
345 n_buckets *= (size != 0);
346
347 __ASSERT_NO_MSG(new_num_buckets != NULL);
348 __ASSERT_NO_MSG(new_num_buckets != &data->n_buckets);
349 *new_num_buckets = n_buckets;
350
351 should_grow =
352 grow && (data->n_buckets == 0 ||
353 (size + num_reserved) * 100 / data->n_buckets > map->config->load_factor);
354 should_shrink =
355 shrink && (n_buckets == 0 || (size * 100) / n_buckets <= map->config->load_factor);
356
357 return should_grow || should_shrink;
358}
359
362#ifdef __cplusplus
363}
364#endif
365
366#endif /* ZEPHYR_INCLUDE_SYS_HASH_MAP_H_ */
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:66
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:204
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:186
static uint8_t sys_hashmap_load_factor(const struct sys_hashmap *map)
Query the load factor of map.
Definition: hash_map.h:275
static size_t sys_hashmap_size(const struct sys_hashmap *map)
Query the number of entries contained within map.
Definition: hash_map.h:247
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:221
static bool sys_hashmap_is_empty(const struct sys_hashmap *map)
Check if map is empty.
Definition: hash_map.h:260
void(* sys_hashmap_callback_t)(uint64_t key, uint64_t value, void *cookie)
Callback interface for sys_hashmap.
Definition: hash_map_api.h:104
static size_t sys_hashmap_num_buckets(const struct sys_hashmap *map)
Query the number of buckets used in map.
Definition: hash_map.h:290
void *(* sys_hashmap_allocator_t)(void *ptr, size_t new_size)
Allocator interface for sys_hashmap.
Definition: hash_map_api.h:82
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:235
static void * sys_hashmap_default_allocator(void *ptr, size_t size)
Definition: hash_map.h:114
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:165
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:145
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:316
uint32_t(* sys_hash_func32_t)(const void *str, size_t n)
32-bit Hash function interface
Definition: hash_function.h:35
Hashmap (Hash Table) API.
C++ Hashmap.
Open-Addressing / Linear Probe Hashmap Implementation.
Separate Chaining Hashmap Implementation.
Public kernel APIs.
struct region_map map[]
Definition: main.c:35
void * ptr
Definition: printk.c:120
static k_spinlock_key_t key
Definition: spinlock_error_case.c:15
__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:173
Generic Hashmap configuration.
Definition: hash_map_api.h:201
Generic Hashmap data.
Definition: hash_map_api.h:230
Generic Hashmap iterator interface.
Definition: hash_map_api.h:49
const size_t size
Definition: hash_map_api.h:55
uint64_t key
Definition: hash_map_api.h:53
void(* next)(struct sys_hashmap_iterator *it)
Definition: hash_map_api.h:51
uint64_t value
Definition: hash_map_api.h:54
Definition: hash_map_oa_lp.h:26
size_t size
Definition: hash_map_oa_lp.h:29
size_t n_buckets
Definition: hash_map_oa_lp.h:28
Generic Hashmap.
Definition: hash_map.h:130
struct sys_hashmap_data * data
Definition: hash_map.h:133
sys_hash_func32_t hash_func
Definition: hash_map.h:134
const struct sys_hashmap_api * api
Definition: hash_map.h:131
sys_hashmap_allocator_t alloc_func
Definition: hash_map.h:135
const struct sys_hashmap_config * config
Definition: hash_map.h:132
static fdata_t data[2]
Definition: test_fifo_contexts.c:15