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