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 2013 Olaf Wintermann. All rights reserved. |
4 * Copyright 2015 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 |
42 |
42 |
43 if(!allocator) { |
43 if(!allocator) { |
44 allocator = ucx_default_allocator(); |
44 allocator = ucx_default_allocator(); |
45 } |
45 } |
46 |
46 |
47 UcxMap *map = (UcxMap*)allocator->malloc(allocator->pool, sizeof(UcxMap)); |
47 UcxMap *map = (UcxMap*)almalloc(allocator, sizeof(UcxMap)); |
48 if (!map) { |
48 if (!map) { |
49 return NULL; |
49 return NULL; |
50 } |
50 } |
51 |
51 |
52 map->allocator = allocator; |
52 map->allocator = allocator; |
53 map->map = (UcxMapElement**)allocator->calloc( |
53 map->map = (UcxMapElement**)alcalloc( |
54 allocator->pool, |
54 allocator, size, sizeof(UcxMapElement*)); |
55 size, |
|
56 sizeof(UcxMapElement*)); |
|
57 if(map->map == NULL) { |
55 if(map->map == NULL) { |
58 allocator->free(allocator->pool, map); |
56 alfree(allocator, map); |
59 return NULL; |
57 return NULL; |
60 } |
58 } |
61 map->size = size; |
59 map->size = size; |
62 map->count = 0; |
60 map->count = 0; |
63 |
61 |
64 return map; |
62 return map; |
65 } |
63 } |
66 |
64 |
67 static void ucx_map_free_elmlist(UcxMap *map) { |
65 static void ucx_map_free_elmlist_contents(UcxMap *map) { |
68 for (size_t n = 0 ; n < map->size ; n++) { |
66 for (size_t n = 0 ; n < map->size ; n++) { |
69 UcxMapElement *elem = map->map[n]; |
67 UcxMapElement *elem = map->map[n]; |
70 if (elem != NULL) { |
68 if (elem != NULL) { |
71 do { |
69 do { |
72 UcxMapElement *next = elem->next; |
70 UcxMapElement *next = elem->next; |
73 map->allocator->free(map->allocator->pool, elem->key.data); |
71 alfree(map->allocator, elem->key.data); |
74 map->allocator->free(map->allocator->pool, elem); |
72 alfree(map->allocator, elem); |
75 elem = next; |
73 elem = next; |
76 } while (elem != NULL); |
74 } while (elem != NULL); |
77 } |
75 } |
78 } |
76 } |
79 map->allocator->free(map->allocator->pool, map->map); |
|
80 } |
77 } |
81 |
78 |
82 void ucx_map_free(UcxMap *map) { |
79 void ucx_map_free(UcxMap *map) { |
83 ucx_map_free_elmlist(map); |
80 ucx_map_free_elmlist_contents(map); |
84 map->allocator->free(map->allocator->pool, map); |
81 alfree(map->allocator, map->map); |
|
82 alfree(map->allocator, map); |
|
83 } |
|
84 |
|
85 void ucx_map_free_content(UcxMap *map, ucx_destructor destr) { |
|
86 UcxMapIterator iter = ucx_map_iterator(map); |
|
87 void *val; |
|
88 UCX_MAP_FOREACH(key, val, iter) { |
|
89 destr(val); |
|
90 } |
|
91 } |
|
92 |
|
93 void ucx_map_clear(UcxMap *map) { |
|
94 if (map->count == 0) { |
|
95 return; // nothing to do |
|
96 } |
|
97 ucx_map_free_elmlist_contents(map); |
|
98 memset(map->map, 0, map->size*sizeof(UcxMapElement*)); |
|
99 map->count = 0; |
85 } |
100 } |
86 |
101 |
87 int ucx_map_copy(UcxMap *restrict from, UcxMap *restrict to, |
102 int ucx_map_copy(UcxMap *restrict from, UcxMap *restrict to, |
88 copy_func fnc, void *data) { |
103 copy_func fnc, void *data) { |
89 UcxMapIterator i = ucx_map_iterator(from); |
104 UcxMapIterator i = ucx_map_iterator(from); |
114 oldmap.size = map->size; |
129 oldmap.size = map->size; |
115 oldmap.count = map->count; |
130 oldmap.count = map->count; |
116 oldmap.allocator = map->allocator; |
131 oldmap.allocator = map->allocator; |
117 |
132 |
118 map->size = (map->count * 5) >> 1; |
133 map->size = (map->count * 5) >> 1; |
119 map->map = (UcxMapElement**)map->allocator->calloc( |
134 map->map = (UcxMapElement**)alcalloc( |
120 map->allocator->pool, |
135 map->allocator, map->size, sizeof(UcxMapElement*)); |
121 map->size, |
|
122 sizeof(UcxMapElement*)); |
|
123 if (!map->map) { |
136 if (!map->map) { |
124 *map = oldmap; |
137 *map = oldmap; |
125 return 1; |
138 return 1; |
126 } |
139 } |
127 map->count = 0; |
140 map->count = 0; |
128 ucx_map_copy(&oldmap, map, NULL, NULL); |
141 ucx_map_copy(&oldmap, map, NULL, NULL); |
129 |
142 |
130 /* free the UcxMapElement list of oldmap */ |
143 /* free the UcxMapElement list of oldmap */ |
131 ucx_map_free_elmlist(&oldmap); |
144 ucx_map_free_elmlist_contents(&oldmap); |
|
145 alfree(map->allocator, oldmap.map); |
132 } |
146 } |
133 return 0; |
147 return 0; |
134 } |
148 } |
135 |
149 |
136 int ucx_map_put(UcxMap *map, UcxKey key, void *data) { |
150 int ucx_map_put(UcxMap *map, UcxKey key, void *data) { |