blob: 061a53834c41171e983693b9f648da7aee09b863 [file] [log] [blame]
liubin281ac462023-07-19 14:22:54 +08001/*
2 * mbtk_map.c
3 *
4 * Created on: Aug 18, 2020
5 * Author: lb
6 */
7#include <stdlib.h>
8#include <string.h>
9#include "mbtk_map.h"
10
11map_node_t* map_create(uint32 capacity, map_free_func free_func)
12{
13 if (capacity > 0) {
14 map_node_t *map = (map_node_t*) malloc(sizeof(map_node_t));
15 if (map) {
16 memset(map, 0x0, sizeof(map_node_t));
17 map->size = 0;
18 map->cur_index = 0;
19 map->cur_data = NULL;
20 map->capacity = (uint32) (capacity * 0.75f); // Default 0.75
21 if(map->capacity < 1) {
22 free(map);
23 return NULL;
24 }
25 map->free_func = free_func;
26 map->map_array = (map_data_t**) malloc(
27 sizeof(map_data_t*) * map->capacity);
28 uint32 i = 0;
29 while (i < map->capacity) {
30 map->map_array[i] = NULL;
31 i++;
32 }
33 return map;
34 }
35 }
36
37 return NULL;
38}
39
40uint32 map_size(map_node_t* map)
41{
42 if (map) {
43 return map->size;
44 }
45
46 return 0;
47}
48
49uint32 map_hash(const char* key, uint32 capacity)
50{
51 uint32 hash = 0;
52 const uint8 *ptr = (const uint8*) key;
53 while (*ptr) {
54 hash = 31 * hash + *ptr;
55 ptr++;
56 }
57
58 return hash % capacity;
59}
60
61void map_put(map_node_t* map, const char* key, void* value)
62{
63 if (map && key && strlen(key) > 0 && value) {
64 uint32 index = map_hash(key, map->capacity);
65
66 map_data_t *ptr = map->map_array[index];
67 if (!ptr) { // Add to first position.
68 ptr = (map_data_t*) malloc(sizeof(map_data_t));
69 ptr->key = strdup(key);
70 ptr->value = value;
71 ptr->next = NULL;
72
73 map->size++;
74 map->map_array[index] = ptr;
75 } else { // This position has one item at least.
76 if (!memcmp(ptr->key, key, strlen(key))) { // Has this item,will change.
77 if (map->free_func) {
78 map->free_func(ptr->value);
79 }
80
81 ptr->value = value;
82 } else {
83 while (ptr->next) {
84 if (!memcmp(ptr->next->key, key, strlen(key))) // Has this item,will change.
85 break;
86 ptr = ptr->next;
87 }
88
89 if (!ptr->next) { // Add new item.
90 ptr->next = (map_data_t*) malloc(sizeof(map_data_t));
91
92 ptr->next->key = strdup(key);
93 ptr->next->value = value;
94 ptr->next->next = NULL;
95 map->size++;
96 } else { // Change item.
97 if (map->free_func) {
98 map->free_func(ptr->next->value);
99 }
100
101 ptr->next->value = value;
102 }
103 }
104 }
105 }
106}
107
108void* map_get(map_node_t* map, char* key)
109{
110 if (map && key && strlen(key) > 0) {
111 uint32 index = map_hash(key, map->capacity);
112 map_data_t *ptr = map->map_array[index];
113 while (ptr) {
114 if (ptr->key && !memcmp(ptr->key, key, strlen(key))) {
115 return ptr->value;
116 }
117 ptr = ptr->next;
118 }
119 }
120 return NULL;
121}
122
123void* map_remove(map_node_t* map, char* key)
124{
125 if (map && key && strlen(key) > 0) {
126 uint32 index = map_hash(key, map->capacity);
127 map_data_t *ptr = map->map_array[index];
128 if (!ptr) { // No items.
129 return NULL;
130 }
131
132 if (!memcmp(ptr->key, key, strlen(key))) { // Is first item
133 map_data_t *temp = ptr;
134 void *result = temp->value;
135 map->map_array[index] = ptr->next;
136 free(temp);
137 map->size--;
138
139 return result;
140 } else {
141 while (ptr->next) {
142 if (!memcmp(ptr->next->key, key, strlen(key))) {
143 map_data_t *temp = ptr->next;
144 void *result = temp->value;
145 ptr->next = temp->next;
146 free(temp);
147 map->size--;
148
149 return result;
150 }
151 ptr = ptr->next;
152 }
153 }
154 }
155 return NULL;
156}
157
158void map_first(map_node_t *map)
159{
160 if (map) {
161 map->cur_index = 0;
162 map->cur_data = map->map_array[0];
163 }
164}
165
166void* map_next(map_node_t *map)
167{
168 if (map) {
169 while (1) {
170 if (map->cur_data) {
171 void *result = map->cur_data;
172 map->cur_data = map->cur_data->next;
173 return result;
174 } else {
175 map->cur_index++;
176 if (map->cur_index < map->capacity) {
177 map->cur_data = map->map_array[map->cur_index];
178 } else { // Finish
179 return NULL;
180 }
181 }
182 }
183 } else {
184 return NULL;
185 }
186}
187
188void map_clear(map_node_t* map)
189{
190 if (map) {
191 uint32 i = 0;
192 map_data_t *ptr = NULL;
193 while (i < map->capacity) {
194 ptr = map->map_array[i];
195 while (ptr) {
196 map->map_array[i] = ptr->next;
197
198 free(ptr->key);
199 if (map->free_func) {
200 map->free_func(ptr->value);
201 }
202 free(ptr);
203
204 ptr = map->map_array[i];
205 }
206 i++;
207 }
208
209 map->size = 0;
210 map->cur_index = 0;
211 map->cur_data = NULL;
212 memset(map->map_array, 0x0,
213 sizeof(sizeof(map_data_t*) * map->capacity));
214 }
215}
216
217void map_free(map_node_t* map)
218{
219 if (map) {
220 uint32 i = 0;
221 map_data_t *ptr = NULL;
222 while (i < map->capacity) {
223 ptr = map->map_array[i];
224 while (ptr) {
225 map->map_array[i] = ptr->next;
226
227 free(ptr->key);
228 if (map->free_func) {
229 map->free_func(ptr->value);
230 }
231 free(ptr);
232
233 ptr = map->map_array[i];
234 }
235 i++;
236 }
237
238 free(map->map_array);
239 free(map);
240 }
241}
242