aboutsummaryrefslogtreecommitdiff
path: root/src/util/container_multishortmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/container_multishortmap.c')
-rw-r--r--src/util/container_multishortmap.c781
1 files changed, 393 insertions, 388 deletions
diff --git a/src/util/container_multishortmap.c b/src/util/container_multishortmap.c
index 4f2bc149d..86ab31107 100644
--- a/src/util/container_multishortmap.c
+++ b/src/util/container_multishortmap.c
@@ -27,7 +27,7 @@
27#include "gnunet_util_lib.h" 27#include "gnunet_util_lib.h"
28 28
29#define LOG(kind, ...) \ 29#define LOG(kind, ...) \
30 GNUNET_log_from(kind, "util-container-multishortmap", __VA_ARGS__) 30 GNUNET_log_from (kind, "util-container-multishortmap", __VA_ARGS__)
31 31
32/** 32/**
33 * Maximum recursion depth for callbacks of 33 * Maximum recursion depth for callbacks of
@@ -41,7 +41,8 @@
41/** 41/**
42 * An entry in the hash map with the full key. 42 * An entry in the hash map with the full key.
43 */ 43 */
44struct BigMapEntry { 44struct BigMapEntry
45{
45 /** 46 /**
46 * Value of the entry. 47 * Value of the entry.
47 */ 48 */
@@ -62,7 +63,8 @@ struct BigMapEntry {
62/** 63/**
63 * An entry in the hash map with just a pointer to the key. 64 * An entry in the hash map with just a pointer to the key.
64 */ 65 */
65struct SmallMapEntry { 66struct SmallMapEntry
67{
66 /** 68 /**
67 * Value of the entry. 69 * Value of the entry.
68 */ 70 */
@@ -83,7 +85,8 @@ struct SmallMapEntry {
83/** 85/**
84 * Entry in the map. 86 * Entry in the map.
85 */ 87 */
86union MapEntry { 88union MapEntry
89{
87 /** 90 /**
88 * Variant used if map entries only contain a pointer to the key. 91 * Variant used if map entries only contain a pointer to the key.
89 */ 92 */
@@ -99,7 +102,8 @@ union MapEntry {
99/** 102/**
100 * Internal representation of the hash map. 103 * Internal representation of the hash map.
101 */ 104 */
102struct GNUNET_CONTAINER_MultiShortmap { 105struct GNUNET_CONTAINER_MultiShortmap
106{
103 /** 107 /**
104 * All of our buckets. 108 * All of our buckets.
105 */ 109 */
@@ -146,7 +150,8 @@ struct GNUNET_CONTAINER_MultiShortmap {
146 * Cursor into a multishortmap. 150 * Cursor into a multishortmap.
147 * Allows to enumerate elements asynchronously. 151 * Allows to enumerate elements asynchronously.
148 */ 152 */
149struct GNUNET_CONTAINER_MultiShortmapIterator { 153struct GNUNET_CONTAINER_MultiShortmapIterator
154{
150 /** 155 /**
151 * Position in the bucket 'idx' 156 * Position in the bucket 'idx'
152 */ 157 */
@@ -186,18 +191,18 @@ struct GNUNET_CONTAINER_MultiShortmapIterator {
186 * @return NULL on error 191 * @return NULL on error
187 */ 192 */
188struct GNUNET_CONTAINER_MultiShortmap * 193struct GNUNET_CONTAINER_MultiShortmap *
189GNUNET_CONTAINER_multishortmap_create(unsigned int len, int do_not_copy_keys) 194GNUNET_CONTAINER_multishortmap_create (unsigned int len, int do_not_copy_keys)
190{ 195{
191 struct GNUNET_CONTAINER_MultiShortmap *map; 196 struct GNUNET_CONTAINER_MultiShortmap *map;
192 197
193 GNUNET_assert(len > 0); 198 GNUNET_assert (len > 0);
194 map = GNUNET_new(struct GNUNET_CONTAINER_MultiShortmap); 199 map = GNUNET_new (struct GNUNET_CONTAINER_MultiShortmap);
195 map->map = GNUNET_malloc_large(len * sizeof(union MapEntry)); 200 map->map = GNUNET_malloc_large (len * sizeof(union MapEntry));
196 if (NULL == map->map) 201 if (NULL == map->map)
197 { 202 {
198 GNUNET_free(map); 203 GNUNET_free (map);
199 return NULL; 204 return NULL;
200 } 205 }
201 map->map_length = len; 206 map->map_length = len;
202 map->use_small_entries = do_not_copy_keys; 207 map->use_small_entries = do_not_copy_keys;
203 return map; 208 return map;
@@ -211,44 +216,44 @@ GNUNET_CONTAINER_multishortmap_create(unsigned int len, int do_not_copy_keys)
211 * @param map the map 216 * @param map the map
212 */ 217 */
213void 218void
214GNUNET_CONTAINER_multishortmap_destroy( 219GNUNET_CONTAINER_multishortmap_destroy (
215 struct GNUNET_CONTAINER_MultiShortmap *map) 220 struct GNUNET_CONTAINER_MultiShortmap *map)
216{ 221{
217 GNUNET_assert(0 == map->next_cache_off); 222 GNUNET_assert (0 == map->next_cache_off);
218 for (unsigned int i = 0; i < map->map_length; i++) 223 for (unsigned int i = 0; i < map->map_length; i++)
219 { 224 {
220 union MapEntry me; 225 union MapEntry me;
221 226
222 me = map->map[i]; 227 me = map->map[i];
223 if (map->use_small_entries) 228 if (map->use_small_entries)
224 { 229 {
225 struct SmallMapEntry *sme; 230 struct SmallMapEntry *sme;
226 struct SmallMapEntry *nxt; 231 struct SmallMapEntry *nxt;
227 232
228 nxt = me.sme; 233 nxt = me.sme;
229 while (NULL != (sme = nxt)) 234 while (NULL != (sme = nxt))
230 { 235 {
231 nxt = sme->next; 236 nxt = sme->next;
232 GNUNET_free(sme); 237 GNUNET_free (sme);
233 } 238 }
234 me.sme = NULL; 239 me.sme = NULL;
235 }
236 else
237 {
238 struct BigMapEntry *bme;
239 struct BigMapEntry *nxt;
240
241 nxt = me.bme;
242 while (NULL != (bme = nxt))
243 {
244 nxt = bme->next;
245 GNUNET_free(bme);
246 }
247 me.bme = NULL;
248 }
249 } 240 }
250 GNUNET_free(map->map); 241 else
251 GNUNET_free(map); 242 {
243 struct BigMapEntry *bme;
244 struct BigMapEntry *nxt;
245
246 nxt = me.bme;
247 while (NULL != (bme = nxt))
248 {
249 nxt = bme->next;
250 GNUNET_free (bme);
251 }
252 me.bme = NULL;
253 }
254 }
255 GNUNET_free (map->map);
256 GNUNET_free (map);
252} 257}
253 258
254 259
@@ -260,13 +265,13 @@ GNUNET_CONTAINER_multishortmap_destroy(
260 * @return offset into the "map" array of "map" 265 * @return offset into the "map" array of "map"
261 */ 266 */
262static unsigned int 267static unsigned int
263idx_of(const struct GNUNET_CONTAINER_MultiShortmap *map, 268idx_of (const struct GNUNET_CONTAINER_MultiShortmap *map,
264 const struct GNUNET_ShortHashCode *key) 269 const struct GNUNET_ShortHashCode *key)
265{ 270{
266 unsigned int kx; 271 unsigned int kx;
267 272
268 GNUNET_assert(NULL != map); 273 GNUNET_assert (NULL != map);
269 GNUNET_memcpy(&kx, key, sizeof(kx)); 274 GNUNET_memcpy (&kx, key, sizeof(kx));
270 return kx % map->map_length; 275 return kx % map->map_length;
271} 276}
272 277
@@ -278,7 +283,7 @@ idx_of(const struct GNUNET_CONTAINER_MultiShortmap *map,
278 * @return the number of key value pairs 283 * @return the number of key value pairs
279 */ 284 */
280unsigned int 285unsigned int
281GNUNET_CONTAINER_multishortmap_size( 286GNUNET_CONTAINER_multishortmap_size (
282 const struct GNUNET_CONTAINER_MultiShortmap *map) 287 const struct GNUNET_CONTAINER_MultiShortmap *map)
283{ 288{
284 return map->size; 289 return map->size;
@@ -296,25 +301,25 @@ GNUNET_CONTAINER_multishortmap_size(
296 * key-value pairs with value NULL 301 * key-value pairs with value NULL
297 */ 302 */
298void * 303void *
299GNUNET_CONTAINER_multishortmap_get( 304GNUNET_CONTAINER_multishortmap_get (
300 const struct GNUNET_CONTAINER_MultiShortmap *map, 305 const struct GNUNET_CONTAINER_MultiShortmap *map,
301 const struct GNUNET_ShortHashCode *key) 306 const struct GNUNET_ShortHashCode *key)
302{ 307{
303 union MapEntry me; 308 union MapEntry me;
304 309
305 me = map->map[idx_of(map, key)]; 310 me = map->map[idx_of (map, key)];
306 if (map->use_small_entries) 311 if (map->use_small_entries)
307 { 312 {
308 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next) 313 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
309 if (0 == GNUNET_memcmp(key, sme->key)) 314 if (0 == GNUNET_memcmp (key, sme->key))
310 return sme->value; 315 return sme->value;
311 } 316 }
312 else 317 else
313 { 318 {
314 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next) 319 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
315 if (0 == GNUNET_memcmp(key, &bme->key)) 320 if (0 == GNUNET_memcmp (key, &bme->key))
316 return bme->value; 321 return bme->value;
317 } 322 }
318 return NULL; 323 return NULL;
319} 324}
320 325
@@ -329,7 +334,7 @@ GNUNET_CONTAINER_multishortmap_get(
329 * #GNUNET_SYSERR if it aborted iteration 334 * #GNUNET_SYSERR if it aborted iteration
330 */ 335 */
331int 336int
332GNUNET_CONTAINER_multishortmap_iterate( 337GNUNET_CONTAINER_multishortmap_iterate (
333 struct GNUNET_CONTAINER_MultiShortmap *map, 338 struct GNUNET_CONTAINER_MultiShortmap *map,
334 GNUNET_CONTAINER_ShortmapIterator it, 339 GNUNET_CONTAINER_ShortmapIterator it,
335 void *it_cls) 340 void *it_cls)
@@ -340,50 +345,50 @@ GNUNET_CONTAINER_multishortmap_iterate(
340 struct GNUNET_ShortHashCode kc; 345 struct GNUNET_ShortHashCode kc;
341 346
342 count = 0; 347 count = 0;
343 GNUNET_assert(NULL != map); 348 GNUNET_assert (NULL != map);
344 ce = &map->next_cache[map->next_cache_off]; 349 ce = &map->next_cache[map->next_cache_off];
345 GNUNET_assert(++map->next_cache_off < NEXT_CACHE_SIZE); 350 GNUNET_assert (++map->next_cache_off < NEXT_CACHE_SIZE);
346 for (unsigned int i = 0; i < map->map_length; i++) 351 for (unsigned int i = 0; i < map->map_length; i++)
352 {
353 me = map->map[i];
354 if (map->use_small_entries)
347 { 355 {
348 me = map->map[i]; 356 struct SmallMapEntry *sme;
349 if (map->use_small_entries) 357
358 ce->sme = me.sme;
359 while (NULL != (sme = ce->sme))
360 {
361 ce->sme = sme->next;
362 if ((NULL != it) && (GNUNET_OK != it (it_cls, sme->key, sme->value)))
350 { 363 {
351 struct SmallMapEntry *sme; 364 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE);
352 365 return GNUNET_SYSERR;
353 ce->sme = me.sme;
354 while (NULL != (sme = ce->sme))
355 {
356 ce->sme = sme->next;
357 if ((NULL != it) && (GNUNET_OK != it(it_cls, sme->key, sme->value)))
358 {
359 GNUNET_assert(--map->next_cache_off < NEXT_CACHE_SIZE);
360 return GNUNET_SYSERR;
361 }
362 count++;
363 }
364 } 366 }
365 else 367 count++;
368 }
369 }
370 else
371 {
372 struct BigMapEntry *bme;
373
374 ce->bme = me.bme;
375 while (NULL != (bme = ce->bme))
376 {
377 ce->bme = bme->next;
378 if (NULL != it)
366 { 379 {
367 struct BigMapEntry *bme; 380 kc = bme->key;
368 381 if (GNUNET_OK != it (it_cls, &kc, bme->value))
369 ce->bme = me.bme; 382 {
370 while (NULL != (bme = ce->bme)) 383 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE);
371 { 384 return GNUNET_SYSERR;
372 ce->bme = bme->next; 385 }
373 if (NULL != it)
374 {
375 kc = bme->key;
376 if (GNUNET_OK != it(it_cls, &kc, bme->value))
377 {
378 GNUNET_assert(--map->next_cache_off < NEXT_CACHE_SIZE);
379 return GNUNET_SYSERR;
380 }
381 }
382 count++;
383 }
384 } 386 }
387 count++;
388 }
385 } 389 }
386 GNUNET_assert(--map->next_cache_off < NEXT_CACHE_SIZE); 390 }
391 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE);
387 return count; 392 return count;
388} 393}
389 394
@@ -396,8 +401,8 @@ GNUNET_CONTAINER_multishortmap_iterate(
396 * @param bme the entry that is about to be free'd 401 * @param bme the entry that is about to be free'd
397 */ 402 */
398static void 403static void
399update_next_cache_bme(struct GNUNET_CONTAINER_MultiShortmap *map, 404update_next_cache_bme (struct GNUNET_CONTAINER_MultiShortmap *map,
400 const struct BigMapEntry *bme) 405 const struct BigMapEntry *bme)
401{ 406{
402 for (unsigned int i = 0; i < map->next_cache_off; i++) 407 for (unsigned int i = 0; i < map->next_cache_off; i++)
403 if (map->next_cache[i].bme == bme) 408 if (map->next_cache[i].bme == bme)
@@ -413,8 +418,8 @@ update_next_cache_bme(struct GNUNET_CONTAINER_MultiShortmap *map,
413 * @param sme the entry that is about to be free'd 418 * @param sme the entry that is about to be free'd
414 */ 419 */
415static void 420static void
416update_next_cache_sme(struct GNUNET_CONTAINER_MultiShortmap *map, 421update_next_cache_sme (struct GNUNET_CONTAINER_MultiShortmap *map,
417 const struct SmallMapEntry *sme) 422 const struct SmallMapEntry *sme)
418{ 423{
419 for (unsigned int i = 0; i < map->next_cache_off; i++) 424 for (unsigned int i = 0; i < map->next_cache_off; i++)
420 if (map->next_cache[i].sme == sme) 425 if (map->next_cache[i].sme == sme)
@@ -434,7 +439,7 @@ update_next_cache_sme(struct GNUNET_CONTAINER_MultiShortmap *map,
434 * is not in the map 439 * is not in the map
435 */ 440 */
436int 441int
437GNUNET_CONTAINER_multishortmap_remove( 442GNUNET_CONTAINER_multishortmap_remove (
438 struct GNUNET_CONTAINER_MultiShortmap *map, 443 struct GNUNET_CONTAINER_MultiShortmap *map,
439 const struct GNUNET_ShortHashCode *key, 444 const struct GNUNET_ShortHashCode *key,
440 const void *value) 445 const void *value)
@@ -443,48 +448,48 @@ GNUNET_CONTAINER_multishortmap_remove(
443 unsigned int i; 448 unsigned int i;
444 449
445 map->modification_counter++; 450 map->modification_counter++;
446 i = idx_of(map, key); 451 i = idx_of (map, key);
447 me = map->map[i]; 452 me = map->map[i];
448 if (map->use_small_entries) 453 if (map->use_small_entries)
449 { 454 {
450 struct SmallMapEntry *p = NULL; 455 struct SmallMapEntry *p = NULL;
451 456
452 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next) 457 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
453 { 458 {
454 if ((0 == GNUNET_memcmp(key, sme->key)) && (value == sme->value)) 459 if ((0 == GNUNET_memcmp (key, sme->key)) && (value == sme->value))
455 { 460 {
456 if (NULL == p) 461 if (NULL == p)
457 map->map[i].sme = sme->next; 462 map->map[i].sme = sme->next;
458 else 463 else
459 p->next = sme->next; 464 p->next = sme->next;
460 update_next_cache_sme(map, sme); 465 update_next_cache_sme (map, sme);
461 GNUNET_free(sme); 466 GNUNET_free (sme);
462 map->size--; 467 map->size--;
463 return GNUNET_YES; 468 return GNUNET_YES;
464 } 469 }
465 p = sme; 470 p = sme;
466 }
467 } 471 }
472 }
468 else 473 else
469 { 474 {
470 struct BigMapEntry *p = NULL; 475 struct BigMapEntry *p = NULL;
471 476
472 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next) 477 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
473 { 478 {
474 if ((0 == GNUNET_memcmp(key, &bme->key)) && (value == bme->value)) 479 if ((0 == GNUNET_memcmp (key, &bme->key)) && (value == bme->value))
475 { 480 {
476 if (NULL == p) 481 if (NULL == p)
477 map->map[i].bme = bme->next; 482 map->map[i].bme = bme->next;
478 else 483 else
479 p->next = bme->next; 484 p->next = bme->next;
480 update_next_cache_bme(map, bme); 485 update_next_cache_bme (map, bme);
481 GNUNET_free(bme); 486 GNUNET_free (bme);
482 map->size--; 487 map->size--;
483 return GNUNET_YES; 488 return GNUNET_YES;
484 } 489 }
485 p = bme; 490 p = bme;
486 }
487 } 491 }
492 }
488 return GNUNET_NO; 493 return GNUNET_NO;
489} 494}
490 495
@@ -498,7 +503,7 @@ GNUNET_CONTAINER_multishortmap_remove(
498 * @return number of values removed 503 * @return number of values removed
499 */ 504 */
500int 505int
501GNUNET_CONTAINER_multishortmap_remove_all( 506GNUNET_CONTAINER_multishortmap_remove_all (
502 struct GNUNET_CONTAINER_MultiShortmap *map, 507 struct GNUNET_CONTAINER_MultiShortmap *map,
503 const struct GNUNET_ShortHashCode *key) 508 const struct GNUNET_ShortHashCode *key)
504{ 509{
@@ -509,70 +514,70 @@ GNUNET_CONTAINER_multishortmap_remove_all(
509 map->modification_counter++; 514 map->modification_counter++;
510 515
511 ret = 0; 516 ret = 0;
512 i = idx_of(map, key); 517 i = idx_of (map, key);
513 me = map->map[i]; 518 me = map->map[i];
514 if (map->use_small_entries) 519 if (map->use_small_entries)
515 { 520 {
516 struct SmallMapEntry *sme; 521 struct SmallMapEntry *sme;
517 struct SmallMapEntry *p; 522 struct SmallMapEntry *p;
518 523
519 p = NULL; 524 p = NULL;
520 sme = me.sme; 525 sme = me.sme;
521 while (NULL != sme) 526 while (NULL != sme)
522 { 527 {
523 if (0 == GNUNET_memcmp(key, sme->key)) 528 if (0 == GNUNET_memcmp (key, sme->key))
524 { 529 {
525 if (NULL == p) 530 if (NULL == p)
526 map->map[i].sme = sme->next; 531 map->map[i].sme = sme->next;
527 else 532 else
528 p->next = sme->next; 533 p->next = sme->next;
529 update_next_cache_sme(map, sme); 534 update_next_cache_sme (map, sme);
530 GNUNET_free(sme); 535 GNUNET_free (sme);
531 map->size--; 536 map->size--;
532 if (NULL == p) 537 if (NULL == p)
533 sme = map->map[i].sme; 538 sme = map->map[i].sme;
534 else 539 else
535 sme = p->next; 540 sme = p->next;
536 ret++; 541 ret++;
537 } 542 }
538 else 543 else
539 { 544 {
540 p = sme; 545 p = sme;
541 sme = sme->next; 546 sme = sme->next;
542 } 547 }
543 }
544 } 548 }
549 }
545 else 550 else
546 { 551 {
547 struct BigMapEntry *bme; 552 struct BigMapEntry *bme;
548 struct BigMapEntry *p; 553 struct BigMapEntry *p;
549 554
550 p = NULL; 555 p = NULL;
551 bme = me.bme; 556 bme = me.bme;
552 while (NULL != bme) 557 while (NULL != bme)
553 { 558 {
554 if (0 == GNUNET_memcmp(key, &bme->key)) 559 if (0 == GNUNET_memcmp (key, &bme->key))
555 { 560 {
556 if (NULL == p) 561 if (NULL == p)
557 map->map[i].bme = bme->next; 562 map->map[i].bme = bme->next;
558 else 563 else
559 p->next = bme->next; 564 p->next = bme->next;
560 update_next_cache_bme(map, bme); 565 update_next_cache_bme (map, bme);
561 GNUNET_free(bme); 566 GNUNET_free (bme);
562 map->size--; 567 map->size--;
563 if (NULL == p) 568 if (NULL == p)
564 bme = map->map[i].bme; 569 bme = map->map[i].bme;
565 else 570 else
566 bme = p->next; 571 bme = p->next;
567 ret++; 572 ret++;
568 } 573 }
569 else 574 else
570 { 575 {
571 p = bme; 576 p = bme;
572 bme = bme->next; 577 bme = bme->next;
573 } 578 }
574 }
575 } 579 }
580 }
576 return ret; 581 return ret;
577} 582}
578 583
@@ -587,25 +592,25 @@ GNUNET_CONTAINER_multishortmap_remove_all(
587 * #GNUNET_NO if not 592 * #GNUNET_NO if not
588 */ 593 */
589int 594int
590GNUNET_CONTAINER_multishortmap_contains( 595GNUNET_CONTAINER_multishortmap_contains (
591 const struct GNUNET_CONTAINER_MultiShortmap *map, 596 const struct GNUNET_CONTAINER_MultiShortmap *map,
592 const struct GNUNET_ShortHashCode *key) 597 const struct GNUNET_ShortHashCode *key)
593{ 598{
594 union MapEntry me; 599 union MapEntry me;
595 600
596 me = map->map[idx_of(map, key)]; 601 me = map->map[idx_of (map, key)];
597 if (map->use_small_entries) 602 if (map->use_small_entries)
598 { 603 {
599 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next) 604 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
600 if (0 == GNUNET_memcmp(key, sme->key)) 605 if (0 == GNUNET_memcmp (key, sme->key))
601 return GNUNET_YES; 606 return GNUNET_YES;
602 } 607 }
603 else 608 else
604 { 609 {
605 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next) 610 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
606 if (0 == GNUNET_memcmp(key, &bme->key)) 611 if (0 == GNUNET_memcmp (key, &bme->key))
607 return GNUNET_YES; 612 return GNUNET_YES;
608 } 613 }
609 return GNUNET_NO; 614 return GNUNET_NO;
610} 615}
611 616
@@ -621,26 +626,26 @@ GNUNET_CONTAINER_multishortmap_contains(
621 * #GNUNET_NO if not 626 * #GNUNET_NO if not
622 */ 627 */
623int 628int
624GNUNET_CONTAINER_multishortmap_contains_value( 629GNUNET_CONTAINER_multishortmap_contains_value (
625 const struct GNUNET_CONTAINER_MultiShortmap *map, 630 const struct GNUNET_CONTAINER_MultiShortmap *map,
626 const struct GNUNET_ShortHashCode *key, 631 const struct GNUNET_ShortHashCode *key,
627 const void *value) 632 const void *value)
628{ 633{
629 union MapEntry me; 634 union MapEntry me;
630 635
631 me = map->map[idx_of(map, key)]; 636 me = map->map[idx_of (map, key)];
632 if (map->use_small_entries) 637 if (map->use_small_entries)
633 { 638 {
634 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next) 639 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
635 if ((0 == GNUNET_memcmp(key, sme->key)) && (sme->value == value)) 640 if ((0 == GNUNET_memcmp (key, sme->key)) && (sme->value == value))
636 return GNUNET_YES; 641 return GNUNET_YES;
637 } 642 }
638 else 643 else
639 { 644 {
640 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next) 645 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
641 if ((0 == GNUNET_memcmp(key, &bme->key)) && (bme->value == value)) 646 if ((0 == GNUNET_memcmp (key, &bme->key)) && (bme->value == value))
642 return GNUNET_YES; 647 return GNUNET_YES;
643 } 648 }
644 return GNUNET_NO; 649 return GNUNET_NO;
645} 650}
646 651
@@ -651,7 +656,7 @@ GNUNET_CONTAINER_multishortmap_contains_value(
651 * @param map the hash map to grow 656 * @param map the hash map to grow
652 */ 657 */
653static void 658static void
654grow(struct GNUNET_CONTAINER_MultiShortmap *map) 659grow (struct GNUNET_CONTAINER_MultiShortmap *map)
655{ 660{
656 union MapEntry *old_map; 661 union MapEntry *old_map;
657 union MapEntry *new_map; 662 union MapEntry *new_map;
@@ -666,40 +671,40 @@ grow(struct GNUNET_CONTAINER_MultiShortmap *map)
666 new_len = old_len; /* never use 0 */ 671 new_len = old_len; /* never use 0 */
667 if (new_len == old_len) 672 if (new_len == old_len)
668 return; /* nothing changed */ 673 return; /* nothing changed */
669 new_map = GNUNET_malloc_large(new_len * sizeof(union MapEntry)); 674 new_map = GNUNET_malloc_large (new_len * sizeof(union MapEntry));
670 if (NULL == new_map) 675 if (NULL == new_map)
671 return; /* grow not possible */ 676 return; /* grow not possible */
672 map->modification_counter++; 677 map->modification_counter++;
673 map->map_length = new_len; 678 map->map_length = new_len;
674 map->map = new_map; 679 map->map = new_map;
675 for (unsigned int i = 0; i < old_len; i++) 680 for (unsigned int i = 0; i < old_len; i++)
681 {
682 if (map->use_small_entries)
676 { 683 {
677 if (map->use_small_entries) 684 struct SmallMapEntry *sme;
678 { 685
679 struct SmallMapEntry *sme; 686 while (NULL != (sme = old_map[i].sme))
680 687 {
681 while (NULL != (sme = old_map[i].sme)) 688 old_map[i].sme = sme->next;
682 { 689 idx = idx_of (map, sme->key);
683 old_map[i].sme = sme->next; 690 sme->next = new_map[idx].sme;
684 idx = idx_of(map, sme->key); 691 new_map[idx].sme = sme;
685 sme->next = new_map[idx].sme; 692 }
686 new_map[idx].sme = sme;
687 }
688 }
689 else
690 {
691 struct BigMapEntry *bme;
692
693 while (NULL != (bme = old_map[i].bme))
694 {
695 old_map[i].bme = bme->next;
696 idx = idx_of(map, &bme->key);
697 bme->next = new_map[idx].bme;
698 new_map[idx].bme = bme;
699 }
700 }
701 } 693 }
702 GNUNET_free(old_map); 694 else
695 {
696 struct BigMapEntry *bme;
697
698 while (NULL != (bme = old_map[i].bme))
699 {
700 old_map[i].bme = bme->next;
701 idx = idx_of (map, &bme->key);
702 bme->next = new_map[idx].bme;
703 new_map[idx].bme = bme;
704 }
705 }
706 }
707 GNUNET_free (old_map);
703} 708}
704 709
705 710
@@ -716,7 +721,7 @@ grow(struct GNUNET_CONTAINER_MultiShortmap *map)
716 * value already exists 721 * value already exists
717 */ 722 */
718int 723int
719GNUNET_CONTAINER_multishortmap_put( 724GNUNET_CONTAINER_multishortmap_put (
720 struct GNUNET_CONTAINER_MultiShortmap *map, 725 struct GNUNET_CONTAINER_MultiShortmap *map,
721 const struct GNUNET_ShortHashCode *key, 726 const struct GNUNET_ShortHashCode *key,
722 void *value, 727 void *value,
@@ -725,59 +730,59 @@ GNUNET_CONTAINER_multishortmap_put(
725 union MapEntry me; 730 union MapEntry me;
726 unsigned int i; 731 unsigned int i;
727 732
728 i = idx_of(map, key); 733 i = idx_of (map, key);
729 if ((opt != GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE) && 734 if ((opt != GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE) &&
730 (opt != GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) 735 (opt != GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
736 {
737 me = map->map[i];
738 if (map->use_small_entries)
731 { 739 {
732 me = map->map[i]; 740 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
733 if (map->use_small_entries) 741 if (0 == GNUNET_memcmp (key, sme->key))
734 { 742 {
735 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next) 743 if (opt == GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)
736 if (0 == GNUNET_memcmp(key, sme->key)) 744 return GNUNET_SYSERR;
737 { 745 sme->value = value;
738 if (opt == GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY) 746 return GNUNET_NO;
739 return GNUNET_SYSERR;
740 sme->value = value;
741 return GNUNET_NO;
742 }
743 } 747 }
744 else 748 }
749 else
750 {
751 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
752 if (0 == GNUNET_memcmp (key, &bme->key))
745 { 753 {
746 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next) 754 if (opt == GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)
747 if (0 == GNUNET_memcmp(key, &bme->key)) 755 return GNUNET_SYSERR;
748 { 756 bme->value = value;
749 if (opt == GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY) 757 return GNUNET_NO;
750 return GNUNET_SYSERR;
751 bme->value = value;
752 return GNUNET_NO;
753 }
754 } 758 }
755 } 759 }
760 }
756 if (map->size / 3 >= map->map_length / 4) 761 if (map->size / 3 >= map->map_length / 4)
757 { 762 {
758 grow(map); 763 grow (map);
759 i = idx_of(map, key); 764 i = idx_of (map, key);
760 } 765 }
761 if (map->use_small_entries) 766 if (map->use_small_entries)
762 { 767 {
763 struct SmallMapEntry *sme; 768 struct SmallMapEntry *sme;
764 769
765 sme = GNUNET_new(struct SmallMapEntry); 770 sme = GNUNET_new (struct SmallMapEntry);
766 sme->key = key; 771 sme->key = key;
767 sme->value = value; 772 sme->value = value;
768 sme->next = map->map[i].sme; 773 sme->next = map->map[i].sme;
769 map->map[i].sme = sme; 774 map->map[i].sme = sme;
770 } 775 }
771 else 776 else
772 { 777 {
773 struct BigMapEntry *bme; 778 struct BigMapEntry *bme;
774 779
775 bme = GNUNET_new(struct BigMapEntry); 780 bme = GNUNET_new (struct BigMapEntry);
776 bme->key = *key; 781 bme->key = *key;
777 bme->value = value; 782 bme->value = value;
778 bme->next = map->map[i].bme; 783 bme->next = map->map[i].bme;
779 map->map[i].bme = bme; 784 map->map[i].bme = bme;
780 } 785 }
781 map->size++; 786 map->size++;
782 return GNUNET_OK; 787 return GNUNET_OK;
783} 788}
@@ -794,7 +799,7 @@ GNUNET_CONTAINER_multishortmap_put(
794 * #GNUNET_SYSERR if it aborted iteration 799 * #GNUNET_SYSERR if it aborted iteration
795 */ 800 */
796int 801int
797GNUNET_CONTAINER_multishortmap_get_multiple( 802GNUNET_CONTAINER_multishortmap_get_multiple (
798 struct GNUNET_CONTAINER_MultiShortmap *map, 803 struct GNUNET_CONTAINER_MultiShortmap *map,
799 const struct GNUNET_ShortHashCode *key, 804 const struct GNUNET_ShortHashCode *key,
800 GNUNET_CONTAINER_ShortmapIterator it, 805 GNUNET_CONTAINER_ShortmapIterator it,
@@ -805,46 +810,46 @@ GNUNET_CONTAINER_multishortmap_get_multiple(
805 union MapEntry *ce; 810 union MapEntry *ce;
806 811
807 ce = &map->next_cache[map->next_cache_off]; 812 ce = &map->next_cache[map->next_cache_off];
808 GNUNET_assert(++map->next_cache_off < NEXT_CACHE_SIZE); 813 GNUNET_assert (++map->next_cache_off < NEXT_CACHE_SIZE);
809 count = 0; 814 count = 0;
810 me = map->map[idx_of(map, key)]; 815 me = map->map[idx_of (map, key)];
811 if (map->use_small_entries) 816 if (map->use_small_entries)
812 { 817 {
813 struct SmallMapEntry *sme; 818 struct SmallMapEntry *sme;
814 819
815 ce->sme = me.sme; 820 ce->sme = me.sme;
816 while (NULL != (sme = ce->sme)) 821 while (NULL != (sme = ce->sme))
817 { 822 {
818 ce->sme = sme->next; 823 ce->sme = sme->next;
819 if (0 != GNUNET_memcmp(key, sme->key)) 824 if (0 != GNUNET_memcmp (key, sme->key))
820 continue; 825 continue;
821 if ((NULL != it) && (GNUNET_OK != it(it_cls, key, sme->value))) 826 if ((NULL != it) && (GNUNET_OK != it (it_cls, key, sme->value)))
822 { 827 {
823 GNUNET_assert(--map->next_cache_off < NEXT_CACHE_SIZE); 828 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE);
824 return GNUNET_SYSERR; 829 return GNUNET_SYSERR;
825 } 830 }
826 count++; 831 count++;
827 }
828 } 832 }
833 }
829 else 834 else
830 { 835 {
831 struct BigMapEntry *bme; 836 struct BigMapEntry *bme;
832 837
833 ce->bme = me.bme; 838 ce->bme = me.bme;
834 while (NULL != (bme = ce->bme)) 839 while (NULL != (bme = ce->bme))
835 { 840 {
836 ce->bme = bme->next; 841 ce->bme = bme->next;
837 if (0 != GNUNET_memcmp(key, &bme->key)) 842 if (0 != GNUNET_memcmp (key, &bme->key))
838 continue; 843 continue;
839 if ((NULL != it) && (GNUNET_OK != it(it_cls, key, bme->value))) 844 if ((NULL != it) && (GNUNET_OK != it (it_cls, key, bme->value)))
840 { 845 {
841 GNUNET_assert(--map->next_cache_off < NEXT_CACHE_SIZE); 846 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE);
842 return GNUNET_SYSERR; 847 return GNUNET_SYSERR;
843 } 848 }
844 count++; 849 count++;
845 }
846 } 850 }
847 GNUNET_assert(--map->next_cache_off < NEXT_CACHE_SIZE); 851 }
852 GNUNET_assert (--map->next_cache_off < NEXT_CACHE_SIZE);
848 return count; 853 return count;
849} 854}
850 855
@@ -861,7 +866,7 @@ GNUNET_CONTAINER_multishortmap_get_multiple(
861 * @return the number of key value pairs processed, zero or one. 866 * @return the number of key value pairs processed, zero or one.
862 */ 867 */
863unsigned int 868unsigned int
864GNUNET_CONTAINER_multishortmap_get_random( 869GNUNET_CONTAINER_multishortmap_get_random (
865 const struct GNUNET_CONTAINER_MultiShortmap *map, 870 const struct GNUNET_CONTAINER_MultiShortmap *map,
866 GNUNET_CONTAINER_ShortmapIterator it, 871 GNUNET_CONTAINER_ShortmapIterator it,
867 void *it_cls) 872 void *it_cls)
@@ -873,38 +878,38 @@ GNUNET_CONTAINER_multishortmap_get_random(
873 return 0; 878 return 0;
874 if (NULL == it) 879 if (NULL == it)
875 return 1; 880 return 1;
876 off = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_NONCE, map->size); 881 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, map->size);
877 for (unsigned int idx = 0; idx < map->map_length; idx++) 882 for (unsigned int idx = 0; idx < map->map_length; idx++)
883 {
884 me = map->map[idx];
885 if (map->use_small_entries)
878 { 886 {
879 me = map->map[idx]; 887 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next)
880 if (map->use_small_entries) 888 {
889 if (0 == off)
881 { 890 {
882 for (struct SmallMapEntry *sme = me.sme; NULL != sme; sme = sme->next) 891 if (GNUNET_OK != it (it_cls, sme->key, sme->value))
883 { 892 return GNUNET_SYSERR;
884 if (0 == off) 893 return 1;
885 {
886 if (GNUNET_OK != it(it_cls, sme->key, sme->value))
887 return GNUNET_SYSERR;
888 return 1;
889 }
890 off--;
891 }
892 } 894 }
893 else 895 off--;
896 }
897 }
898 else
899 {
900 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next)
901 {
902 if (0 == off)
894 { 903 {
895 for (struct BigMapEntry *bme = me.bme; NULL != bme; bme = bme->next) 904 if (GNUNET_OK != it (it_cls, &bme->key, bme->value))
896 { 905 return GNUNET_SYSERR;
897 if (0 == off) 906 return 1;
898 {
899 if (GNUNET_OK != it(it_cls, &bme->key, bme->value))
900 return GNUNET_SYSERR;
901 return 1;
902 }
903 off--;
904 }
905 } 907 }
908 off--;
909 }
906 } 910 }
907 GNUNET_break(0); 911 }
912 GNUNET_break (0);
908 return GNUNET_SYSERR; 913 return GNUNET_SYSERR;
909} 914}
910 915
@@ -922,12 +927,12 @@ GNUNET_CONTAINER_multishortmap_get_random(
922 * @return an iterator over the given multishortmap 'map' 927 * @return an iterator over the given multishortmap 'map'
923 */ 928 */
924struct GNUNET_CONTAINER_MultiShortmapIterator * 929struct GNUNET_CONTAINER_MultiShortmapIterator *
925GNUNET_CONTAINER_multishortmap_iterator_create( 930GNUNET_CONTAINER_multishortmap_iterator_create (
926 const struct GNUNET_CONTAINER_MultiShortmap *map) 931 const struct GNUNET_CONTAINER_MultiShortmap *map)
927{ 932{
928 struct GNUNET_CONTAINER_MultiShortmapIterator *iter; 933 struct GNUNET_CONTAINER_MultiShortmapIterator *iter;
929 934
930 iter = GNUNET_new(struct GNUNET_CONTAINER_MultiShortmapIterator); 935 iter = GNUNET_new (struct GNUNET_CONTAINER_MultiShortmapIterator);
931 iter->map = map; 936 iter->map = map;
932 iter->modification_counter = map->modification_counter; 937 iter->modification_counter = map->modification_counter;
933 iter->me = map->map[0]; 938 iter->me = map->map[0];
@@ -950,47 +955,47 @@ GNUNET_CONTAINER_multishortmap_iterator_create(
950 * #GNUNET_NO if we are out of elements 955 * #GNUNET_NO if we are out of elements
951 */ 956 */
952int 957int
953GNUNET_CONTAINER_multishortmap_iterator_next( 958GNUNET_CONTAINER_multishortmap_iterator_next (
954 struct GNUNET_CONTAINER_MultiShortmapIterator *iter, 959 struct GNUNET_CONTAINER_MultiShortmapIterator *iter,
955 struct GNUNET_ShortHashCode *key, 960 struct GNUNET_ShortHashCode *key,
956 const void **value) 961 const void **value)
957{ 962{
958 /* make sure the map has not been modified */ 963 /* make sure the map has not been modified */
959 GNUNET_assert(iter->modification_counter == iter->map->modification_counter); 964 GNUNET_assert (iter->modification_counter == iter->map->modification_counter);
960 965
961 /* look for the next entry, skipping empty buckets */ 966 /* look for the next entry, skipping empty buckets */
962 while (1) 967 while (1)
968 {
969 if (iter->idx >= iter->map->map_length)
970 return GNUNET_NO;
971 if (GNUNET_YES == iter->map->use_small_entries)
963 { 972 {
964 if (iter->idx >= iter->map->map_length) 973 if (NULL != iter->me.sme)
965 return GNUNET_NO; 974 {
966 if (GNUNET_YES == iter->map->use_small_entries) 975 if (NULL != key)
967 { 976 *key = *iter->me.sme->key;
968 if (NULL != iter->me.sme) 977 if (NULL != value)
969 { 978 *value = iter->me.sme->value;
970 if (NULL != key) 979 iter->me.sme = iter->me.sme->next;
971 *key = *iter->me.sme->key; 980 return GNUNET_YES;
972 if (NULL != value) 981 }
973 *value = iter->me.sme->value; 982 }
974 iter->me.sme = iter->me.sme->next; 983 else
975 return GNUNET_YES; 984 {
976 } 985 if (NULL != iter->me.bme)
977 } 986 {
978 else 987 if (NULL != key)
979 { 988 *key = iter->me.bme->key;
980 if (NULL != iter->me.bme) 989 if (NULL != value)
981 { 990 *value = iter->me.bme->value;
982 if (NULL != key) 991 iter->me.bme = iter->me.bme->next;
983 *key = iter->me.bme->key; 992 return GNUNET_YES;
984 if (NULL != value) 993 }
985 *value = iter->me.bme->value;
986 iter->me.bme = iter->me.bme->next;
987 return GNUNET_YES;
988 }
989 }
990 iter->idx += 1;
991 if (iter->idx < iter->map->map_length)
992 iter->me = iter->map->map[iter->idx];
993 } 994 }
995 iter->idx += 1;
996 if (iter->idx < iter->map->map_length)
997 iter->me = iter->map->map[iter->idx];
998 }
994} 999}
995 1000
996 1001
@@ -1000,10 +1005,10 @@ GNUNET_CONTAINER_multishortmap_iterator_next(
1000 * @param iter the iterator to destroy 1005 * @param iter the iterator to destroy
1001 */ 1006 */
1002void 1007void
1003GNUNET_CONTAINER_multishortmap_iterator_destroy( 1008GNUNET_CONTAINER_multishortmap_iterator_destroy (
1004 struct GNUNET_CONTAINER_MultiShortmapIterator *iter) 1009 struct GNUNET_CONTAINER_MultiShortmapIterator *iter)
1005{ 1010{
1006 GNUNET_free(iter); 1011 GNUNET_free (iter);
1007} 1012}
1008 1013
1009 1014