diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2013-06-25 09:58:00 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2013-06-25 09:58:00 +0000 |
commit | efecad9df3e8847f45a4284ec717c32260460adc (patch) | |
tree | 703aab4408f54e4933869252406a3f4f77ccb9d4 /src/ats | |
parent | c83d77d730a4ae94dff88ec0c6801fde14490f65 (diff) | |
download | gnunet-efecad9df3e8847f45a4284ec717c32260460adc.tar.gz gnunet-efecad9df3e8847f45a4284ec717c32260460adc.zip |
completed normalizing with min max handlin
Diffstat (limited to 'src/ats')
-rw-r--r-- | src/ats/gnunet-service-ats_addresses.c | 8 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats_addresses.h | 26 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats_normalization.c | 161 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats_normalization.h | 4 |
4 files changed, 141 insertions, 58 deletions
diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c index 03400136a..f32c6a7c9 100644 --- a/src/ats/gnunet-service-ats_addresses.c +++ b/src/ats/gnunet-service-ats_addresses.c | |||
@@ -532,7 +532,7 @@ create_address (const struct GNUNET_PeerIdentity *peer, | |||
532 | 532 | ||
533 | for (c1 = 0; c1 < GNUNET_ATS_QualityPropertiesCount; c1 ++) | 533 | for (c1 = 0; c1 < GNUNET_ATS_QualityPropertiesCount; c1 ++) |
534 | { | 534 | { |
535 | aa->atsin[c1].index = 0; | 535 | aa->atsin[c1].avg_queue_index = 0; |
536 | for (c2 = 0; c2 < GAS_normalization_queue_length; c2++) | 536 | for (c2 = 0; c2 < GAS_normalization_queue_length; c2++) |
537 | aa->atsin[c1].atsi_abs[c2] = GNUNET_ATS_VALUE_UNDEFINED; | 537 | aa->atsin[c1].atsi_abs[c2] = GNUNET_ATS_VALUE_UNDEFINED; |
538 | } | 538 | } |
@@ -809,7 +809,7 @@ GAS_addresses_add (struct GAS_Addresses_Handle *handle, | |||
809 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Added new address for peer `%s' session id %u, %p\n", | 809 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Added new address for peer `%s' session id %u, %p\n", |
810 | GNUNET_i2s (peer), session_id, aa); | 810 | GNUNET_i2s (peer), session_id, aa); |
811 | /* Tell solver about new address */ | 811 | /* Tell solver about new address */ |
812 | GAS_normalization_normalize_property (aa, atsi, atsi_count); | 812 | GAS_normalization_normalize_property (handle->addresses, aa, atsi, atsi_count); |
813 | handle->s_add (handle->solver, handle->addresses, aa, addr_net); | 813 | handle->s_add (handle->solver, handle->addresses, aa, addr_net); |
814 | /* Notify performance clients about new address */ | 814 | /* Notify performance clients about new address */ |
815 | GAS_performance_notify_all_clients (&aa->peer, | 815 | GAS_performance_notify_all_clients (&aa->peer, |
@@ -853,7 +853,7 @@ GAS_addresses_add (struct GAS_Addresses_Handle *handle, | |||
853 | } | 853 | } |
854 | 854 | ||
855 | /* Notify solver about update with atsi information and session */ | 855 | /* Notify solver about update with atsi information and session */ |
856 | GAS_normalization_normalize_property (ea, atsi, atsi_count); | 856 | GAS_normalization_normalize_property (handle->addresses, ea, atsi, atsi_count); |
857 | handle->s_update (handle->solver, handle->addresses, ea, session_id, ea->used, atsi_delta, atsi_delta_count); | 857 | handle->s_update (handle->solver, handle->addresses, ea, session_id, ea->used, atsi_delta, atsi_delta_count); |
858 | GNUNET_free_non_null (atsi_delta); | 858 | GNUNET_free_non_null (atsi_delta); |
859 | 859 | ||
@@ -931,7 +931,7 @@ GAS_addresses_update (struct GAS_Addresses_Handle *handle, | |||
931 | prev_session = aa->session_id; | 931 | prev_session = aa->session_id; |
932 | aa->session_id = session_id; | 932 | aa->session_id = session_id; |
933 | 933 | ||
934 | GAS_normalization_normalize_property (aa, atsi, atsi_count); | 934 | GAS_normalization_normalize_property (handle->addresses, aa, atsi, atsi_count); |
935 | 935 | ||
936 | /* Tell solver about update */ | 936 | /* Tell solver about update */ |
937 | handle->s_update (handle->solver, handle->addresses, aa, prev_session, aa->used, atsi_delta, atsi_delta_count); | 937 | handle->s_update (handle->solver, handle->addresses, aa, prev_session, aa->used, atsi_delta, atsi_delta_count); |
diff --git a/src/ats/gnunet-service-ats_addresses.h b/src/ats/gnunet-service-ats_addresses.h index 8c462ed8c..4eddd5290 100644 --- a/src/ats/gnunet-service-ats_addresses.h +++ b/src/ats/gnunet-service-ats_addresses.h | |||
@@ -233,12 +233,30 @@ | |||
233 | 233 | ||
234 | struct GAS_Addresses_Handle; | 234 | struct GAS_Addresses_Handle; |
235 | 235 | ||
236 | 236 | /** | |
237 | * Information provided by ATS normalization | ||
238 | */ | ||
237 | struct GAS_NormalizationInfo | 239 | struct GAS_NormalizationInfo |
238 | { | 240 | { |
239 | unsigned int index; | 241 | /** |
240 | uint32_t avg; | 242 | * Next index to use in averaging queue |
243 | */ | ||
244 | unsigned int avg_queue_index; | ||
245 | |||
246 | /** | ||
247 | * Averaging queue | ||
248 | */ | ||
241 | uint32_t atsi_abs[GAS_normalization_queue_length]; | 249 | uint32_t atsi_abs[GAS_normalization_queue_length]; |
250 | |||
251 | /** | ||
252 | * Averaged ATSI values from queue | ||
253 | */ | ||
254 | uint32_t avg; | ||
255 | |||
256 | /** | ||
257 | * Normalized values from queue to a range of values [1.0...2.0] | ||
258 | */ | ||
259 | double norm; | ||
242 | }; | 260 | }; |
243 | 261 | ||
244 | /** | 262 | /** |
@@ -354,7 +372,7 @@ struct ATS_Address | |||
354 | 372 | ||
355 | /** | 373 | /** |
356 | * Normalized ATS performance information for this address | 374 | * Normalized ATS performance information for this address |
357 | * Each entry can be accessed using the GNUNET_ATS_QualityProperties index | 375 | * Each entry can be accessed using the GNUNET_ATS_QualityProperties avg_queue_index |
358 | */ | 376 | */ |
359 | struct GAS_NormalizationInfo atsin[GNUNET_ATS_QualityPropertiesCount]; | 377 | struct GAS_NormalizationInfo atsin[GNUNET_ATS_QualityPropertiesCount]; |
360 | }; | 378 | }; |
diff --git a/src/ats/gnunet-service-ats_normalization.c b/src/ats/gnunet-service-ats_normalization.c index 84a07b0d8..5ac7cb8d7 100644 --- a/src/ats/gnunet-service-ats_normalization.c +++ b/src/ats/gnunet-service-ats_normalization.c | |||
@@ -515,8 +515,8 @@ GAS_normalization_get_preferences (const struct GNUNET_PeerIdentity *id) | |||
515 | 515 | ||
516 | struct Property | 516 | struct Property |
517 | { | 517 | { |
518 | int have_min; /* Do we have min and max */ | 518 | uint32_t prop_type; |
519 | int have_max; | 519 | uint32_t atsi_type; |
520 | uint32_t min; | 520 | uint32_t min; |
521 | uint32_t max; | 521 | uint32_t max; |
522 | }; | 522 | }; |
@@ -561,10 +561,10 @@ property_average (struct ATS_Address *address, | |||
561 | index = c1; | 561 | index = c1; |
562 | 562 | ||
563 | ni = &address->atsin[index]; | 563 | ni = &address->atsin[index]; |
564 | ni->atsi_abs[ni->index] = current_val; | 564 | ni->atsi_abs[ni->avg_queue_index] = current_val; |
565 | ni->index ++; | 565 | ni->avg_queue_index ++; |
566 | if (GAS_normalization_queue_length == ni->index) | 566 | if (GAS_normalization_queue_length == ni->avg_queue_index) |
567 | ni->index = 0; | 567 | ni->avg_queue_index = 0; |
568 | 568 | ||
569 | count = 0; | 569 | count = 0; |
570 | sum = 0; | 570 | sum = 0; |
@@ -591,65 +591,125 @@ property_average (struct ATS_Address *address, | |||
591 | return res; | 591 | return res; |
592 | } | 592 | } |
593 | 593 | ||
594 | |||
595 | struct FindMinMaxCtx | ||
596 | { | ||
597 | struct Property *p; | ||
598 | uint32_t min; | ||
599 | uint32_t max; | ||
600 | }; | ||
601 | |||
602 | static int | ||
603 | find_min_max_it (void *cls, const struct GNUNET_HashCode *h, void *k) | ||
604 | { | ||
605 | struct ATS_Address *a = (struct ATS_Address *) k; | ||
606 | struct FindMinMaxCtx *find_res = cls; | ||
607 | |||
608 | if (a->atsin[find_res->p->prop_type].avg > find_res->max) | ||
609 | find_res->max = a->atsin[find_res->p->prop_type].avg; | ||
610 | |||
611 | if (a->atsin[find_res->p->prop_type].avg < find_res->min) | ||
612 | find_res->min = a->atsin[find_res->p->prop_type].avg; | ||
613 | |||
614 | return GNUNET_OK; | ||
615 | } | ||
616 | |||
617 | |||
618 | static int | ||
619 | normalize_address (void *cls, const struct GNUNET_HashCode *h, void *k) | ||
620 | { | ||
621 | struct Property *p = cls; | ||
622 | struct ATS_Address *address = (struct ATS_Address *) k; | ||
623 | |||
624 | double delta; | ||
625 | uint32_t avg_value = address->atsin[p->prop_type].avg; | ||
626 | |||
627 | delta = p->max - p->min; | ||
628 | address->atsin[p->prop_type].norm = (delta + (avg_value - p->min)) / (delta); | ||
629 | |||
630 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Normalize `%s' address %p's '%s' with value %u to range [%u..%u] = %.3f\n", | ||
631 | GNUNET_i2s (&address->peer), | ||
632 | address, | ||
633 | GNUNET_ATS_print_property_type (p->atsi_type), | ||
634 | address->atsin[p->prop_type].avg, | ||
635 | p->min, p->max, | ||
636 | address->atsin[p->prop_type].norm ); | ||
637 | |||
638 | if (NULL != prop_ch_cb) | ||
639 | prop_ch_cb (prop_ch_cb_cls, address, p->atsi_type, | ||
640 | address->atsin[p->prop_type].norm); | ||
641 | |||
642 | |||
643 | return GNUNET_OK; | ||
644 | } | ||
645 | |||
646 | |||
594 | /** | 647 | /** |
595 | * Normalize avg_value to a range of values between [1.0, 2.0] | 648 | * Normalize avg_value to a range of values between [1.0, 2.0] |
596 | * based on min max values currently known. | 649 | * based on min max values currently known. |
597 | * | 650 | * |
598 | * @param property p the property | 651 | * @param property p the property |
599 | * @param address the address | 652 | * @param address the address |
600 | * @param type the atsi type | ||
601 | * @param avg_value the value to normalize | 653 | * @param avg_value the value to normalize |
602 | */ | 654 | */ |
603 | 655 | ||
604 | static void | 656 | static void |
605 | property_normalize (struct Property *p, | 657 | property_normalize (struct GNUNET_CONTAINER_MultiHashMap *addresses, |
658 | struct Property *p, | ||
606 | struct ATS_Address *address, | 659 | struct ATS_Address *address, |
607 | uint32_t type, | ||
608 | uint32_t avg_value) | 660 | uint32_t avg_value) |
609 | { | 661 | { |
610 | double res; | 662 | struct FindMinMaxCtx find_ctx; |
611 | double delta; | 663 | int addr_count; |
612 | uint32_t current_min; | 664 | int limits_changed; |
613 | 665 | ||
614 | /* Normalize the values of this property */ | 666 | find_ctx.p = p; |
615 | if (avg_value > p->max) | 667 | find_ctx.max = 0; |
668 | find_ctx.min = UINT32_MAX; | ||
669 | addr_count = GNUNET_CONTAINER_multihashmap_iterate(addresses, &find_min_max_it, &find_ctx); | ||
670 | if (0 == addr_count) | ||
616 | { | 671 | { |
617 | p->max = avg_value; | 672 | GNUNET_break (0); |
618 | if (GNUNET_NO == p->have_max) | 673 | return; |
619 | p->have_max = GNUNET_YES; | ||
620 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
621 | "New maximum of %u for property %s\n", | ||
622 | p->max, GNUNET_ATS_print_property_type (type)); | ||
623 | } | 674 | } |
624 | 675 | ||
625 | if ((avg_value < p->min) && (avg_value < p->max)) | 676 | |
677 | limits_changed = GNUNET_NO; | ||
678 | if (find_ctx.max != p->max) | ||
626 | { | 679 | { |
627 | p->min = avg_value; | 680 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Normalizing %s: new maximum %u -> recalculate all values\n", |
628 | if (GNUNET_NO == p->have_min) | 681 | GNUNET_ATS_print_property_type (p->atsi_type), |
629 | p->have_min = GNUNET_YES; | 682 | find_ctx.max); |
630 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 683 | p->max = find_ctx.max; |
631 | "New minimum of %u for property %s\n", | 684 | limits_changed = GNUNET_YES; |
632 | p->min, GNUNET_ATS_print_property_type (type)); | ||
633 | } | 685 | } |
634 | 686 | ||
635 | current_min = p->min; | 687 | if ((find_ctx.min != p->min) && (find_ctx.min < p->max)) |
636 | if (UINT32_MAX == p->min) | 688 | { |
637 | current_min = 0; /* If we do not have a minimum we use 0.0 */ | 689 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Normalizing %s: new minimum %u -> recalculate all values\n", |
638 | 690 | GNUNET_ATS_print_property_type (p->atsi_type), | |
639 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Normalizing %u: new normalized property `%s' using min=%u max=%u\n", | 691 | find_ctx.min, find_ctx.max); |
640 | avg_value, | 692 | p->min = find_ctx.min; |
641 | GNUNET_ATS_print_property_type (type), | 693 | limits_changed = GNUNET_YES; |
642 | current_min, p->max); | 694 | } |
695 | else if (find_ctx.min == p->max) | ||
696 | { | ||
697 | /* Only one value, so minimum has to be 0 */ | ||
698 | p->min = 0; | ||
699 | } | ||
643 | 700 | ||
644 | if (GNUNET_YES == p->have_max) | 701 | /* Normalize the values of this property */ |
702 | if (GNUNET_NO == limits_changed) | ||
645 | { | 703 | { |
646 | delta = p->max - current_min; | 704 | /* normalize just this address */ |
647 | res = (delta + (avg_value - current_min)) / (delta); | 705 | normalize_address (p, &address->peer.hashPubKey, address); |
648 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 706 | return; |
649 | "Peer `%s': New normalized value of %f for property %s\n", | 707 | } |
650 | GNUNET_i2s (&address->peer), res, GNUNET_ATS_print_property_type (type)); | 708 | else |
651 | if (NULL != prop_ch_cb) | 709 | { |
652 | prop_ch_cb (prop_ch_cb_cls, address, type, res); | 710 | /* limits changed, normalize all addresses */ |
711 | GNUNET_CONTAINER_multihashmap_iterate(addresses, &normalize_address, p); | ||
712 | return; | ||
653 | } | 713 | } |
654 | } | 714 | } |
655 | 715 | ||
@@ -657,12 +717,14 @@ property_normalize (struct Property *p, | |||
657 | /** | 717 | /** |
658 | * Update and normalize a atsi performance information | 718 | * Update and normalize a atsi performance information |
659 | * | 719 | * |
720 | * @param addresses hashmap containing all addresses | ||
660 | * @param address the address to update | 721 | * @param address the address to update |
661 | * @param atsi the array of performance information | 722 | * @param atsi the array of performance information |
662 | * @param atsi_count the number of atsi information in the array | 723 | * @param atsi_count the number of atsi information in the array |
663 | */ | 724 | */ |
664 | void | 725 | void |
665 | GAS_normalization_normalize_property (struct ATS_Address *address, | 726 | GAS_normalization_normalize_property (struct GNUNET_CONTAINER_MultiHashMap *addresses, |
727 | struct ATS_Address *address, | ||
666 | const struct GNUNET_ATS_Information *atsi, | 728 | const struct GNUNET_ATS_Information *atsi, |
667 | uint32_t atsi_count) | 729 | uint32_t atsi_count) |
668 | { | 730 | { |
@@ -705,7 +767,7 @@ GAS_normalization_normalize_property (struct ATS_Address *address, | |||
705 | /* Normalizing */ | 767 | /* Normalizing */ |
706 | /* Check min, max */ | 768 | /* Check min, max */ |
707 | cur_prop = &properties[c2]; | 769 | cur_prop = &properties[c2]; |
708 | property_normalize (cur_prop, address, ntohl(atsi[c1].type), current_val); | 770 | property_normalize (addresses, cur_prop, address, current_val); |
709 | } | 771 | } |
710 | } | 772 | } |
711 | 773 | ||
@@ -728,13 +790,14 @@ GAS_normalization_start (GAS_Normalization_preference_changed_cb pref_ch_cb, | |||
728 | int i; | 790 | int i; |
729 | preference_peers = GNUNET_CONTAINER_multihashmap_create(10, GNUNET_NO); | 791 | preference_peers = GNUNET_CONTAINER_multihashmap_create(10, GNUNET_NO); |
730 | property_peers = GNUNET_CONTAINER_multihashmap_create(10, GNUNET_NO); | 792 | property_peers = GNUNET_CONTAINER_multihashmap_create(10, GNUNET_NO); |
793 | unsigned int existing_properties[] = GNUNET_ATS_QualityProperties; | ||
731 | 794 | ||
732 | for (c1 = 0; c1 < GNUNET_ATS_QualityPropertiesCount; c1++) | 795 | for (c1 = 0; c1 < GNUNET_ATS_QualityPropertiesCount; c1++) |
733 | { | 796 | { |
734 | properties[c1].min = UINT32_MAX; | 797 | properties[c1].prop_type = c1; |
798 | properties[c1].atsi_type = existing_properties[c1]; | ||
799 | properties[c1].min = 0; | ||
735 | properties[c1].max = 0; | 800 | properties[c1].max = 0; |
736 | properties[c1].have_max = GNUNET_NO; | ||
737 | properties[c1].have_min = GNUNET_NO; | ||
738 | } | 801 | } |
739 | 802 | ||
740 | pref_changed_cb = pref_ch_cb; | 803 | pref_changed_cb = pref_ch_cb; |
diff --git a/src/ats/gnunet-service-ats_normalization.h b/src/ats/gnunet-service-ats_normalization.h index 75158ac72..35906be7d 100644 --- a/src/ats/gnunet-service-ats_normalization.h +++ b/src/ats/gnunet-service-ats_normalization.h | |||
@@ -74,12 +74,14 @@ GAS_normalization_normalize_preference (void *src, | |||
74 | /** | 74 | /** |
75 | * Update and normalize a atsi performance information | 75 | * Update and normalize a atsi performance information |
76 | * | 76 | * |
77 | * @param addresses hashmap containing all addresses | ||
77 | * @param address the address to update | 78 | * @param address the address to update |
78 | * @param atsi the array of performance information | 79 | * @param atsi the array of performance information |
79 | * @param atsi_count the number of atsi information in the array | 80 | * @param atsi_count the number of atsi information in the array |
80 | */ | 81 | */ |
81 | void | 82 | void |
82 | GAS_normalization_normalize_property (struct ATS_Address *address, | 83 | GAS_normalization_normalize_property (struct GNUNET_CONTAINER_MultiHashMap *addresses, |
84 | struct ATS_Address *address, | ||
83 | const struct GNUNET_ATS_Information *atsi, | 85 | const struct GNUNET_ATS_Information *atsi, |
84 | uint32_t atsi_count); | 86 | uint32_t atsi_count); |
85 | 87 | ||