MOS Source Code
Loading...
Searching...
No Matches
hashmap.c
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
4#include "mos/mm/slab.h"
6
8#include <mos/moslib_global.h>
9#include <mos_stdlib.h>
10#include <mos_string.h>
11
12#define HASHMAP_MAGIC MOS_FOURCC('H', 'M', 'a', 'p')
13
14typedef struct hashmap_entry
15{
17 void *value;
20
23
24void hashmap_init(hashmap_t *map, size_t capacity, hashmap_hash_t hash_func, hashmap_key_compare_t compare_func)
25{
26 MOS_LIB_ASSERT(map);
27 if (map->magic == HASHMAP_MAGIC)
28 {
29 mos_panic("hashmap_init: hashmap %p is already initialized", (void *) map);
30 return;
31 }
32 memzero(map, sizeof(hashmap_t));
33 map->magic = HASHMAP_MAGIC;
34 map->entries = kcalloc(capacity, sizeof(hashmap_entry_t *));
35 map->capacity = capacity;
36 map->size = 0;
37 map->hash_func = hash_func;
38 map->key_compare_func = compare_func;
39}
40
50{
51 MOS_LIB_ASSERT_X(map && map->magic == HASHMAP_MAGIC, "hashmap_put: hashmap %p is not initialized", (void *) map);
53 map->magic = 0;
54 for (size_t i = 0; i < map->capacity; i++)
55 {
56 hashmap_entry_t *entry = map->entries[i];
57 while (entry != NULL)
58 {
59 hashmap_entry_t *next = entry->next;
60 kfree(entry);
61 entry = next;
62 }
63 }
64 kfree(map->entries);
66}
67
68void *hashmap_put(hashmap_t *map, uintn key, void *value)
69{
70 MOS_LIB_ASSERT_X(map && map->magic == HASHMAP_MAGIC, "hashmap_put: hashmap %p is not initialized", (void *) map);
72 size_t index = map->hash_func(key).hash % map->capacity;
73 hashmap_entry_t *entry = map->entries[index];
74 while (entry != NULL)
75 {
76 if (map->key_compare_func(entry->key, key))
77 {
78 // key already exists, replace value
79 void *old_value = entry->value;
80 entry->value = value;
82 return old_value;
83 }
84 entry = entry->next;
85 }
86 entry = kmalloc(hashmap_entry_slab);
87 entry->key = key;
88 entry->value = value;
89 entry->next = map->entries[index];
90 map->entries[index] = entry;
91 map->size++;
93 return NULL;
94}
95
96void *hashmap_get(hashmap_t *map, uintn key)
97{
98 MOS_LIB_ASSERT_X(map && map->magic == HASHMAP_MAGIC, "hashmap_put: hashmap %p is not initialized", (void *) map);
100 size_t index = map->hash_func(key).hash % map->capacity;
101 hashmap_entry_t *entry = map->entries[index];
102 while (entry != NULL)
103 {
104 if (map->key_compare_func(entry->key, key))
105 {
106 void *value = entry->value;
107 spinlock_release(&map->lock);
108 return value;
109 }
110 entry = entry->next;
111 }
112
113 spinlock_release(&map->lock);
114 return NULL;
115}
116
118{
119 MOS_LIB_ASSERT_X(map && map->magic == HASHMAP_MAGIC, "hashmap_put: hashmap %p is not initialized", (void *) map);
120 spinlock_acquire(&map->lock);
121 size_t index = map->hash_func(key).hash % map->capacity;
122 hashmap_entry_t *entry = map->entries[index];
123 hashmap_entry_t *prev = NULL;
124 while (entry != NULL)
125 {
126 if (map->key_compare_func(entry->key, key))
127 {
128 if (prev == NULL)
129 map->entries[index] = entry->next;
130 else
131 prev->next = entry->next;
132 void *value = entry->value;
133 kfree(entry);
134 map->size--;
135 spinlock_release(&map->lock);
136 return value;
137 }
138 prev = entry;
139 entry = entry->next;
140 }
141
142 spinlock_release(&map->lock);
143 return NULL;
144}
145
147{
148 MOS_LIB_ASSERT_X(map && map->magic == HASHMAP_MAGIC, "hashmap_put: hashmap %p is not initialized", (void *) map);
149 for (size_t i = 0; i < map->capacity; i++)
150 {
151 hashmap_entry_t *entry = map->entries[i];
152 while (entry != NULL)
153 {
154 if (!func(entry->key, entry->value, data))
155 return;
156 entry = entry->next;
157 }
158 }
159}
void * hashmap_get(hashmap_t *map, uintn key)
Definition hashmap.c:96
void * hashmap_put(hashmap_t *map, uintn key, void *value)
Definition hashmap.c:68
void hashmap_deinit(hashmap_t *map)
Deinitialize a hashmap.
Definition hashmap.c:49
int(* hashmap_key_compare_t)(const uintn key1, const uintn key2)
A hashmap hash function prototype.
Definition hashmap.h:17
hash_t(* hashmap_hash_t)(const uintn key)
Definition hashmap.h:16
void hashmap_init(hashmap_t *map, size_t capacity, hashmap_hash_t hash_func, hashmap_key_compare_t compare_func)
Definition hashmap.c:24
void * hashmap_remove(hashmap_t *map, uintn key)
Definition hashmap.c:117
struct hashmap_entry hashmap_entry_t
A hashmap foreach callback function prototype.
Definition hashmap.h:20
void hashmap_foreach(hashmap_t *map, hashmap_foreach_func_t func, void *data)
Definition hashmap.c:146
bool(* hashmap_foreach_func_t)(const uintn key, void *value, void *data)
A hashmap key comparison function prototype.
Definition hashmap.h:18
slab_t * hashmap_entry_slab
Definition hashmap.c:21
#define HASHMAP_MAGIC
Definition hashmap.c:12
#define mos_panic(fmt,...)
Definition panic.h:55
#define NULL
Definition pb_syshdr.h:46
#define memzero(ptr, size)
Definition rpc_client.c:40
#define MOS_LIB_ASSERT_X(cond, msg)
Definition rpc_server.c:25
#define MOS_LIB_ASSERT(cond)
Definition rpc_server.c:26
#define SLAB_AUTOINIT(name, var, type)
#define spinlock_acquire(lock)
Definition spinlock.h:61
#define spinlock_release(lock)
Definition spinlock.h:62
Definition hashmap.c:15
void * value
Definition hashmap.c:17
hashmap_entry_t * next
Definition hashmap.c:18
ptr_t key
Definition hashmap.c:16
s32 magic
Definition hashmap.h:24
spinlock_t lock
Definition hashmap.h:30
size_t size
Definition hashmap.h:27
hashmap_hash_t hash_func
Definition hashmap.h:28
hashmap_key_compare_t key_compare_func
Definition hashmap.h:29
hashmap_entry_t ** entries
Definition hashmap.h:25
size_t capacity
Definition hashmap.h:26
Definition slab.h:45
unsigned long uintn
Definition types.h:30
unsigned long ptr_t
Definition types.h:25