aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-02-08 22:38:43 +0000
committerChristian Grothoff <christian@grothoff.org>2015-02-08 22:38:43 +0000
commitdc2ca2186e69be1e24e864251bd6e17e40236d9c (patch)
tree8732ddd5f59e015337015159924bcd8dad26c60f /src
parentc54a053bd3dcebb64604855580c6231005f70f48 (diff)
downloadgnunet-dc2ca2186e69be1e24e864251bd6e17e40236d9c.tar.gz
gnunet-dc2ca2186e69be1e24e864251bd6e17e40236d9c.zip
-cleaning up bandwidth allocation routine
Diffstat (limited to 'src')
-rw-r--r--src/ats/plugin_ats_proportional.c152
1 files changed, 57 insertions, 95 deletions
diff --git a/src/ats/plugin_ats_proportional.c b/src/ats/plugin_ats_proportional.c
index 2521bb448..bacb57e02 100644
--- a/src/ats/plugin_ats_proportional.c
+++ b/src/ats/plugin_ats_proportional.c
@@ -422,33 +422,29 @@ all_require_connectivity (struct GAS_PROPORTIONAL_Handle *s,
422 422
423 423
424/** 424/**
425 * Update bandwidth assigned to peers in this network 425 * Update bandwidth assigned to peers in this network. The basic idea
426 * is to assign every peer in the network the minimum bandwidth, and
427 * then distribute the remaining bandwidth proportional to application
428 * preferences.
426 * 429 *
427 * @param s the solver handle 430 * @param s the solver handle
428 * @param net the network type to update 431 * @param net the network type to update
429 * this address
430 */ 432 */
431static void 433static void
432distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s, 434distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s,
433 struct Network *net) 435 struct Network *net)
434{ 436{
437 const uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
435 struct AddressWrapper *aw; 438 struct AddressWrapper *aw;
436 unsigned long long remaining_quota_in = 0; 439 unsigned long long remaining_quota_in;
437 unsigned long long quota_out_used = 0; 440 unsigned long long quota_out_used;
438 unsigned long long remaining_quota_out = 0; 441 unsigned long long remaining_quota_out;
439 unsigned long long quota_in_used = 0; 442 unsigned long long quota_in_used;
440 int count_addresses; 443 unsigned int count_addresses;
441 uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__); 444 double sum_relative_peer_prefences;
442 double relative_peer_prefence;
443 double sum_relative_peer_prefences; /* Important: has to be double not float due to precision */
444 double cur_pref; /* Important: has to be double not float due to precision */
445 double peer_weight; 445 double peer_weight;
446 double total_weight; 446 double total_weight;
447 const double *peer_relative_prefs = NULL; /* Important: has to be double not float due to precision */ 447 const double *peer_relative_prefs;
448
449 uint32_t assigned_quota_in = 0;
450 uint32_t assigned_quota_out = 0;
451
452 448
453 LOG (GNUNET_ERROR_TYPE_INFO, 449 LOG (GNUNET_ERROR_TYPE_INFO,
454 "Recalculate quota for network type `%s' for %u addresses (in/out): %llu/%llu \n", 450 "Recalculate quota for network type `%s' for %u addresses (in/out): %llu/%llu \n",
@@ -460,11 +456,7 @@ distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s,
460 if (0 == net->active_addresses) 456 if (0 == net->active_addresses)
461 return; /* no addresses to update */ 457 return; /* no addresses to update */
462 458
463 /* Idea: 459 /* sanity checks */
464 * Assign every peer in network minimum Bandwidth
465 * Distribute remaining bandwidth proportional to preferences.
466 */
467
468 if ((net->active_addresses * min_bw) > net->total_quota_in) 460 if ((net->active_addresses * min_bw) > net->total_quota_in)
469 { 461 {
470 GNUNET_break(0); 462 GNUNET_break(0);
@@ -476,16 +468,9 @@ distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s,
476 return; 468 return;
477 } 469 }
478 470
479 remaining_quota_in = net->total_quota_in - (net->active_addresses * min_bw);
480 remaining_quota_out = net->total_quota_out - (net->active_addresses * min_bw);
481 LOG (GNUNET_ERROR_TYPE_DEBUG,
482 "Proportionally distributable bandwidth (in/out): %llu/%llu\n",
483 remaining_quota_in,
484 remaining_quota_out);
485 sum_relative_peer_prefences = 0.0;
486
487 /* Calculate sum of relative preference for active addresses in this 471 /* Calculate sum of relative preference for active addresses in this
488 network */ 472 network */
473 sum_relative_peer_prefences = 0.0;
489 count_addresses = 0; 474 count_addresses = 0;
490 for (aw = net->head; NULL != aw; aw = aw->next) 475 for (aw = net->head; NULL != aw; aw = aw->next)
491 { 476 {
@@ -496,7 +481,6 @@ distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s,
496 sum_relative_peer_prefences += peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH]; 481 sum_relative_peer_prefences += peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH];
497 count_addresses++; 482 count_addresses++;
498 } 483 }
499
500 if (count_addresses != net->active_addresses) 484 if (count_addresses != net->active_addresses)
501 { 485 {
502 GNUNET_break (0); 486 GNUNET_break (0);
@@ -505,88 +489,66 @@ distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s,
505 net->desc, 489 net->desc,
506 count_addresses, 490 count_addresses,
507 net->active_addresses); 491 net->active_addresses);
508 for (aw = net->head; NULL != aw; aw = aw->next) 492 /* try to fix... */
509 { 493 net->active_addresses = count_addresses;
510 if (GNUNET_YES != aw->addr->active)
511 continue;
512
513 LOG (GNUNET_ERROR_TYPE_WARNING,
514 "Active: `%s' `%s' length %u\n",
515 GNUNET_i2s (&aw->addr->peer),
516 aw->addr->plugin,
517 aw->addr->addr_len);
518 }
519 } 494 }
520
521 LOG (GNUNET_ERROR_TYPE_INFO, 495 LOG (GNUNET_ERROR_TYPE_INFO,
522 "Total relative preference %.3f for %u addresses in network %s\n", 496 "Total relative preference %.3f for %u addresses in network %s\n",
523 sum_relative_peer_prefences, 497 sum_relative_peer_prefences,
524 net->active_addresses, 498 net->active_addresses,
525 net->desc); 499 net->desc);
526 500
501 /* check how much we have to distribute */
502 remaining_quota_in = net->total_quota_in - (net->active_addresses * min_bw);
503 remaining_quota_out = net->total_quota_out - (net->active_addresses * min_bw);
504 LOG (GNUNET_ERROR_TYPE_DEBUG,
505 "Proportionally distributable bandwidth (in/out): %llu/%llu\n",
506 remaining_quota_in,
507 remaining_quota_out);
508
509 /* distribute remaining quota; we do not do it exactly proportional,
510 but balance "even" distribution ("net->active_addresses") with
511 the preference sum using the "prop_factor". */
512 total_weight = net->active_addresses +
513 s->prop_factor * sum_relative_peer_prefences;
514 quota_out_used = 0;
515 quota_in_used = 0;
527 for (aw = net->head; NULL != aw; aw = aw->next) 516 for (aw = net->head; NULL != aw; aw = aw->next)
528 { 517 {
529 if (GNUNET_YES == aw->addr->active) 518 if (GNUNET_YES != aw->addr->active)
530 {
531 peer_relative_prefs = s->env->get_preferences (s->env->cls,
532 &aw->addr->peer);
533
534 cur_pref = peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH];
535 total_weight = net->active_addresses +
536 s->prop_factor * sum_relative_peer_prefences;
537 peer_weight = (1.0 + (s->prop_factor * cur_pref));
538
539 assigned_quota_in = min_bw
540 + ((peer_weight / total_weight) * remaining_quota_in);
541 assigned_quota_out = min_bw
542 + ((peer_weight / total_weight) * remaining_quota_out);
543
544 LOG (GNUNET_ERROR_TYPE_INFO,
545 "New quota for peer `%s' with weight (cur/total) %.3f/%.3f (in/out): %llu / %llu\n",
546 GNUNET_i2s (&aw->addr->peer),
547 peer_weight,
548 total_weight,
549 assigned_quota_in,
550 assigned_quota_out);
551 }
552 else
553 { 519 {
554 assigned_quota_in = 0; 520 /* set to 0, just to be sure */
555 assigned_quota_out = 0; 521 aw->calculated_quota_in = 0;
522 aw->calculated_quota_out = 0;
523 continue;
556 } 524 }
525 peer_relative_prefs = s->env->get_preferences (s->env->cls,
526 &aw->addr->peer);
527 peer_weight = 1.0
528 + s->prop_factor * peer_relative_prefs[GNUNET_ATS_PREFERENCE_BANDWIDTH];
529
530 aw->calculated_quota_in = min_bw
531 + (peer_weight / total_weight) * remaining_quota_in;
532 aw->calculated_quota_out = min_bw
533 + (peer_weight / total_weight) * remaining_quota_out;
557 534
558 quota_in_used += assigned_quota_in; 535 LOG (GNUNET_ERROR_TYPE_INFO,
559 quota_out_used += assigned_quota_out; 536 "New quotas for peer `%s' with weight (cur/total) %.3f/%.3f (in/out) are: %u/%u\n",
560 /* Prevent overflow due to rounding errors */ 537 GNUNET_i2s (&aw->addr->peer),
561 if (assigned_quota_in > UINT32_MAX) 538 peer_weight,
562 assigned_quota_in = UINT32_MAX; 539 total_weight,
563 if (assigned_quota_out > UINT32_MAX) 540 (unsigned int) aw->calculated_quota_in,
564 assigned_quota_out = UINT32_MAX; 541 (unsigned int) aw->calculated_quota_out);
565 542 quota_in_used += aw->calculated_quota_in;
566 /* Store for later propagation */ 543 quota_out_used += aw->calculated_quota_out;
567 aw->calculated_quota_in = assigned_quota_in;
568 aw->calculated_quota_out = assigned_quota_out;
569 } 544 }
570 LOG (GNUNET_ERROR_TYPE_DEBUG, 545 LOG (GNUNET_ERROR_TYPE_DEBUG,
571 "Total bandwidth assigned is (in/out): %llu /%llu\n", 546 "Total bandwidth assigned is (in/out): %llu /%llu\n",
572 quota_in_used, 547 quota_in_used,
573 quota_out_used); 548 quota_out_used);
574 if (quota_out_used > net->total_quota_out + 1) /* +1 is required due to rounding errors */ 549 /* +1 due to possible rounding errors */
575 { 550 GNUNET_break (quota_out_used <= net->total_quota_out + 1);
576 LOG (GNUNET_ERROR_TYPE_ERROR, 551 GNUNET_break (quota_in_used <= net->total_quota_in + 1);
577 "Total outbound bandwidth assigned is larger than allowed (used/allowed) for %u active addresses: %llu / %llu\n",
578 net->active_addresses,
579 quota_out_used,
580 net->total_quota_out);
581 }
582 if (quota_in_used > net->total_quota_in + 1) /* +1 is required due to rounding errors */
583 {
584 LOG (GNUNET_ERROR_TYPE_ERROR,
585 "Total inbound bandwidth assigned is larger than allowed (used/allowed) for %u active addresses: %llu / %llu\n",
586 net->active_addresses,
587 quota_in_used,
588 net->total_quota_in);
589 }
590} 552}
591 553
592 554