diff options
Diffstat (limited to 'src/testbed/testbed_api_topology.c')
-rw-r--r-- | src/testbed/testbed_api_topology.c | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/src/testbed/testbed_api_topology.c b/src/testbed/testbed_api_topology.c index a6dd51fd2..d506ee7e3 100644 --- a/src/testbed/testbed_api_topology.c +++ b/src/testbed/testbed_api_topology.c | |||
@@ -596,17 +596,20 @@ gen_topo_random (struct TopologyContext *tc, unsigned int links, int append) | |||
596 | static void | 596 | static void |
597 | gen_scale_free (struct TopologyContext *tc, uint16_t cap, uint8_t m) | 597 | gen_scale_free (struct TopologyContext *tc, uint16_t cap, uint8_t m) |
598 | { | 598 | { |
599 | unsigned int *deg; | ||
600 | unsigned int *etab; | ||
601 | unsigned int *used; | ||
602 | unsigned int etaboff; | ||
599 | unsigned int cnt; | 603 | unsigned int cnt; |
600 | unsigned int cnt2; | 604 | unsigned int cnt2; |
601 | unsigned int peer; | 605 | unsigned int peer; |
602 | unsigned int random_peer; | 606 | unsigned int random_peer; |
603 | unsigned int *deg; | ||
604 | unsigned int *etab; | ||
605 | unsigned int *used; | ||
606 | unsigned int links; | 607 | unsigned int links; |
607 | unsigned int random; | 608 | unsigned int off; |
609 | unsigned int redo_threshold; | ||
608 | 610 | ||
609 | links = 0; | 611 | links = 0; |
612 | etaboff = 0; | ||
610 | tc->link_array_size = tc->num_peers * m; | 613 | tc->link_array_size = tc->num_peers * m; |
611 | tc->link_array = GNUNET_malloc_large (sizeof (struct OverlayLink) * | 614 | tc->link_array = GNUNET_malloc_large (sizeof (struct OverlayLink) * |
612 | tc->link_array_size); | 615 | tc->link_array_size); |
@@ -617,8 +620,8 @@ gen_scale_free (struct TopologyContext *tc, uint16_t cap, uint8_t m) | |||
617 | make_link (&tc->link_array[0], 0, 1, tc); | 620 | make_link (&tc->link_array[0], 0, 1, tc); |
618 | deg[0]++; | 621 | deg[0]++; |
619 | deg[1]++; | 622 | deg[1]++; |
620 | etab[2 * links] = 0; | 623 | etab[etaboff++] = 0; |
621 | etab[(2 * links) + 1] = 1; | 624 | etab[etaboff++] = 1; |
622 | links = 1; | 625 | links = 1; |
623 | for (peer = 2; peer < tc->num_peers; peer++) | 626 | for (peer = 2; peer < tc->num_peers; peer++) |
624 | { | 627 | { |
@@ -626,23 +629,41 @@ gen_scale_free (struct TopologyContext *tc, uint16_t cap, uint8_t m) | |||
626 | continue; | 629 | continue; |
627 | for (cnt = 0; cnt < GNUNET_MIN (peer, m); cnt++) | 630 | for (cnt = 0; cnt < GNUNET_MIN (peer, m); cnt++) |
628 | { | 631 | { |
632 | redo_threshold = 0; | ||
629 | redo: | 633 | redo: |
630 | random = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, (2 * links)); | 634 | off = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, etaboff); |
631 | random_peer = etab[random]; | 635 | random_peer = etab[off]; |
632 | if (cap < deg[random_peer]) | 636 | if (cap < deg[random_peer]) |
637 | { | ||
638 | if (++redo_threshold > GNUNET_MAX (1, cap / 2)) | ||
639 | { | ||
640 | redo_threshold = 0; | ||
641 | off = 0; | ||
642 | for (cnt2 = 0; cnt2 < etaboff; cnt2++) | ||
643 | { | ||
644 | if (random_peer == etab[cnt2]) | ||
645 | { | ||
646 | off++; | ||
647 | continue; | ||
648 | } | ||
649 | etab[cnt2 - off] = etab[cnt2]; | ||
650 | } | ||
651 | etaboff -= off; | ||
652 | } | ||
633 | goto redo; | 653 | goto redo; |
654 | } | ||
634 | for (cnt2 = 0; cnt2 < cnt; cnt2++) | 655 | for (cnt2 = 0; cnt2 < cnt; cnt2++) |
635 | if (random_peer == used[cnt2]) | 656 | if (random_peer == used[cnt2]) |
636 | goto redo; | 657 | goto redo; |
637 | make_link (&tc->link_array[links + cnt], etab[random], peer, tc); | 658 | make_link (&tc->link_array[links + cnt], random_peer, peer, tc); |
638 | deg[random_peer]++; | 659 | deg[random_peer]++; |
639 | deg[peer]++; | 660 | deg[peer]++; |
640 | used[cnt] = random_peer; | 661 | used[cnt] = random_peer; |
641 | } | 662 | } |
642 | for (cnt = 0; cnt < GNUNET_MIN (peer, m); cnt++) | 663 | for (cnt = 0; cnt < GNUNET_MIN (peer, m); cnt++) |
643 | { | 664 | { |
644 | etab[(2 * links) + cnt] = used[cnt]; | 665 | etab[etaboff++] = used[cnt]; |
645 | etab[(2 * links) + cnt + 1] = peer; | 666 | etab[etaboff++] = peer; |
646 | } | 667 | } |
647 | links += GNUNET_MIN (peer, m); | 668 | links += GNUNET_MIN (peer, m); |
648 | } | 669 | } |