diff options
Diffstat (limited to 'src/testbed/testbed_api_topology.c')
-rw-r--r-- | src/testbed/testbed_api_topology.c | 87 |
1 files changed, 54 insertions, 33 deletions
diff --git a/src/testbed/testbed_api_topology.c b/src/testbed/testbed_api_topology.c index defaad2a1..374e42ad4 100644 --- a/src/testbed/testbed_api_topology.c +++ b/src/testbed/testbed_api_topology.c | |||
@@ -589,46 +589,60 @@ gen_topo_random (struct TopologyContext *tc, unsigned int links, int append) | |||
589 | * "Emergence of Scaling in Random Networks." Science 286, 509-512, 1999. | 589 | * "Emergence of Scaling in Random Networks." Science 286, 509-512, 1999. |
590 | * | 590 | * |
591 | * @param tc the topology context | 591 | * @param tc the topology context |
592 | * @param cap maximum allowed node degree | ||
593 | * @param m number of edges to establish for a new node when it is added to the | ||
594 | * network | ||
592 | */ | 595 | */ |
593 | static void | 596 | static void |
594 | gen_scale_free (struct TopologyContext *tc) | 597 | gen_scale_free (struct TopologyContext *tc, uint16_t cap, uint8_t m) |
595 | { | 598 | { |
596 | double random; | ||
597 | double probability; | ||
598 | unsigned int cnt; | 599 | unsigned int cnt; |
599 | unsigned int previous_connections; | 600 | unsigned int cnt2; |
600 | unsigned int i; | 601 | unsigned int peer; |
601 | uint16_t *popularity; | 602 | unsigned int *etab; |
602 | 603 | unsigned int *used; | |
603 | popularity = GNUNET_malloc (sizeof (uint16_t) * tc->num_peers); | 604 | unsigned int links; |
604 | /* Initially connect peer 1 to peer 0 */ | 605 | unsigned int random; |
605 | tc->link_array_size = 1; | 606 | |
606 | tc->link_array = GNUNET_malloc (sizeof (struct OverlayLink)); | 607 | links = 0; |
607 | make_link (&tc->link_array[0], 0, 1, tc); | 608 | tc->link_array_size = tc->num_peers * m; |
608 | popularity[0]++; /* increase popularity of 0 as 1 connected to it */ | 609 | tc->link_array = GNUNET_malloc_large (sizeof (struct OverlayLink) * |
609 | for (cnt = 2; cnt < tc->num_peers; cnt++) | 610 | tc->link_array_size); |
611 | etab = GNUNET_malloc_large (sizeof (unsigned int) * 2 * tc->link_array_size); | ||
612 | |||
613 | used = GNUNET_malloc (sizeof (unsigned int) * m); | ||
614 | |||
615 | make_link (&tc->link_array[0], 0, 1, tc); /* Initially connect peer 1 to peer 0 */ | ||
616 | etab[2 * links] = 0; | ||
617 | etab[(2 * links) + 1] = 1; | ||
618 | links = 1; | ||
619 | for (peer = 2; peer < tc->num_peers; peer++) | ||
610 | { | 620 | { |
611 | previous_connections = tc->link_array_size; | 621 | for (cnt = 0; cnt < GNUNET_MIN (peer, m); cnt++) |
612 | for (i = 0; i < cnt; i++) | ||
613 | { | 622 | { |
614 | probability = ((double) popularity[i]) / ((double) previous_connections); | 623 | redo: |
615 | random = | 624 | random = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, (2 * links) |
616 | ((double) | 625 | + cnt); |
617 | GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, | 626 | for (cnt2 = 0; cnt2 < cnt; cnt2++) |
618 | UINT64_MAX)) / ((double) UINT64_MAX); | 627 | if (etab[random] == used[cnt2]) |
619 | if (random < probability) | 628 | goto redo; |
620 | { | 629 | make_link (&tc->link_array[links + cnt], etab[random], peer, tc); |
621 | tc->link_array_size++; | 630 | etab[(2 * links) + cnt] = etab[random]; |
622 | tc->link_array = | 631 | used[cnt] = etab[random]; |
623 | GNUNET_realloc (tc->link_array, | ||
624 | (sizeof (struct OverlayLink) * | ||
625 | tc->link_array_size)); | ||
626 | make_link (&tc->link_array[tc->link_array_size - 1], i, cnt, tc); | ||
627 | popularity[i]++; | ||
628 | } | ||
629 | } | 632 | } |
633 | for (cnt = 0; cnt < GNUNET_MIN (peer, m); cnt++) | ||
634 | { | ||
635 | etab[(2 * links) + cnt + 1] = peer; | ||
636 | } | ||
637 | links += GNUNET_MIN (peer, m); | ||
630 | } | 638 | } |
631 | GNUNET_free (popularity); | 639 | GNUNET_free (etab); |
640 | GNUNET_free (used); | ||
641 | GNUNET_assert (links <= tc->link_array_size); | ||
642 | tc->link_array_size = links; | ||
643 | tc->link_array = | ||
644 | GNUNET_realloc (tc->link_array, | ||
645 | sizeof (struct OverlayLink) * tc->link_array_size); | ||
632 | } | 646 | } |
633 | 647 | ||
634 | 648 | ||
@@ -933,7 +947,14 @@ GNUNET_TESTBED_overlay_configure_topology_va (void *op_cls, | |||
933 | 947 | ||
934 | break; | 948 | break; |
935 | case GNUNET_TESTBED_TOPOLOGY_SCALE_FREE: | 949 | case GNUNET_TESTBED_TOPOLOGY_SCALE_FREE: |
936 | gen_scale_free (tc); | 950 | { |
951 | uint16_t cap; | ||
952 | uint8_t m; | ||
953 | |||
954 | cap = (uint16_t) va_arg (va, unsigned int); | ||
955 | m = (uint8_t) va_arg (va, unsigned int); | ||
956 | gen_scale_free (tc, cap, m); | ||
957 | } | ||
937 | break; | 958 | break; |
938 | case GNUNET_TESTBED_TOPOLOGY_FROM_FILE: | 959 | case GNUNET_TESTBED_TOPOLOGY_FROM_FILE: |
939 | { | 960 | { |