ucx/map.c

changeset 17
11dffb40cd91
parent 5
88625853ae74
child 70
88092b88ec00
equal deleted inserted replaced
16:5dbef9e07376 17:11dffb40cd91
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*)allocator->malloc(allocator->pool, sizeof(UcxMap));
48 if(map == NULL) { 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**)allocator->calloc(
87 int ucx_map_copy(UcxMap *restrict from, UcxMap *restrict to, 87 int ucx_map_copy(UcxMap *restrict from, UcxMap *restrict to,
88 copy_func fnc, void *data) { 88 copy_func fnc, void *data) {
89 UcxMapIterator i = ucx_map_iterator(from); 89 UcxMapIterator i = ucx_map_iterator(from);
90 void *value; 90 void *value;
91 UCX_MAP_FOREACH(key, value, i) { 91 UCX_MAP_FOREACH(key, value, i) {
92 int ret = ucx_map_put(to, i.cur->key, fnc ? fnc(value, data) : value); 92 if (ucx_map_put(to, key, fnc ? fnc(value, data) : value)) {
93 if(ret != 0) {
94 return 1; 93 return 1;
95 } 94 }
96 } 95 }
97 return 0; 96 return 0;
98 } 97 }
99 98
100 UcxMap *ucx_map_clone(UcxMap *map, copy_func fnc, void *data) { 99 UcxMap *ucx_map_clone(UcxMap *map, copy_func fnc, void *data) {
101 size_t bs = (map->count * 5) >> 1; 100 size_t bs = (map->count * 5) >> 1;
102 UcxMap *newmap = ucx_map_new(bs > map->size ? bs : map->size); 101 UcxMap *newmap = ucx_map_new(bs > map->size ? bs : map->size);
103 if(newmap == NULL) { 102 if (!newmap) {
104 return NULL; 103 return NULL;
105 } 104 }
106 ucx_map_copy(map, newmap, fnc, data); 105 ucx_map_copy(map, newmap, fnc, data);
107 return newmap; 106 return newmap;
108 } 107 }
119 map->size = (map->count * 5) >> 1; 118 map->size = (map->count * 5) >> 1;
120 map->map = (UcxMapElement**)map->allocator->calloc( 119 map->map = (UcxMapElement**)map->allocator->calloc(
121 map->allocator->pool, 120 map->allocator->pool,
122 map->size, 121 map->size,
123 sizeof(UcxMapElement*)); 122 sizeof(UcxMapElement*));
124 if(map->map == NULL) { 123 if (!map->map) {
125 *map = oldmap; 124 *map = oldmap;
126 return 1; 125 return 1;
127 } 126 }
128 map->count = 0; 127 map->count = 0;
129 ucx_map_copy(&oldmap, map, NULL, NULL); 128 ucx_map_copy(&oldmap, map, NULL, NULL);
135 } 134 }
136 135
137 int ucx_map_put(UcxMap *map, UcxKey key, void *data) { 136 int ucx_map_put(UcxMap *map, UcxKey key, void *data) {
138 UcxAllocator *allocator = map->allocator; 137 UcxAllocator *allocator = map->allocator;
139 138
140 if(key.hash == 0) { 139 if (key.hash == 0) {
141 key.hash = ucx_hash((char*)key.data, key.len); 140 key.hash = ucx_hash((char*)key.data, key.len);
142 } 141 }
143 142
144 size_t slot = key.hash%map->size; 143 size_t slot = key.hash%map->size;
145 UcxMapElement *restrict elm = map->map[slot]; 144 UcxMapElement *restrict elm = map->map[slot];
146 UcxMapElement *restrict prev = NULL; 145 UcxMapElement *restrict prev = NULL;
147 146
148 while (elm != NULL && elm->key.hash < key.hash) { 147 while (elm && elm->key.hash < key.hash) {
149 prev = elm; 148 prev = elm;
150 elm = elm->next; 149 elm = elm->next;
151 } 150 }
152 151
153 if (elm == NULL || elm->key.hash != key.hash) { 152 if (!elm || elm->key.hash != key.hash) {
154 UcxMapElement *e = (UcxMapElement*)allocator->malloc( 153 UcxMapElement *e = (UcxMapElement*)allocator->malloc(
155 allocator->pool, 154 allocator->pool,
156 sizeof(UcxMapElement)); 155 sizeof(UcxMapElement));
157 if(e == NULL) { 156 if (!e) {
158 return -1; 157 return -1;
159 } 158 }
160 e->key.data = NULL; 159 e->key.data = NULL;
161 if (prev) { 160 if (prev) {
162 prev->next = e; 161 prev->next = e;
165 } 164 }
166 e->next = elm; 165 e->next = elm;
167 elm = e; 166 elm = e;
168 } 167 }
169 168
170 if(elm->key.data == NULL) { 169 if (!elm->key.data) {
171 void *kd = allocator->malloc(allocator->pool, key.len); 170 void *kd = allocator->malloc(allocator->pool, key.len);
172 if (kd == NULL) { 171 if (!kd) {
173 return -1; 172 return -1;
174 } 173 }
175 memcpy(kd, key.data, key.len); 174 memcpy(kd, key.data, key.len);
176 key.data = kd; 175 key.data = kd;
177 elm->key = key; 176 elm->key = key;
199 if (pelm) { 198 if (pelm) {
200 pelm->next = elm->next; 199 pelm->next = elm->next;
201 } else { 200 } else {
202 map->map[slot] = elm->next; 201 map->map[slot] = elm->next;
203 } 202 }
203 map->allocator->free(map->allocator->pool, elm->key.data);
204 map->allocator->free(map->allocator->pool, elm); 204 map->allocator->free(map->allocator->pool, elm);
205 map->count--; 205 map->count--;
206 } 206 }
207 207
208 return data; 208 return data;
283 } 283 }
284 284
285 int ucx_map_iter_next(UcxMapIterator *i, UcxKey *key, void **elm) { 285 int ucx_map_iter_next(UcxMapIterator *i, UcxKey *key, void **elm) {
286 UcxMapElement *e = i->cur; 286 UcxMapElement *e = i->cur;
287 287
288 if(e == NULL) { 288 if (e) {
289 e = e->next;
290 } else {
289 e = i->map->map[0]; 291 e = i->map->map[0];
290 } else { 292 }
291 e = e->next; 293
292 } 294 while (i->index < i->map->size) {
293 295 if (e) {
294 while(i->index < i->map->size) { 296 if (e->data) {
295 if(e != NULL) {
296 if(e->data != NULL) {
297 i->cur = e; 297 i->cur = e;
298 *elm = e->data; 298 *elm = e->data;
299 *key = e->key; 299 *key = e->key;
300 return 0; 300 return 1;
301 } 301 }
302 302
303 e = e->next; 303 e = e->next;
304 } else { 304 } else {
305 i->index++; 305 i->index++;
306 306
307 if(i->index < i->map->size) { 307 if (i->index < i->map->size) {
308 e = i->map->map[i->index]; 308 e = i->map->map[i->index];
309 } 309 }
310 } 310 }
311 } 311 }
312 312
313 return 1; 313 return 0;
314 } 314 }
315 315

mercurial