1 /* |
1 /* |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 * |
3 * |
4 * Copyright 2016 Olaf Wintermann. All rights reserved. |
4 * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved. |
5 * |
5 * |
6 * Redistribution and use in source and binary forms, with or without |
6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions are met: |
7 * modification, are permitted provided that the following conditions are met: |
8 * |
8 * |
9 * 1. Redistributions of source code must retain the above copyright |
9 * 1. Redistributions of source code must retain the above copyright |
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 * POSSIBILITY OF SUCH DAMAGE. |
26 * POSSIBILITY OF SUCH DAMAGE. |
27 */ |
27 */ |
28 |
28 |
|
29 #include "ucx/map.h" |
|
30 |
29 #include <stdlib.h> |
31 #include <stdlib.h> |
30 #include <string.h> |
32 #include <string.h> |
31 |
|
32 #include "map.h" |
|
33 |
33 |
34 UcxMap *ucx_map_new(size_t size) { |
34 UcxMap *ucx_map_new(size_t size) { |
35 return ucx_map_new_a(NULL, size); |
35 return ucx_map_new_a(NULL, size); |
36 } |
36 } |
37 |
37 |
97 ucx_map_free_elmlist_contents(map); |
97 ucx_map_free_elmlist_contents(map); |
98 memset(map->map, 0, map->size*sizeof(UcxMapElement*)); |
98 memset(map->map, 0, map->size*sizeof(UcxMapElement*)); |
99 map->count = 0; |
99 map->count = 0; |
100 } |
100 } |
101 |
101 |
102 int ucx_map_copy(UcxMap *restrict from, UcxMap *restrict to, |
102 int ucx_map_copy(UcxMap *from, UcxMap *to, copy_func fnc, void *data) { |
103 copy_func fnc, void *data) { |
|
104 UcxMapIterator i = ucx_map_iterator(from); |
103 UcxMapIterator i = ucx_map_iterator(from); |
105 void *value; |
104 void *value; |
106 UCX_MAP_FOREACH(key, value, i) { |
105 UCX_MAP_FOREACH(key, value, i) { |
107 if (ucx_map_put(to, key, fnc ? fnc(value, data) : value)) { |
106 if (ucx_map_put(to, key, fnc ? fnc(value, data) : value)) { |
108 return 1; |
107 return 1; |
153 if (key.hash == 0) { |
152 if (key.hash == 0) { |
154 key.hash = ucx_hash((char*)key.data, key.len); |
153 key.hash = ucx_hash((char*)key.data, key.len); |
155 } |
154 } |
156 |
155 |
157 size_t slot = key.hash%map->size; |
156 size_t slot = key.hash%map->size; |
158 UcxMapElement *restrict elm = map->map[slot]; |
157 UcxMapElement *elm = map->map[slot]; |
159 UcxMapElement *restrict prev = NULL; |
158 UcxMapElement *prev = NULL; |
160 |
159 |
161 while (elm && elm->key.hash < key.hash) { |
160 while (elm && elm->key.hash < key.hash) { |
162 prev = elm; |
161 prev = elm; |
163 elm = elm->next; |
162 elm = elm->next; |
164 } |
163 } |
192 elm->data = data; |
191 elm->data = data; |
193 |
192 |
194 return 0; |
193 return 0; |
195 } |
194 } |
196 |
195 |
197 void* ucx_map_get_and_remove(UcxMap *map, UcxKey key, _Bool remove) { |
196 static void* ucx_map_get_and_remove(UcxMap *map, UcxKey key, int remove) { |
198 if(key.hash == 0) { |
197 if(key.hash == 0) { |
199 key.hash = ucx_hash((char*)key.data, key.len); |
198 key.hash = ucx_hash((char*)key.data, key.len); |
200 } |
199 } |
201 |
200 |
202 size_t slot = key.hash%map->size; |
201 size_t slot = key.hash%map->size; |
203 UcxMapElement *restrict elm = map->map[slot]; |
202 UcxMapElement *elm = map->map[slot]; |
204 UcxMapElement *restrict pelm = NULL; |
203 UcxMapElement *pelm = NULL; |
205 while (elm && elm->key.hash <= key.hash) { |
204 while (elm && elm->key.hash <= key.hash) { |
206 if(elm->key.hash == key.hash) { |
205 if(elm->key.hash == key.hash) { |
207 int n = (key.len > elm->key.len) ? elm->key.len : key.len; |
206 int n = (key.len > elm->key.len) ? elm->key.len : key.len; |
208 if (memcmp(elm->key.data, key.data, n) == 0) { |
207 if (memcmp(elm->key.data, key.data, n) == 0) { |
209 void *data = elm->data; |
208 void *data = elm->data; |