ucx/map.c

changeset 124
80609f9675f1
parent 0
1f419bd32da1
child 152
62921b370c60
equal deleted inserted replaced
123:55adc92e7c09 124:80609f9675f1
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) {
148 prev = elm; 162 prev = elm;
149 elm = elm->next; 163 elm = elm->next;
150 } 164 }
151 165
152 if (!elm || elm->key.hash != key.hash) { 166 if (!elm || elm->key.hash != key.hash) {
153 UcxMapElement *e = (UcxMapElement*)allocator->malloc( 167 UcxMapElement *e = (UcxMapElement*)almalloc(
154 allocator->pool, 168 allocator, sizeof(UcxMapElement));
155 sizeof(UcxMapElement));
156 if (!e) { 169 if (!e) {
157 return -1; 170 return -1;
158 } 171 }
159 e->key.data = NULL; 172 e->key.data = NULL;
160 if (prev) { 173 if (prev) {
165 e->next = elm; 178 e->next = elm;
166 elm = e; 179 elm = e;
167 } 180 }
168 181
169 if (!elm->key.data) { 182 if (!elm->key.data) {
170 void *kd = allocator->malloc(allocator->pool, key.len); 183 void *kd = almalloc(allocator, key.len);
171 if (!kd) { 184 if (!kd) {
172 return -1; 185 return -1;
173 } 186 }
174 memcpy(kd, key.data, key.len); 187 memcpy(kd, key.data, key.len);
175 key.data = kd; 188 key.data = kd;
198 if (pelm) { 211 if (pelm) {
199 pelm->next = elm->next; 212 pelm->next = elm->next;
200 } else { 213 } else {
201 map->map[slot] = elm->next; 214 map->map[slot] = elm->next;
202 } 215 }
203 map->allocator->free(map->allocator->pool, elm->key.data); 216 alfree(map->allocator, elm->key.data);
204 map->allocator->free(map->allocator->pool, elm); 217 alfree(map->allocator, elm);
205 map->count--; 218 map->count--;
206 } 219 }
207 220
208 return data; 221 return data;
209 } 222 }

mercurial