diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-02-08 22:38:43 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-02-08 22:38:43 +0000 |
commit | dc2ca2186e69be1e24e864251bd6e17e40236d9c (patch) | |
tree | 8732ddd5f59e015337015159924bcd8dad26c60f /src/ats/plugin_ats_proportional.c | |
parent | c54a053bd3dcebb64604855580c6231005f70f48 (diff) | |
download | gnunet-dc2ca2186e69be1e24e864251bd6e17e40236d9c.tar.gz gnunet-dc2ca2186e69be1e24e864251bd6e17e40236d9c.zip |
-cleaning up bandwidth allocation routine
Diffstat (limited to 'src/ats/plugin_ats_proportional.c')
-rw-r--r-- | src/ats/plugin_ats_proportional.c | 152 |
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 | */ |
431 | static void | 433 | static void |
432 | distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s, | 434 | distribute_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 | ||