src/hash_map.c

changeset 1115
6db21dee4929
parent 1114
ad5eeb256242
equal deleted inserted replaced
1114:ad5eeb256242 1115:6db21dee4929
251 ) { 251 ) {
252 return cx_hash_map_get_remove(map, key, targetbuf, true); 252 return cx_hash_map_get_remove(map, key, targetbuf, true);
253 } 253 }
254 254
255 static void *cx_hash_map_iter_current_entry(const void *it) { 255 static void *cx_hash_map_iter_current_entry(const void *it) {
256 const struct cx_iterator_s *iter = it; 256 const CxMapIterator *iter = it;
257 // struct has to have a compatible signature 257 // we have to cast away const, because of the signature
258 return (struct cx_map_entry_s *) &(iter->kv_data); 258 return (void*) &iter->entry;
259 } 259 }
260 260
261 static void *cx_hash_map_iter_current_key(const void *it) { 261 static void *cx_hash_map_iter_current_key(const void *it) {
262 const struct cx_iterator_s *iter = it; 262 const CxMapIterator *iter = it;
263 struct cx_hash_map_element_s *elm = iter->elem_handle; 263 struct cx_hash_map_element_s *elm = iter->elem;
264 return &elm->key; 264 return &elm->key;
265 } 265 }
266 266
267 static void *cx_hash_map_iter_current_value(const void *it) { 267 static void *cx_hash_map_iter_current_value(const void *it) {
268 const struct cx_iterator_s *iter = it; 268 const CxMapIterator *iter = it;
269 const struct cx_hash_map_s *map = iter->src_handle.c; 269 const CxMap *map = iter->map.c;
270 struct cx_hash_map_element_s *elm = iter->elem_handle; 270 struct cx_hash_map_element_s *elm = iter->elem;
271 if (map->base.collection.store_pointer) { 271 if (map->collection.store_pointer) {
272 return *(void **) elm->data; 272 return *(void **) elm->data;
273 } else { 273 } else {
274 return elm->data; 274 return elm->data;
275 } 275 }
276 } 276 }
277 277
278 static bool cx_hash_map_iter_valid(const void *it) { 278 static bool cx_hash_map_iter_valid(const void *it) {
279 const struct cx_iterator_s *iter = it; 279 const CxMapIterator *iter = it;
280 return iter->elem_handle != NULL; 280 return iter->elem != NULL;
281 } 281 }
282 282
283 static void cx_hash_map_iter_next(void *it) { 283 static void cx_hash_map_iter_next(void *it) {
284 struct cx_iterator_s *iter = it; 284 CxMapIterator *iter = it;
285 struct cx_hash_map_element_s *elm = iter->elem_handle; 285 CxMap *map = iter->map.m;
286 struct cx_hash_map_s *map = iter->src_handle.m; 286 struct cx_hash_map_s *hmap = (struct cx_hash_map_s *) map;
287 struct cx_hash_map_element_s *elm = iter->elem;
287 288
288 // remove current element, if asked 289 // remove current element, if asked
289 if (iter->base.remove) { 290 if (iter->base.remove) {
290 291
291 // clear the flag 292 // clear the flag
294 // determine the next element 295 // determine the next element
295 struct cx_hash_map_element_s *next = elm->next; 296 struct cx_hash_map_element_s *next = elm->next;
296 297
297 // search the previous element 298 // search the previous element
298 struct cx_hash_map_element_s *prev = NULL; 299 struct cx_hash_map_element_s *prev = NULL;
299 if (map->buckets[iter->slot] != elm) { 300 if (hmap->buckets[iter->slot] != elm) {
300 prev = map->buckets[iter->slot]; 301 prev = hmap->buckets[iter->slot];
301 while (prev->next != elm) { 302 while (prev->next != elm) {
302 prev = prev->next; 303 prev = prev->next;
303 } 304 }
304 } 305 }
305 306
306 // destroy 307 // destroy
307 cx_invoke_destructor((struct cx_map_s *) map, elm->data); 308 cx_invoke_destructor(map, elm->data);
308 309
309 // unlink 310 // unlink
310 cx_hash_map_unlink(map, iter->slot, prev, elm); 311 cx_hash_map_unlink(hmap, iter->slot, prev, elm);
311 312
312 // advance 313 // advance
313 elm = next; 314 elm = next;
314 } else { 315 } else {
315 // just advance 316 // just advance
316 elm = elm->next; 317 elm = elm->next;
317 iter->index++; 318 iter->index++;
318 } 319 }
319 320
320 // search the next bucket, if required 321 // search the next bucket, if required
321 while (elm == NULL && ++iter->slot < map->bucket_count) { 322 while (elm == NULL && ++iter->slot < hmap->bucket_count) {
322 elm = map->buckets[iter->slot]; 323 elm = hmap->buckets[iter->slot];
323 } 324 }
324 325 iter->elem = elm;
325 // fill the struct with the next element 326
326 iter->elem_handle = elm; 327 // copy data to a location where the iterator can point to
327 if (elm == NULL) { 328 // we need to do it here, because the iterator function call
328 iter->kv_data.key = NULL; 329 // must not modify the iterator (the parameter is const)
329 iter->kv_data.value = NULL; 330 if (elm != NULL) {
330 } else { 331 iter->entry.key = &elm->key;
331 iter->kv_data.key = &elm->key; 332 if (iter->map.c->collection.store_pointer) {
332 if (map->base.collection.store_pointer) { 333 iter->entry.value = *(void **) elm->data;
333 iter->kv_data.value = *(void **) elm->data;
334 } else { 334 } else {
335 iter->kv_data.value = elm->data; 335 iter->entry.value = elm->data;
336 } 336 }
337 } 337 }
338 } 338 }
339 339
340 static CxIterator cx_hash_map_iterator( 340 static CxMapIterator cx_hash_map_iterator(
341 const CxMap *map, 341 const CxMap *map,
342 enum cx_map_iterator_type type 342 enum cx_map_iterator_type type
343 ) { 343 ) {
344 CxIterator iter; 344 CxMapIterator iter;
345 345
346 iter.src_handle.c = map; 346 iter.map.c = map;
347 iter.elem_count = map->collection.size; 347 iter.elem_count = map->collection.size;
348 348
349 switch (type) { 349 switch (type) {
350 case CX_MAP_ITERATOR_PAIRS: 350 case CX_MAP_ITERATOR_PAIRS:
351 iter.elem_size = sizeof(CxMapEntry); 351 iter.elem_size = sizeof(CxMapEntry);
375 struct cx_hash_map_s *hash_map = (struct cx_hash_map_s *) map; 375 struct cx_hash_map_s *hash_map = (struct cx_hash_map_s *) map;
376 struct cx_hash_map_element_s *elm = hash_map->buckets[0]; 376 struct cx_hash_map_element_s *elm = hash_map->buckets[0];
377 while (elm == NULL) { 377 while (elm == NULL) {
378 elm = hash_map->buckets[++iter.slot]; 378 elm = hash_map->buckets[++iter.slot];
379 } 379 }
380 iter.elem_handle = elm; 380 iter.elem = elm;
381 iter.kv_data.key = &elm->key; 381 iter.entry.key = &elm->key;
382 if (map->collection.store_pointer) { 382 if (map->collection.store_pointer) {
383 iter.kv_data.value = *(void **) elm->data; 383 iter.entry.value = *(void **) elm->data;
384 } else { 384 } else {
385 iter.kv_data.value = elm->data; 385 iter.entry.value = elm->data;
386 } 386 }
387 } else { 387 } else {
388 iter.elem_handle = NULL; 388 iter.elem = NULL;
389 iter.kv_data.key = NULL;
390 iter.kv_data.value = NULL;
391 } 389 }
392 390
393 return iter; 391 return iter;
394 } 392 }
395 393

mercurial