aboutsummaryrefslogtreecommitdiff
path: root/src/transport/transport_ats.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2011-07-06 15:46:07 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2011-07-06 15:46:07 +0000
commit8baa8015d7eb3bd684a3a0d22dc698837de13c7e (patch)
treeb0425dc0554bd0a1804d4defa2cc7ad5e5b11142 /src/transport/transport_ats.c
parent53c1c40f7ea78892a3b3d8f95557ef53873565a7 (diff)
downloadgnunet-8baa8015d7eb3bd684a3a0d22dc698837de13c7e.tar.gz
gnunet-8baa8015d7eb3bd684a3a0d22dc698837de13c7e.zip
changes to ats
Diffstat (limited to 'src/transport/transport_ats.c')
-rw-r--r--src/transport/transport_ats.c1833
1 files changed, 1101 insertions, 732 deletions
diff --git a/src/transport/transport_ats.c b/src/transport/transport_ats.c
index cf558c038..fdd8126cd 100644
--- a/src/transport/transport_ats.c
+++ b/src/transport/transport_ats.c
@@ -30,6 +30,12 @@
30#include "gnunet_statistics_service.h" 30#include "gnunet_statistics_service.h"
31#include "gnunet_container_lib.h" 31#include "gnunet_container_lib.h"
32 32
33
34/*
35 * Temporary included structs and defines
36 */
37
38
33/** 39/**
34 * FIXME to be removed 40 * FIXME to be removed
35 * Entry in linked list of all of our current neighbours. 41 * Entry in linked list of all of our current neighbours.
@@ -256,7 +262,9 @@ struct ForeignAddressList
256 262
257 /** 263 /**
258 * Are we currently connected via this address? The first time we 264 * Are we currently connected via this address? The first time we
259 * successfully transmit or receive data to a peer via a particular 265 * successfully transmit or receive data to a peer via a particularcurl:
266 * (56) Recv failure: Connection reset by peer
267 *
260 * address, we set this to GNUNET_YES. If we later get an error 268 * address, we set this to GNUNET_YES. If we later get an error
261 * (disconnect notification, transmission failure, timeout), we set 269 * (disconnect notification, transmission failure, timeout), we set
262 * it back to GNUNET_NO. 270 * it back to GNUNET_NO.
@@ -308,6 +316,8 @@ struct ReadyList
308 struct NeighbourList *neighbour; 316 struct NeighbourList *neighbour;
309}; 317};
310 318
319
320#if !HAVE_LIBGLPK
311/* optimization direction flag: */ 321/* optimization direction flag: */
312#define GLP_MIN 1 /* minimization */ 322#define GLP_MIN 1 /* minimization */
313#define GLP_MAX 2 /* maximization */ 323#define GLP_MAX 2 /* maximization */
@@ -357,6 +367,7 @@ struct ReadyList
357#define GLP_ON 1 /* enable something */ 367#define GLP_ON 1 /* enable something */
358#define GLP_OFF 0 /* disable something */ 368#define GLP_OFF 0 /* disable something */
359 369
370
360typedef struct 371typedef struct
361{ /* simplex method control parameters */ 372{ /* simplex method control parameters */
362 int msg_lev; /* message level: */ 373 int msg_lev; /* message level: */
@@ -428,143 +439,325 @@ typedef struct
428#endif 439#endif
429 double foo_bar[29]; /* (reserved) */ 440 double foo_bar[29]; /* (reserved) */
430} glp_iocp; 441} glp_iocp;
442#endif
443
444
445/*
446 * Wrappers for GLPK Functions
447 */
431 448
432 449
450void * _lp_create_prob ( void )
451{
452#if HAVE_LIBGLPK
453 return glp_create_prob( );
454#else
455 // Function not implemented
456 GNUNET_break (0);
457#endif
458 return NULL;
459}
460
461void _lp_set_obj_dir (void *P, int dir)
462{
463#if HAVE_LIBGLPK
464 return glp_set_obj_dir (P, dir);
465#else
466 // Function not implemented
467 GNUNET_break (0);
468#endif
469}
470
433void _lp_set_prob_name (void *P, const char *name) 471void _lp_set_prob_name (void *P, const char *name)
434{ 472{
435#if HAVE_GLPK 473#if HAVE_LIBGLPK
436 glp_set_prob_name(P, name); 474 glp_set_prob_name(P, name);
475#else
476 // Function not implemented
477 GNUNET_break (0);
437#endif 478#endif
438} 479}
439 480
440int _lp_add_cols (void *P, int ncs) 481int _lp_add_cols (void *P, int ncs)
441{ 482{
442#if HAVE_GLPK 483#if HAVE_LIBGLPK
443 return glp_add_cols(P, ncs); 484 return glp_add_cols(P, ncs);
485#else
486 // Function not implemented
487 GNUNET_break (0);
444#endif 488#endif
445 return 0; 489 return 0;
446} 490}
447 491
492int _lp_add_rows (void *P, int nrs)
493{
494#if HAVE_LIBGLPK
495 return glp_add_rows (P, nrs);
496#else
497 // Function not implemented
498 GNUNET_break (0);
499#endif
500 return 0;
501}
502
503
448void _lp_set_row_bnds (void *P, int i, int type, double lb, double ub) 504void _lp_set_row_bnds (void *P, int i, int type, double lb, double ub)
449{ 505{
450#if HAVE_GLPK 506#if HAVE_LIBGLPK
451 glp_set_row_bnds(P, i , type, lb, ub); 507 glp_set_row_bnds(P, i , type, lb, ub);
508#else
509 // Function not implemented
510 GNUNET_break (0);
452#endif 511#endif
453} 512}
454 513
455void _lp_init_smcp (void * parm) 514void _lp_init_smcp (void * parm)
456{ 515{
457#if HAVE_GLPK 516#if HAVE_LIBGLPK
458 glp_init_smcp(parm); 517 glp_init_smcp(parm);
518#else
519 // Function not implemented
520 GNUNET_break (0);
459#endif 521#endif
460} 522}
461 523
462void _lp_set_col_name (void *P, int j, const char *name) 524void _lp_set_col_name (void *P, int j, const char *name)
463{ 525{
464#if HAVE_GLPK 526#if HAVE_LIBGLPK
465 glp_set_col_name (P, j, name); 527 glp_set_col_name (P, j, name);
528#else
529 // Function not implemented
530 GNUNET_break (0);
466#endif 531#endif
467} 532}
468 533
469void _lp_set_col_bnds (void *P, int j, int type, double lb, 534void _lp_set_col_bnds (void *P, int j, int type, double lb,
470 double ub) 535 double ub)
471{ 536{
472#if HAVE_GLPK 537#if HAVE_LIBGLPK
473 glp_set_col_bnds(P, j, type, lb, ub); 538 glp_set_col_bnds(P, j, type, lb, ub);
539#else
540 // Function not implemented
541 GNUNET_break (0);
474#endif 542#endif
475} 543}
476 544
477void _lp_set_obj_coef(void *P, int j, double coef) 545void _lp_set_obj_coef(void *P, int j, double coef)
478{ 546{
479#if HAVE_GLPK 547#if HAVE_LIBGLPK
480 _lp_set_obj_coef(P, j, coef); 548 glp_set_obj_coef(P, j, coef);
549#else
550 // Function not implemented
551 GNUNET_break (0);
481#endif 552#endif
482} 553}
483 554
484void _lp_delete_prob (void * P) 555void _lp_delete_prob (void * P)
485{ 556{
486#if HAVE_GLPK 557#if HAVE_LIBGLPK
487 glp_delete_prob (P); 558 glp_delete_prob (P);
559#else
560 // Function not implemented
561 GNUNET_break (0);
488#endif 562#endif
489} 563}
490 564
491int _lp_simplex(void *P, void *parm) 565static int _lp_simplex(void *P, void *parm)
492{ 566{
493#if HAVE_GLPK 567#if HAVE_LIBGLPK
494 return glp_simplex (P, parm); 568 return glp_simplex (P, parm);
569#else
570 // Function not implemented
571 GNUNET_break (0);
495#endif 572#endif
496 return 0; 573 return 0;
497} 574}
498 575
499void _lp_load_matrix (void *P, int ne, const int ia[], 576static void _lp_load_matrix (void *P, int ne, const int ia[],
500 const int ja[], const double ar[]) 577 const int ja[], const double ar[])
501{ 578{
502#if HAVE_GLPK 579#if HAVE_LIBGLPK
503 glp_load_matrix(P, ne, ia, ja, ar); 580 glp_load_matrix(P, ne, ia, ja, ar);
581#else
582 // Function not implemented
583 GNUNET_break (0);
504#endif 584#endif
505} 585}
506 586
507void _lp_set_mat_row (void *P, int i, int len, const int ind[], 587static void _lp_set_mat_row (void *P, int i, int len, const int ind[],
508 const double val[]) 588 const double val[])
509{ 589{
510#if HAVE_GLPK 590#if HAVE_LIBGLPK
511 glp_set_mat_row (P, i, len, ind, val); 591 glp_set_mat_row (P, i, len, ind, val);
592#else
593 // Function not implemented
594 GNUNET_break (0);
512#endif 595#endif
513} 596}
514 597
515int _lp_write_lp (void * *P, const void *parm, const char *fname) 598static int _lp_write_lp (void *P, const void *parm, const char *fname)
516{ 599{
517#if HAVE_GLPK 600#if HAVE_LIBGLPK
518 return glp_write_lp (P, parm, fname); 601 return glp_write_lp ( P, parm, fname);
602#else
603 // Function not implemented
604 GNUNET_break (0);
519#endif 605#endif
520 return 0; 606 return 0;
521} 607}
522 608
523void _lp_init_iocp (void *parm) 609static void _lp_init_iocp (void *parm)
524{ 610{
525#if HAVE_GLPK 611#if HAVE_LIBGLPK
526 glp_init_iocp (parm); 612 glp_init_iocp (parm);
613#else
614 // Function not implemented
615 GNUNET_break (0);
527#endif 616#endif
528} 617}
529 618
530int _lp_intopt (void *P, const void *parm) 619static int _lp_intopt (void *P, const void *parm)
531{ 620{
532#if HAVE_GLPK 621#if HAVE_LIBGLPK
533 return glp_intopt (P, parm); 622 return glp_intopt (P, parm);
623#else
624 // Function not implemented
625 GNUNET_break (0);
534#endif 626#endif
535 return 0; 627 return 0;
536} 628}
537 629
538int _lp_get_status (void *P) 630static int _lp_get_status (void *P)
539{ 631{
540#if HAVE_GLPK 632#if HAVE_LIBGLPK
541 return glp_get_status (P); 633 return glp_get_status (P);
634#else
635 // Function not implemented
636 GNUNET_break (0);
542#endif 637#endif
543 return 0; 638 return 0;
544} 639}
545 640
546int _lp_mip_status(void *P) 641static int _lp_mip_status (void *P)
547{ 642{
548#if HAVE_GLPK 643#if HAVE_LIBGLPK
549 return glp_mip_status (P); 644 return glp_mip_status (P);
645#else
646 // Function not implemented
647 GNUNET_break (0);
550#endif 648#endif
551 return 0; 649 return 0;
552} 650}
553 651
652static void _lp_set_col_kind (void *P, int j, int kind)
653{
654#if HAVE_LIBGLPK
655 glp_set_col_kind (P, j, kind);
656#else
657 // Function not implemented
658 GNUNET_break (0);
659#endif
660}
661
662static void _lp_free_env (void)
663{
664#if HAVE_LIBGLPK
665 glp_free_env ();
666#else
667 // Function not implemented
668 GNUNET_break (0);
669#endif
670}
671
672static const char * _lp_get_col_name ( void *P, int j)
673{
674#if HAVE_LIBGLPK
675 return glp_get_col_name (P, j);
676#else
677 // Function not implemented
678 GNUNET_break (0);
679#endif
680 return NULL;
681}
682
683static double _lp_mip_obj_val (void *P)
684{
685#if HAVE_LIBGLPK
686 return glp_mip_obj_val (P);
687#else
688 // Function not implemented
689 GNUNET_break (0);
690#endif
691 return 0.0;
692}
693
694
695static double _lp_get_col_prim (void *P, int j)
696{
697#if HAVE_LIBGLPK
698 return glp_get_col_prim (P , j);
699#else
700 // Function not implemented
701 GNUNET_break (0);
702#endif
703 return 0.0;
704}
554 705
555struct ATS_info * ats_init (const struct GNUNET_CONFIGURATION_Handle *cfg) 706static int _lp_print_sol(void *P, const char *fname)
556{ 707{
708#if HAVE_LIBGLPK
709 return glp_print_sol (P, fname);
710#else
711 // Function not implemented
712 GNUNET_break (0);
713#endif
714 return 0;
715}
716
717/*
718 * Dummy functions for CFLAGS
719 */
720
721static void _dummy2 ();
722static void _dummy ()
723{
724 return;
725 _lp_get_col_name (NULL, 0);
726 _lp_mip_obj_val (NULL);
727 _lp_get_col_prim (NULL, 0);
728 _dummy2();
729}
730
731static void _dummy2 ()
732{
733 _dummy();
734}
735
736/*
737 * ATS Functions
738 */
739
740
741/**
742 * Initialize ATS
743 * @param cfg configuration handle to retrieve configuration (to be removed)
744 * @return
745 */
746
747struct ATS_Handle * ats_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
748{
749
557#if !HAVE_LIBGLPK 750#if !HAVE_LIBGLPK
558 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS not active\n"); 751 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS not active\n");
559 return NULL; 752 return NULL;
560#endif 753#endif
561 754
562 struct ATS_info * ats = NULL; 755 struct ATS_Handle * ats = NULL;
563 int c = 0; 756 int c = 0;
564 unsigned long long value; 757 unsigned long long value;
565 char * section; 758 char * section;
566 759
567 ats = GNUNET_malloc(sizeof (struct ATS_info)); 760 ats = GNUNET_malloc(sizeof (struct ATS_Handle));
568 761
569 ats->prob = NULL; 762 ats->prob = NULL;
570 763
@@ -627,43 +820,56 @@ struct ATS_info * ats_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
627 } 820 }
628 821
629 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "DUMP_MLP")) 822 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "DUMP_MLP"))
630 ats->save_mlp = GNUNET_CONFIGURATION_get_value_yesno (cfg, "transport","DUMP_MLP"); 823 ats->save_mlp = GNUNET_CONFIGURATION_get_value_yesno (cfg,
824 "transport","DUMP_MLP");
631 825
632 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "DUMP_SOLUTION")) 826 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "DUMP_SOLUTION"))
633 ats->save_solution = GNUNET_CONFIGURATION_get_value_yesno (cfg, "transport","DUMP_SOLUTION"); 827 ats->save_solution = GNUNET_CONFIGURATION_get_value_yesno (cfg,
828 "transport","DUMP_SOLUTION");
634 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "DUMP_OVERWRITE")) 829 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "DUMP_OVERWRITE"))
635 ats->dump_overwrite = GNUNET_CONFIGURATION_get_value_yesno (cfg, "transport","DUMP_OVERWRITE"); 830 ats->dump_overwrite = GNUNET_CONFIGURATION_get_value_yesno (cfg,
831 "transport","DUMP_OVERWRITE");
636 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "DUMP_MIN_PEERS")) 832 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "DUMP_MIN_PEERS"))
637 { 833 {
638 GNUNET_CONFIGURATION_get_value_number(cfg, "transport","DUMP_MIN_PEERS", &value); 834 GNUNET_CONFIGURATION_get_value_number(cfg,
835 "transport","DUMP_MIN_PEERS", &value);
639 ats->dump_min_peers= value; 836 ats->dump_min_peers= value;
640 } 837 }
641 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "DUMP_MIN_ADDRS")) 838 if (GNUNET_CONFIGURATION_have_value(cfg,
839 "transport", "DUMP_MIN_ADDRS"))
642 { 840 {
643 GNUNET_CONFIGURATION_get_value_number(cfg, "transport","DUMP_MIN_ADDRS", &value); 841 GNUNET_CONFIGURATION_get_value_number(cfg,
644 ats->dump_min_addr= value; 842 "transport","DUMP_MIN_ADDRS", &value);
843 ats->dump_min_addr= value;
645 } 844 }
646 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "DUMP_OVERWRITE")) 845 if (GNUNET_CONFIGURATION_have_value(cfg,
846 "transport", "DUMP_OVERWRITE"))
647 { 847 {
648 GNUNET_CONFIGURATION_get_value_number(cfg, "transport","DUMP_OVERWRITE", &value); 848 GNUNET_CONFIGURATION_get_value_number(cfg,
649 ats->min_delta.rel_value = value; 849 "transport","DUMP_OVERWRITE", &value);
850 ats->min_delta.rel_value = value;
650 } 851 }
651 852
652 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "ATS_MIN_INTERVAL")) 853 if (GNUNET_CONFIGURATION_have_value(cfg,
854 "transport", "ATS_MIN_INTERVAL"))
653 { 855 {
654 GNUNET_CONFIGURATION_get_value_number(cfg, "transport","ATS_MIN_INTERVAL", &value); 856 GNUNET_CONFIGURATION_get_value_number(cfg,
655 ats->min_delta.rel_value = value; 857 "transport","ATS_MIN_INTERVAL", &value);
858 ats->min_delta.rel_value = value;
656 } 859 }
657 860
658 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "ATS_EXEC_INTERVAL")) 861 if (GNUNET_CONFIGURATION_have_value(cfg,
862 "transport", "ATS_EXEC_INTERVAL"))
659 { 863 {
660 GNUNET_CONFIGURATION_get_value_number(cfg, "transport","ATS_EXEC_INTERVAL", &value); 864 GNUNET_CONFIGURATION_get_value_number(cfg,
661 ats->exec_interval.rel_value = value; 865 "transport","ATS_EXEC_INTERVAL", &value);
866 ats->exec_interval.rel_value = value;
662 } 867 }
663 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "ATS_MIN_INTERVAL")) 868 if (GNUNET_CONFIGURATION_have_value(cfg, "transport", "ATS_MIN_INTERVAL"))
664 { 869 {
665 GNUNET_CONFIGURATION_get_value_number(cfg, "transport","ATS_MIN_INTERVAL", &value); 870 GNUNET_CONFIGURATION_get_value_number(cfg,
666 ats->min_delta.rel_value = value; 871 "transport","ATS_MIN_INTERVAL", &value);
872 ats->min_delta.rel_value = value;
667 } 873 }
668 return ats; 874 return ats;
669} 875}
@@ -680,16 +886,21 @@ struct ATS_info * ats_init (const struct GNUNET_CONFIGURATION_Handle *cfg)
680 * @param stat result struct 886 * @param stat result struct
681 * @return GNUNET_SYSERR if glpk is not available, number of mechanisms used 887 * @return GNUNET_SYSERR if glpk is not available, number of mechanisms used
682 */ 888 */
683int ats_create_problem (struct ATS_info *ats, struct NeighbourList *neighbours, double D, double U, double R, int v_b_min, int v_n_min, struct ATS_stat *stat) 889int ats_create_problem (struct ATS_Handle *ats,
890 struct NeighbourList *neighbours,
891 double D,
892 double U,
893 double R,
894 int v_b_min,
895 int v_n_min,
896 struct ATS_stat *stat)
684{ 897{
685#if !HAVE_LIBGLPK 898#if !HAVE_LIBGLPK
686 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS not active\n"); 899 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS not active\n");
687 return GNUNET_SYSERR; 900 return GNUNET_SYSERR;
688#endif 901#endif
689 902
690#if HAVE_LIBGLPK 903 ats->prob = _lp_create_prob();
691 ats->prob = glp_create_prob();
692#endif
693 904
694 int c; 905 int c;
695 int c_peers = 0; 906 int c_peers = 0;
@@ -728,7 +939,9 @@ int ats_create_problem (struct ATS_info *ats, struct NeighbourList *neighbours,
728 if (c_mechs==0) 939 if (c_mechs==0)
729 { 940 {
730#if DEBUG_ATS 941#if DEBUG_ATS
731 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No addresses for bw distribution available\n", c_peers); 942 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
943 "No addresses for bw distribution available\n",
944 c_peers);
732#endif 945#endif
733 stat->valid = GNUNET_NO; 946 stat->valid = GNUNET_NO;
734 stat->c_peers = 0; 947 stat->c_peers = 0;
@@ -750,38 +963,40 @@ int ats_create_problem (struct ATS_info *ats, struct NeighbourList *neighbours,
750 next = neighbours; 963 next = neighbours;
751 while (next!=NULL) 964 while (next!=NULL)
752 { 965 {
753 int found_addresses = GNUNET_NO; 966 int found_addresses = GNUNET_NO;
754 struct ReadyList *r_next = next->plugins; 967 struct ReadyList *r_next = next->plugins;
755 while (r_next != NULL) 968 while (r_next != NULL)
756 { 969 {
757 struct ForeignAddressList * a_next = r_next->addresses; 970 struct ForeignAddressList * a_next = r_next->addresses;
758 while (a_next != NULL) 971 while (a_next != NULL)
759 { 972 {
760 if (found_addresses == GNUNET_NO) 973 if (found_addresses == GNUNET_NO)
761 { 974 {
762 peers[c_peers].peer = next->id; 975 peers[c_peers].peer = next->id;
763 peers[c_peers].m_head = NULL; 976 peers[c_peers].m_head = NULL;
764 peers[c_peers].m_tail = NULL; 977 peers[c_peers].m_tail = NULL;
765 peers[c_peers].f = 1.0 / c_mechs; 978 peers[c_peers].f = 1.0 / c_mechs;
766 } 979 }
767 980
768 mechanisms[c_mechs].addr = a_next; 981 mechanisms[c_mechs].addr = a_next;
769 mechanisms[c_mechs].col_index = c_mechs; 982 mechanisms[c_mechs].col_index = c_mechs;
770 mechanisms[c_mechs].peer = &peers[c_peers]; 983 mechanisms[c_mechs].peer = &peers[c_peers];
771 mechanisms[c_mechs].next = NULL; 984 mechanisms[c_mechs].next = NULL;
772 mechanisms[c_mechs].plugin = r_next->plugin; 985 mechanisms[c_mechs].plugin = r_next->plugin;
773 986
774 GNUNET_CONTAINER_DLL_insert_tail(peers[c_peers].m_head, peers[c_peers].m_tail, &mechanisms[c_mechs]); 987 GNUNET_CONTAINER_DLL_insert_tail(peers[c_peers].m_head,
775 found_addresses = GNUNET_YES; 988 peers[c_peers].m_tail,
776 c_mechs++; 989 &mechanisms[c_mechs]);
777 990 found_addresses = GNUNET_YES;
778 a_next = a_next->next; 991 c_mechs++;
779 } 992
780 r_next = r_next->next; 993 a_next = a_next->next;
781 } 994 }
782 if (found_addresses == GNUNET_YES) 995 r_next = r_next->next;
783 c_peers++; 996 }
784 next = next->next; 997 if (found_addresses == GNUNET_YES)
998 c_peers++;
999 next = next->next;
785 } 1000 }
786 c_mechs--; 1001 c_mechs--;
787 c_peers--; 1002 c_peers--;
@@ -790,21 +1005,23 @@ int ats_create_problem (struct ATS_info *ats, struct NeighbourList *neighbours,
790 v_n_min = c_peers; 1005 v_n_min = c_peers;
791 1006
792#if VERBOSE_ATS 1007#if VERBOSE_ATS
793 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Creating problem with: %i peers, %i mechanisms, %i resource entries, %i quality metrics \n", c_peers, c_mechs, c_c_ressources, c_q_metrics); 1008 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Creating problem with: %i peers, %i mechanisms, %i resource entries, %i quality metrics \n",
1009 c_peers,
1010 c_mechs,
1011 c_c_ressources,
1012 c_q_metrics);
794#endif 1013#endif
795 1014
796 int size = 1 + 3 + 10 *c_mechs + c_peers + (c_q_metrics*c_mechs)+ c_q_metrics + c_c_ressources * c_mechs ; 1015 int size = 1 + 3 + 10 *c_mechs + c_peers +
1016 (c_q_metrics*c_mechs)+ c_q_metrics + c_c_ressources * c_mechs ;
797 int row_index; 1017 int row_index;
798 int array_index=1; 1018 int array_index=1;
799 int * ia = GNUNET_malloc (size * sizeof (int)); 1019 int * ia = GNUNET_malloc (size * sizeof (int));
800 int * ja = GNUNET_malloc (size * sizeof (int)); 1020 int * ja = GNUNET_malloc (size * sizeof (int));
801 double * ar = GNUNET_malloc(size* sizeof (double)); 1021 double * ar = GNUNET_malloc(size* sizeof (double));
802 1022
803
804 _lp_set_prob_name (ats->prob, "gnunet ats bandwidth distribution"); 1023 _lp_set_prob_name (ats->prob, "gnunet ats bandwidth distribution");
805#if HAVE_LIBGLPK 1024 _lp_set_obj_dir(ats->prob, GLP_MAX);
806 glp_set_obj_dir(ats->prob, GLP_MAX);
807#endif
808 1025
809 /* adding columns */ 1026 /* adding columns */
810 char * name; 1027 char * name;
@@ -812,97 +1029,104 @@ int ats_create_problem (struct ATS_info *ats, struct NeighbourList *neighbours,
812 /* adding b_t cols */ 1029 /* adding b_t cols */
813 for (c=1; c <= c_mechs; c++) 1030 for (c=1; c <= c_mechs; c++)
814 { 1031 {
815#if HAVE_LIBGLPK 1032 GNUNET_asprintf(&name,
816 GNUNET_asprintf(&name, "p_%s_b%i",GNUNET_i2s(&(mechanisms[c].peer->peer)), c); 1033 "p_%s_b%i",GNUNET_i2s(&(mechanisms[c].peer->peer)), c);
817 _lp_set_col_name(ats->prob, c, name); 1034 _lp_set_col_name(ats->prob, c, name);
818 GNUNET_free (name); 1035 GNUNET_free (name);
819 _lp_set_col_bnds(ats->prob, c, GLP_LO, 0.0, 0.0); 1036 _lp_set_col_bnds(ats->prob, c, GLP_LO, 0.0, 0.0);
820 glp_set_col_kind(ats->prob, c, GLP_CV); 1037 _lp_set_col_kind(ats->prob, c, GLP_CV);
821 _lp_set_obj_coef(ats->prob, c, 0); 1038 //_lp_set_obj_coef(ats->prob, c, 0);
822#endif
823
824 } 1039 }
1040
825 /* adding n_t cols */ 1041 /* adding n_t cols */
826 for (c=c_mechs+1; c <= 2*c_mechs; c++) 1042 for (c=c_mechs+1; c <= 2*c_mechs; c++)
827 { 1043 {
828#if HAVE_LIBGLPK 1044 GNUNET_asprintf(&name,
829 GNUNET_asprintf(&name, "p_%s_n%i",GNUNET_i2s(&(mechanisms[c-c_mechs].peer->peer)),(c-c_mechs)); 1045 "p_%s_n%i",GNUNET_i2s(&(mechanisms[c-c_mechs].peer->peer)),(c-c_mechs));
830 _lp_set_col_name(ats->prob, c, name); 1046 _lp_set_col_name(ats->prob, c, name);
831 GNUNET_free (name); 1047 GNUNET_free (name);
832 _lp_set_col_bnds(ats->prob, c, GLP_DB, 0.0, 1.0); 1048 _lp_set_col_bnds(ats->prob, c, GLP_DB, 0.0, 1.0);
833 glp_set_col_kind(ats->prob, c, GLP_IV); 1049 _lp_set_col_kind(ats->prob, c, GLP_IV);
834 _lp_set_obj_coef(ats->prob, c, 0); 1050 _lp_set_obj_coef(ats->prob, c, 0);
835#endif
836 } 1051 }
837 1052
838 /* feasibility constraints */ 1053 /* feasibility constraints */
839 /* Constraint 1: one address per peer*/ 1054 /* Constraint 1: one address per peer*/
840 row_index = 1; 1055 row_index = 1;
841#if HAVE_LIBGLPK 1056
842 glp_add_rows(ats->prob, c_peers); 1057 _lp_add_rows(ats->prob, c_peers);
843#endif 1058
844 for (c=1; c<=c_peers; c++) 1059 for (c=1; c<=c_peers; c++)
845 { 1060 {
846#if VERBOSE_ATS 1061#if VERBOSE_ATS
847 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index); 1062 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",
1063 row_index);
848#endif 1064#endif
849#if HAVE_LIBGLPK 1065
850 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 1.0, 1.0); 1066 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 1.0, 1.0);
851#endif 1067 struct ATS_mechanism *m = peers[c].m_head;
852 struct ATS_mechanism *m = peers[c].m_head; 1068 while (m!=NULL)
853 while (m!=NULL) 1069 {
854 { 1070 ia[array_index] = row_index;
855 ia[array_index] = row_index; 1071 ja[array_index] = (c_mechs + m->col_index);
856 ja[array_index] = (c_mechs + m->col_index); 1072 ar[array_index] = 1;
857 ar[array_index] = 1;
858#if VERBOSE_ATS 1073#if VERBOSE_ATS
859 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]); 1074 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
860#endif 1075 array_index,
861 array_index++; 1076 ia[array_index],
862 m = m->next; 1077 ja[array_index],
863 } 1078 ar[array_index]);
864 row_index++; 1079#endif
1080 array_index++;
1081 m = m->next;
1082 }
1083 row_index++;
865 } 1084 }
866 1085
867 /* Constraint 2: only active mechanism gets bandwidth assigned */ 1086 /* Constraint 2: only active mechanism gets bandwidth assigned */
868#if HAVE_LIBGLPK 1087 _lp_add_rows(ats->prob, c_mechs);
869 glp_add_rows(ats->prob, c_mechs);
870#endif
871 for (c=1; c<=c_mechs; c++) 1088 for (c=1; c<=c_mechs; c++)
872 { 1089 {
873 /* b_t - n_t * M <= 0 */ 1090 /* b_t - n_t * M <= 0 */
874#if VERBOSE_ATS 1091#if VERBOSE_ATS
875 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index); 1092 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",
1093 row_index);
876#endif 1094#endif
877#if HAVE_LIBGLPK
878 _lp_set_row_bnds(ats->prob, row_index, GLP_UP, 0.0, 0.0); 1095 _lp_set_row_bnds(ats->prob, row_index, GLP_UP, 0.0, 0.0);
879#endif
880 ia[array_index] = row_index; 1096 ia[array_index] = row_index;
881 ja[array_index] = mechanisms[c].col_index; 1097 ja[array_index] = mechanisms[c].col_index;
882 ar[array_index] = 1; 1098 ar[array_index] = 1;
883#if VERBOSE_ATS 1099#if VERBOSE_ATS
884 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]); 1100 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
1101 array_index,
1102 ia[array_index],
1103 ja[array_index],
1104 ar[array_index]);
885#endif 1105#endif
886 array_index++; 1106 array_index++;
887 ia[array_index] = row_index; 1107 ia[array_index] = row_index;
888 ja[array_index] = c_mechs + mechanisms[c].col_index; 1108 ja[array_index] = c_mechs + mechanisms[c].col_index;
889 ar[array_index] = -M; 1109 ar[array_index] = -M;
890#if VERBOSE_ATS 1110#if VERBOSE_ATS
891 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]); 1111 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
1112 array_index,
1113 ia[array_index],
1114 ja[array_index],
1115 ar[array_index]);
892#endif 1116#endif
893 array_index++; 1117 array_index++;
894 row_index ++; 1118 row_index ++;
895 } 1119 }
896 1120
897 /* Constraint 3: minimum bandwidth*/ 1121 /* Constraint 3: minimum bandwidth*/
898#if HAVE_LIBGLPK 1122 _lp_add_rows(ats->prob, c_mechs);
899 glp_add_rows(ats->prob, c_mechs); 1123
900#endif
901 for (c=1; c<=c_mechs; c++) 1124 for (c=1; c<=c_mechs; c++)
902 { 1125 {
903 /* b_t - n_t * b_min <= 0 */ 1126 /* b_t - n_t * b_min <= 0 */
904#if VERBOSE_ATS 1127#if VERBOSE_ATS
905 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index); 1128 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",
1129 row_index);
906#endif 1130#endif
907#if HAVE_LIBGLPK 1131#if HAVE_LIBGLPK
908 _lp_set_row_bnds(ats->prob, row_index, GLP_LO, 0.0, 0.0); 1132 _lp_set_row_bnds(ats->prob, row_index, GLP_LO, 0.0, 0.0);
@@ -911,25 +1135,34 @@ int ats_create_problem (struct ATS_info *ats, struct NeighbourList *neighbours,
911 ja[array_index] = mechanisms[c].col_index; 1135 ja[array_index] = mechanisms[c].col_index;
912 ar[array_index] = 1; 1136 ar[array_index] = 1;
913#if VERBOSE_ATS 1137#if VERBOSE_ATS
914 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]); 1138 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
1139 array_index,
1140 ia[array_index],
1141 ja[array_index],
1142 ar[array_index]);
915#endif 1143#endif
916 array_index++; 1144 array_index++;
917 ia[array_index] = row_index; 1145 ia[array_index] = row_index;
918 ja[array_index] = c_mechs + mechanisms[c].col_index; 1146 ja[array_index] = c_mechs + mechanisms[c].col_index;
919 ar[array_index] = -v_b_min; 1147 ar[array_index] = -v_b_min;
920#if VERBOSE_ATS 1148#if VERBOSE_ATS
921 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]); 1149 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
1150 array_index,
1151 ia[array_index],
1152 ja[array_index],
1153 ar[array_index]);
922#endif 1154#endif
923 array_index++; 1155 array_index++;
924 row_index ++; 1156 row_index ++;
925 } 1157 }
926 int c2; 1158 int c2;
1159
927 /* Constraint 4: max ressource capacity */ 1160 /* Constraint 4: max ressource capacity */
928 /* V cr: bt * ct_r <= cr_max 1161 /* V cr: bt * ct_r <= cr_max
929 * */ 1162 * */
930#if HAVE_LIBGLPK 1163
931 glp_add_rows(ats->prob, available_ressources); 1164 _lp_add_rows(ats->prob, available_ressources);
932#endif 1165
933 double ct_max = VERY_BIG_DOUBLE_VALUE; 1166 double ct_max = VERY_BIG_DOUBLE_VALUE;
934 double ct_min = 0.0; 1167 double ct_min = 0.0;
935 1168
@@ -937,48 +1170,56 @@ int ats_create_problem (struct ATS_info *ats, struct NeighbourList *neighbours,
937 1170
938 for (c=0; c<available_ressources; c++) 1171 for (c=0; c<available_ressources; c++)
939 { 1172 {
940 ct_max = ressources[c].c_max; 1173 ct_max = ressources[c].c_max;
941 ct_min = ressources[c].c_min; 1174 ct_min = ressources[c].c_min;
942#if VERBOSE_ATS 1175#if VERBOSE_ATS
943 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] %f..%f\n",row_index, ct_min, ct_max); 1176 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] %f..%f\n",
1177 row_index,
1178 ct_min,
1179 ct_max);
944#endif 1180#endif
945#if HAVE_LIBGLPK 1181#if HAVE_LIBGLPK
946 _lp_set_row_bnds(ats->prob, row_index, GLP_DB, ct_min, ct_max); 1182 _lp_set_row_bnds(ats->prob, row_index, GLP_DB, ct_min, ct_max);
947#endif 1183#endif
948 for (c2=1; c2<=c_mechs; c2++) 1184 for (c2=1; c2<=c_mechs; c2++)
949 { 1185 {
950 double value = 0; 1186 double value = 0;
951 ia[array_index] = row_index; 1187 ia[array_index] = row_index;
952 ja[array_index] = c2; 1188 ja[array_index] = c2;
953 value = mechanisms[c2].addr->ressources[c].c; 1189 value = mechanisms[c2].addr->ressources[c].c;
954 ar[array_index] = value; 1190 ar[array_index] = value;
955#if VERBOSE_ATS 1191#if VERBOSE_ATS
956 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]); 1192 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
1193 array_index, ia[array_index],
1194 ja[array_index],
1195 ar[array_index]);
957#endif 1196#endif
958 array_index++; 1197 array_index++;
959 } 1198 }
960 row_index ++; 1199 row_index ++;
961 } 1200 }
962 stat->end_cr = array_index--; 1201 stat->end_cr = array_index--;
963 1202
964 /* Constraint 5: min number of connections*/ 1203 /* Constraint 5: min number of connections*/
965#if HAVE_LIBGLPK 1204 _lp_add_rows(ats->prob, 1);
966 glp_add_rows(ats->prob, 1); 1205
967#endif
968 for (c=1; c<=c_mechs; c++) 1206 for (c=1; c<=c_mechs; c++)
969 { 1207 {
970 // b_t - n_t * b_min >= 0 1208 // b_t - n_t * b_min >= 0
971#if VERBOSE_ATS 1209#if VERBOSE_ATS
972 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index); 1210 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",
1211 row_index);
973#endif 1212#endif
974#if HAVE_LIBGLPK
975 _lp_set_row_bnds(ats->prob, row_index, GLP_LO, v_n_min, 0.0); 1213 _lp_set_row_bnds(ats->prob, row_index, GLP_LO, v_n_min, 0.0);
976#endif
977 ia[array_index] = row_index; 1214 ia[array_index] = row_index;
978 ja[array_index] = c_mechs + mechanisms[c].col_index; 1215 ja[array_index] = c_mechs + mechanisms[c].col_index;
979 ar[array_index] = 1; 1216 ar[array_index] = 1;
980#if VERBOSE_ATS 1217#if VERBOSE_ATS
981 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]); 1218 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
1219 array_index,
1220 ia[array_index],
1221 ja[array_index],
1222 ar[array_index]);
982#endif 1223#endif
983 array_index++; 1224 array_index++;
984 } 1225 }
@@ -990,39 +1231,45 @@ int ats_create_problem (struct ATS_info *ats, struct NeighbourList *neighbours,
990 1231
991 // Constraint 6: optimize for diversity 1232 // Constraint 6: optimize for diversity
992 int col_d; 1233 int col_d;
993
994 col_d = _lp_add_cols(ats->prob, 1); 1234 col_d = _lp_add_cols(ats->prob, 1);
995#if HAVE_LIBGLPK 1235
996 _lp_set_col_name(ats->prob, col_d, "d"); 1236 _lp_set_col_name(ats->prob, col_d, "d");
997 _lp_set_obj_coef(ats->prob, col_d, D); 1237 _lp_set_obj_coef(ats->prob, col_d, D);
998 _lp_set_col_bnds(ats->prob, col_d, GLP_LO, 0.0, 0.0); 1238 _lp_set_col_bnds(ats->prob, col_d, GLP_LO, 0.0, 0.0);
999 glp_add_rows(ats->prob, 1); 1239 _lp_add_rows(ats->prob, 1);
1000 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 0.0, 0.0); 1240 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 0.0, 0.0);
1001#endif 1241
1002 stat->col_d = col_d; 1242 stat->col_d = col_d;
1003#if VERBOSE_ATS 1243#if VERBOSE_ATS
1004 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index); 1244 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index);
1005#endif 1245#endif
1006 for (c=1; c<=c_mechs; c++) 1246 for (c=1; c<=c_mechs; c++)
1007 { 1247 {
1008 ia[array_index] = row_index; 1248 ia[array_index] = row_index;
1009 ja[array_index] = c_mechs + mechanisms[c].col_index; 1249 ja[array_index] = c_mechs + mechanisms[c].col_index;
1010 ar[array_index] = 1; 1250 ar[array_index] = 1;
1011#if VERBOSE_ATS 1251#if VERBOSE_ATS
1012 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]); 1252 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
1253 array_index,
1254 ia[array_index],
1255 ja[array_index],
1256 ar[array_index]);
1013#endif 1257#endif
1014 array_index++; 1258 array_index++;
1015 } 1259 }
1016 ia[array_index] = row_index; 1260 ia[array_index] = row_index;
1017 ja[array_index] = col_d; 1261 ja[array_index] = col_d;
1018 ar[array_index] = -1; 1262 ar[array_index] = -1;
1019#if VERBOSE_ATS 1263#if VERBOSE_ATS
1020 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]); 1264 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
1265 array_index,
1266 ia[array_index],
1267 ja[array_index],
1268 ar[array_index]);
1021#endif 1269#endif
1022 array_index++; 1270 array_index++;
1023 row_index ++; 1271 row_index ++;
1024 1272
1025
1026 // Constraint 7: optimize for quality 1273 // Constraint 7: optimize for quality
1027 int col_qm; 1274 int col_qm;
1028 col_qm = _lp_add_cols(ats->prob, c_q_metrics); 1275 col_qm = _lp_add_cols(ats->prob, c_q_metrics);
@@ -1031,72 +1278,78 @@ int ats_create_problem (struct ATS_info *ats, struct NeighbourList *neighbours,
1031 //GNUNET_assert (col_qm == (2*c_mechs) + 3 + 1); 1278 //GNUNET_assert (col_qm == (2*c_mechs) + 3 + 1);
1032 for (c=0; c< c_q_metrics; c++) 1279 for (c=0; c< c_q_metrics; c++)
1033 { 1280 {
1034 GNUNET_asprintf(&name, "Q_%s",qm[c].name); 1281 GNUNET_asprintf(&name, "Q_%s",qm[c].name);
1035 _lp_set_col_name (ats->prob, col_qm + c, name); 1282 _lp_set_col_name (ats->prob, col_qm + c, name);
1036 _lp_set_col_bnds (ats->prob, col_qm + c, GLP_LO, 0.0, 0.0); 1283 _lp_set_col_bnds (ats->prob, col_qm + c, GLP_LO, 0.0, 0.0);
1037 GNUNET_free (name); 1284 GNUNET_free (name);
1038 _lp_set_obj_coef (ats->prob, col_qm + c, Q[c]); 1285 _lp_set_obj_coef (ats->prob, col_qm + c, Q[c]);
1039 } 1286 }
1040#if HAVE_LIBGLPK 1287
1041 glp_add_rows(ats->prob, available_quality_metrics); 1288 _lp_add_rows(ats->prob, available_quality_metrics);
1042#endif 1289
1043 stat->begin_qm = row_index; 1290 stat->begin_qm = row_index;
1044 for (c=1; c <= c_q_metrics; c++) 1291 for (c=1; c <= c_q_metrics; c++)
1045 { 1292 {
1046#if VERBOSE_ATS 1293#if VERBOSE_ATS
1047 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index); 1294 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",
1295 row_index);
1048#endif 1296#endif
1049 double value = 1; 1297 double value = 1;
1050#if HAVE_LIBGLPK 1298 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 0.0, 0.0);
1051 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 0.0, 0.0); 1299 for (c2=1; c2<=c_mechs; c2++)
1052#endif 1300 {
1053 for (c2=1; c2<=c_mechs; c2++) 1301 ia[array_index] = row_index;
1302 ja[array_index] = c2;
1303 if (qm[c-1].atis_index == GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY)
1054 { 1304 {
1055 1305 double v0 = 0, v1 = 0, v2 = 0;
1056 ia[array_index] = row_index; 1306 v0 = mechanisms[c2].addr->quality[c-1].values[0];
1057 ja[array_index] = c2; 1307 if (v1 < 1) v0 = 0.1;
1058 if (qm[c-1].atis_index == GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY) 1308 v1 = mechanisms[c2].addr->quality[c-1].values[1];
1059 { 1309 if (v1 < 1) v0 = 0.1;
1060 double v0 = 0, v1 = 0, v2 = 0; 1310 v2 = mechanisms[c2].addr->quality[c-1].values[2];
1061 v0 = mechanisms[c2].addr->quality[c-1].values[0]; 1311 if (v1 < 1) v0 = 0.1;
1062 if (v1 < 1) v0 = 0.1; 1312 value = 100.0 / ((v0 + 2 * v1 + 3 * v2) / 6.0);
1063 v1 = mechanisms[c2].addr->quality[c-1].values[1]; 1313 value = 1;
1064 if (v1 < 1) v0 = 0.1;
1065 v2 = mechanisms[c2].addr->quality[c-1].values[2];
1066 if (v1 < 1) v0 = 0.1;
1067 value = 100.0 / ((v0 + 2 * v1 + 3 * v2) / 6.0);
1068 value = 1;
1069 }
1070 if (qm[c-1].atis_index == GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE)
1071 {
1072 double v0 = 0, v1 = 0, v2 = 0;
1073 v0 = mechanisms[c2].addr->quality[c-1].values[0];
1074 if (v0 < 1) v0 = 1;
1075 v1 = mechanisms[c2].addr->quality[c-1].values[1];
1076 if (v1 < 1) v1 = 1;
1077 v2 = mechanisms[c2].addr->quality[c-1].values[2];
1078 if (v2 < 1) v2 = 1;
1079 value = (v0 + 2 * v1 + 3 * v2) / 6.0;
1080 if (value >= 1)
1081 value = (double) 10 / value;
1082 else
1083 value = 10;
1084 }
1085 ar[array_index] = (mechanisms[c2].peer->f) * value ;
1086#if VERBOSE_ATS
1087 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: %s [%i,%i]=%f \n",array_index, qm[c-1].name, ia[array_index], ja[array_index], ar[array_index]);
1088#endif
1089 array_index++;
1090 } 1314 }
1091 1315 if (qm[c-1].atis_index == GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE)
1092 ia[array_index] = row_index; 1316 {
1093 ja[array_index] = col_qm + c - 1; 1317 double v0 = 0, v1 = 0, v2 = 0;
1094 ar[array_index] = -1; 1318 v0 = mechanisms[c2].addr->quality[c-1].values[0];
1319 if (v0 < 1) v0 = 1;
1320 v1 = mechanisms[c2].addr->quality[c-1].values[1];
1321 if (v1 < 1) v1 = 1;
1322 v2 = mechanisms[c2].addr->quality[c-1].values[2];
1323 if (v2 < 1) v2 = 1;
1324 value = (v0 + 2 * v1 + 3 * v2) / 6.0;
1325 if (value >= 1)
1326 value = (double) 10 / value;
1327 else
1328 value = 10;
1329 }
1330 ar[array_index] = (mechanisms[c2].peer->f) * value ;
1095#if VERBOSE_ATS 1331#if VERBOSE_ATS
1096 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]); 1332 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: %s [%i,%i]=%f \n",
1333 array_index,
1334 qm[c-1].name,
1335 ia[array_index],
1336 ja[array_index],
1337 ar[array_index]);
1097#endif 1338#endif
1098 array_index++; 1339 array_index++;
1099 row_index++; 1340 }
1341 ia[array_index] = row_index;
1342 ja[array_index] = col_qm + c - 1;
1343 ar[array_index] = -1;
1344#if VERBOSE_ATS
1345 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
1346 array_index,
1347 ia[array_index],
1348 ja[array_index],
1349 ar[array_index]);
1350#endif
1351 array_index++;
1352 row_index++;
1100 } 1353 }
1101 stat->end_qm = row_index-1; 1354 stat->end_qm = row_index-1;
1102 1355
@@ -1104,12 +1357,11 @@ int ats_create_problem (struct ATS_info *ats, struct NeighbourList *neighbours,
1104 int col_u; 1357 int col_u;
1105 1358
1106 col_u = _lp_add_cols(ats->prob, 1); 1359 col_u = _lp_add_cols(ats->prob, 1);
1107#if HAVE_LIBGLPK 1360
1108 _lp_set_col_name(ats->prob, col_u, "u"); 1361 _lp_set_col_name(ats->prob, col_u, "u");
1109 _lp_set_obj_coef(ats->prob, col_u, U); 1362 _lp_set_obj_coef(ats->prob, col_u, U);
1110 _lp_set_col_bnds(ats->prob, col_u, GLP_LO, 0.0, 0.0); 1363 _lp_set_col_bnds(ats->prob, col_u, GLP_LO, 0.0, 0.0);
1111 glp_add_rows(ats->prob, 1); 1364 _lp_add_rows(ats->prob, 1);
1112#endif
1113 stat->col_u = col_u; 1365 stat->col_u = col_u;
1114#if VERBOSE_ATS 1366#if VERBOSE_ATS
1115 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index); 1367 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index);
@@ -1117,19 +1369,26 @@ int ats_create_problem (struct ATS_info *ats, struct NeighbourList *neighbours,
1117 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 0.0, 0.0); 1369 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 0.0, 0.0);
1118 for (c=1; c<=c_mechs; c++) 1370 for (c=1; c<=c_mechs; c++)
1119 { 1371 {
1120 ia[array_index] = row_index; 1372 ia[array_index] = row_index;
1121 ja[array_index] = c; 1373 ja[array_index] = c;
1122 ar[array_index] = mechanisms[c].peer->f; 1374 ar[array_index] = mechanisms[c].peer->f;
1123#if VERBOSE_ATS 1375#if VERBOSE_ATS
1124 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]); 1376 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
1377 array_index,
1378 ia[array_index],
1379 ja[array_index],
1380 ar[array_index]);
1125#endif 1381#endif
1126 array_index++; 1382 array_index++;
1127 } 1383 }
1128 ia[array_index] = row_index; 1384 ia[array_index] = row_index;
1129 ja[array_index] = col_u; 1385 ja[array_index] = col_u;
1130 ar[array_index] = -1; 1386 ar[array_index] = -1;
1131#if VERBOSE_ATS 1387#if VERBOSE_ATS
1132 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]); 1388 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
1389 array_index, ia[array_index],
1390 ja[array_index],
1391 ar[array_index]);
1133#endif 1392#endif
1134 1393
1135 array_index++; 1394 array_index++;
@@ -1139,37 +1398,44 @@ int ats_create_problem (struct ATS_info *ats, struct NeighbourList *neighbours,
1139 int col_r; 1398 int col_r;
1140 1399
1141 col_r = _lp_add_cols(ats->prob, 1); 1400 col_r = _lp_add_cols(ats->prob, 1);
1142#if HAVE_LIBGLPK 1401
1143 _lp_set_col_name(ats->prob, col_r, "r"); 1402 _lp_set_col_name(ats->prob, col_r, "r");
1144 _lp_set_obj_coef(ats->prob, col_r, R); 1403 _lp_set_obj_coef(ats->prob, col_r, R);
1145 _lp_set_col_bnds(ats->prob, col_r, GLP_LO, 0.0, 0.0); 1404 _lp_set_col_bnds(ats->prob, col_r, GLP_LO, 0.0, 0.0);
1146 glp_add_rows(ats->prob, c_peers); 1405 _lp_add_rows(ats->prob, c_peers);
1147#endif 1406
1148 stat->col_r = col_r; 1407 stat->col_r = col_r;
1149 for (c=1; c<=c_peers; c++) 1408 for (c=1; c<=c_peers; c++)
1150 { 1409 {
1151 _lp_set_row_bnds(ats->prob, row_index, GLP_LO, 0.0, 0.0); 1410 _lp_set_row_bnds(ats->prob, row_index, GLP_LO, 0.0, 0.0);
1152 1411 struct ATS_mechanism *m = peers[c].m_head;
1153 struct ATS_mechanism *m = peers[c].m_head; 1412 while (m!=NULL)
1154 while (m!=NULL) 1413 {
1155 { 1414 ia[array_index] = row_index;
1156 ia[array_index] = row_index; 1415 ja[array_index] = m->col_index;
1157 ja[array_index] = m->col_index; 1416 ar[array_index] = 1 / mechanisms[c].peer->f;
1158 ar[array_index] = 1 / mechanisms[c].peer->f;
1159#if VERBOSE_ATS 1417#if VERBOSE_ATS
1160 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]); 1418 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
1161#endif 1419 array_index,
1162 array_index++; 1420 ia[array_index],
1163 m = m->next; 1421 ja[array_index],
1164 } 1422 ar[array_index]);
1165 ia[array_index] = row_index; 1423#endif
1166 ja[array_index] = col_r; 1424 array_index++;
1167 ar[array_index] = -1; 1425 m = m->next;
1426 }
1427 ia[array_index] = row_index;
1428 ja[array_index] = col_r;
1429 ar[array_index] = -1;
1168#if VERBOSE_ATS 1430#if VERBOSE_ATS
1169 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, ia[array_index], ja[array_index], ar[array_index]); 1431 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
1170#endif 1432 array_index,
1171 array_index++; 1433 ia[array_index],
1172 row_index++; 1434 ja[array_index],
1435 ar[array_index]);
1436#endif
1437 array_index++;
1438 row_index++;
1173 } 1439 }
1174 1440
1175 /* Loading the matrix */ 1441 /* Loading the matrix */
@@ -1189,8 +1455,13 @@ int ats_create_problem (struct ATS_info *ats, struct NeighbourList *neighbours,
1189} 1455}
1190 1456
1191 1457
1192void ats_delete_problem (struct ATS_info * ats) 1458void ats_delete_problem (struct ATS_Handle * ats)
1193{ 1459{
1460#if !HAVE_LIBGLPK
1461 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS not active\n");
1462 return;
1463#endif
1464
1194#if DEBUG_ATS 1465#if DEBUG_ATS
1195 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Deleting problem\n"); 1466 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Deleting problem\n");
1196#endif 1467#endif
@@ -1198,24 +1469,22 @@ void ats_delete_problem (struct ATS_info * ats)
1198 1469
1199 for (c=0; c< (ats->stat).c_mechs; c++) 1470 for (c=0; c< (ats->stat).c_mechs; c++)
1200 GNUNET_free_non_null (ats->mechanisms[c].rc); 1471 GNUNET_free_non_null (ats->mechanisms[c].rc);
1201
1202
1203 if (ats->mechanisms!=NULL) 1472 if (ats->mechanisms!=NULL)
1204 { 1473 {
1205 GNUNET_free(ats->mechanisms); 1474 GNUNET_free(ats->mechanisms);
1206 ats->mechanisms = NULL; 1475 ats->mechanisms = NULL;
1207 } 1476 }
1208 1477
1209 if (ats->peers!=NULL) 1478 if (ats->peers!=NULL)
1210 { 1479 {
1211 GNUNET_free(ats->peers); 1480 GNUNET_free(ats->peers);
1212 ats->peers = NULL; 1481 ats->peers = NULL;
1213 } 1482 }
1214 1483
1215 if (ats->prob != NULL) 1484 if (ats->prob != NULL)
1216 { 1485 {
1217 _lp_delete_prob(ats->prob); 1486 _lp_delete_prob(ats->prob);
1218 ats->prob = NULL; 1487 ats->prob = NULL;
1219 } 1488 }
1220 1489
1221 ats->stat.begin_cr = GNUNET_SYSERR; 1490 ats->stat.begin_cr = GNUNET_SYSERR;
@@ -1230,591 +1499,691 @@ void ats_delete_problem (struct ATS_info * ats)
1230 1499
1231 1500
1232 1501
1233void ats_solve_problem (struct ATS_info * ats, unsigned int max_it, unsigned int max_dur, unsigned int c_peers, unsigned int c_mechs, struct ATS_stat *stat) 1502void ats_solve_problem (struct ATS_Handle * ats,
1503 unsigned int max_it,
1504 unsigned int max_dur,
1505 unsigned int c_peers,
1506 unsigned int c_mechs,
1507 struct ATS_stat *stat)
1234{ 1508{
1235 int result = GNUNET_SYSERR; 1509#if !HAVE_LIBGLPK
1236 int lp_solution = GNUNET_SYSERR; 1510 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS not active\n");
1237 int mlp_solution = GNUNET_SYSERR; 1511 return;
1512#endif
1238 1513
1239 // Solving simplex
1240 1514
1241 glp_smcp opt_lp; 1515 int result = GNUNET_SYSERR;
1516 int lp_solution = GNUNET_SYSERR;
1517 int mlp_solution = GNUNET_SYSERR;
1242 1518
1243 _lp_init_smcp(&opt_lp); 1519 // Solving simplex
1520
1521 glp_smcp opt_lp;
1522 _lp_init_smcp(&opt_lp);
1244#if VERBOSE_ATS 1523#if VERBOSE_ATS
1245 opt_lp.msg_lev = GLP_MSG_ALL; 1524 opt_lp.msg_lev = GLP_MSG_ALL;
1246#else 1525#else
1247 opt_lp.msg_lev = GLP_MSG_OFF; 1526 opt_lp.msg_lev = GLP_MSG_OFF;
1248#endif 1527#endif
1528 // setting iteration limit
1529 opt_lp.it_lim = max_it;
1530 // maximum duration
1531 opt_lp.tm_lim = max_dur;
1249 1532
1250 // setting iteration limit 1533 if (ats->stat.recreate_problem == GNUNET_YES)
1251 opt_lp.it_lim = max_it; 1534 opt_lp.presolve = GLP_ON;
1252 // maximum duration
1253 opt_lp.tm_lim = max_dur;
1254 1535
1255 if (ats->stat.recreate_problem == GNUNET_YES) 1536 result = _lp_simplex(ats->prob, &opt_lp);
1256 opt_lp.presolve = GLP_ON; 1537 lp_solution = _lp_get_status (ats->prob);
1257 result = _lp_simplex(ats->prob, &opt_lp);
1258 lp_solution = _lp_get_status (ats->prob);
1259 1538
1260 if ((result == GLP_ETMLIM) || (result == GLP_EITLIM)) 1539 if ((result == GLP_ETMLIM) || (result == GLP_EITLIM))
1261 { 1540 {
1262 ats->stat.valid = GNUNET_NO; 1541 ats->stat.valid = GNUNET_NO;
1263 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ATS exceeded time or iteration limit!\n"); 1542 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1264 return; 1543 "ATS exceeded time or iteration limit!\n");
1265 } 1544 return;
1545 }
1266 1546
1267 if (ats_evaluate_results(result, lp_solution, "LP") == GNUNET_YES) 1547 if (ats_evaluate_results(result, lp_solution, "LP") == GNUNET_YES)
1268 { 1548 {
1269 stat->valid = GNUNET_YES; 1549 stat->valid = GNUNET_YES;
1270 } 1550 }
1271 else 1551 else
1272 { 1552 {
1273 ats->stat.simplex_rerun_required = GNUNET_YES; 1553 ats->stat.simplex_rerun_required = GNUNET_YES;
1274 opt_lp.presolve = GLP_ON; 1554 opt_lp.presolve = GLP_ON;
1275 result = _lp_simplex(ats->prob, &opt_lp); 1555 result = _lp_simplex(ats->prob, &opt_lp);
1276 lp_solution = _lp_get_status (ats->prob); 1556 lp_solution = _lp_get_status (ats->prob);
1277
1278 // TODO: Remove if this does not appear until release
1279 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "EXECUTED SIMPLEX WITH PRESOLVER! %i \n", lp_solution);
1280
1281 if (ats_evaluate_results(result, lp_solution, "LP") != GNUNET_YES)
1282 {
1283 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "After execution simplex with presolver: STILL INVALID!\n");
1284 char * filename;
1285 GNUNET_asprintf (&filename, "ats_mlp_p%i_m%i_%llu.mlp",ats->stat.c_peers, ats->stat.c_mechs, GNUNET_TIME_absolute_get().abs_value);
1286 _lp_write_lp (ats->prob, NULL, filename);
1287 GNUNET_free (filename);
1288 stat->valid = GNUNET_NO;
1289 ats->stat.recreate_problem = GNUNET_YES;
1290 return;
1291 }
1292 stat->valid = GNUNET_YES;
1293 }
1294 1557
1295 // Solving mlp 1558 // TODO: Remove if this does not appear until release
1296 glp_iocp opt_mlp; 1559 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, ""
1297 _lp_init_iocp(&opt_mlp); 1560 "EXECUTED SIMPLEX WITH PRESOLVER! %i \n",
1298 // maximum duration 1561 lp_solution);
1299 opt_mlp.tm_lim = max_dur; 1562
1300 // output level 1563 if (ats_evaluate_results(result, lp_solution, "LP") != GNUNET_YES)
1564 {
1565 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1566 "After execution simplex with presolver: STILL INVALID!\n");
1567 char * filename;
1568 GNUNET_asprintf (&filename,
1569 "ats_mlp_p%i_m%i_%llu.mlp",
1570 ats->stat.c_peers,
1571 ats->stat.c_mechs,
1572 GNUNET_TIME_absolute_get().abs_value);
1573 _lp_write_lp ((void *)ats->prob, NULL, filename);
1574 GNUNET_free (filename);
1575 stat->valid = GNUNET_NO;
1576 ats->stat.recreate_problem = GNUNET_YES;
1577 return;
1578 }
1579 stat->valid = GNUNET_YES;
1580 }
1581
1582 // Solving mlp
1583 glp_iocp opt_mlp;
1584 _lp_init_iocp(&opt_mlp);
1585 // maximum duration
1586 opt_mlp.tm_lim = max_dur;
1587 // output level
1301#if VERBOSE_ATS 1588#if VERBOSE_ATS
1302 opt_mlp.msg_lev = GLP_MSG_ALL; 1589 opt_mlp.msg_lev = GLP_MSG_ALL;
1303#else 1590#else
1304 opt_mlp.msg_lev = GLP_MSG_OFF; 1591 opt_mlp.msg_lev = GLP_MSG_OFF;
1305#endif 1592#endif
1306 1593
1307 result = _lp_intopt (ats->prob, &opt_mlp); 1594 result = _lp_intopt (ats->prob, &opt_mlp);
1308 mlp_solution = _lp_mip_status (ats->prob); 1595 mlp_solution = _lp_mip_status (ats->prob);
1309 stat->solution = mlp_solution; 1596 stat->solution = mlp_solution;
1310 1597
1311 if (ats_evaluate_results(result, mlp_solution, "MLP") == GNUNET_YES) 1598 if (ats_evaluate_results(result, mlp_solution, "MLP") == GNUNET_YES)
1312 { 1599 {
1313 stat->valid = GNUNET_YES; 1600 stat->valid = GNUNET_YES;
1314 } 1601 }
1315 else 1602 else
1316 { 1603 {
1317 // TODO: Remove if this does not appear until release 1604 // TODO: Remove if this does not appear until release
1318 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MLP solution for %i peers, %i mechs is invalid: %i\n", ats->stat.c_peers, ats->stat.c_mechs, mlp_solution); 1605 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1319 stat->valid = GNUNET_NO; 1606 "MLP solution for %i peers, %i mechs is invalid: %i\n",
1320 } 1607 ats->stat.c_peers,
1321 1608 ats->stat.c_mechs,
1322/* 1609 mlp_solution);
1323 int check; 1610 stat->valid = GNUNET_NO;
1324 int error = GNUNET_NO; 1611 }
1325 double bw;
1326 struct ATS_mechanism *t = NULL;
1327 for (c=1; c<= (c_peers); c++ )
1328 {
1329 check = GNUNET_NO;
1330 t = peers[c].m_head;
1331 while (t!=NULL)
1332 {
1333 bw = glp_get_col_prim(prob, t->col_index);
1334 if (bw > 1.0)
1335 {
1336#if VERBOSE_ATS
1337 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[%i][%i] `%s' %s %s %f\n", c, t->col_index, GNUNET_h2s(&peers[c].peer.hashPubKey), t->plugin->short_name, glp_get_col_name(prob,t->col_index), bw);
1338#endif
1339 if (check ==GNUNET_YES)
1340 {
1341 glp_write_sol(prob, "invalid_solution.mlp");
1342 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid solution, check invalid_solution.mlp");
1343 GNUNET_STATISTICS_update (stats, "ATS invalid solutions", 1, GNUNET_NO);
1344 error = GNUNET_YES;
1345 }
1346 if (check ==GNUNET_NO)
1347 check = GNUNET_YES;
1348 }
1349 t = t->next;
1350 }
1351 }*/
1352 1612
1353#if VERBOSE_ATS 1613#if VERBOSE_ATS
1354 if (glp_get_col_prim(ats->prob,2*c_mechs+1) != 1) 1614 if (_lp_get_col_prim(ats->prob,2*c_mechs+1) != 1)
1355 { 1615 {
1356 int c; 1616 int c;
1357 for (c=1; c<= available_quality_metrics; c++ ) 1617 for (c=1; c<= available_quality_metrics; c++ )
1358 { 1618 {
1359 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s %f\n", glp_get_col_name(ats->prob,2*c_mechs+3+c), glp_get_col_prim(ats->prob,2*c_mechs+3+c)); 1619 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s %f\n",
1360 } 1620 _lp_get_col_name(ats->prob,2*c_mechs+3+c),
1361 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s %f\n", glp_get_col_name(ats->prob,2*c_mechs+1), glp_get_col_prim(ats->prob,2*c_mechs+1)); 1621 _lp_get_col_prim(ats->prob,2*c_mechs+3+c));
1362 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s %f\n", glp_get_col_name(ats->prob,2*c_mechs+2), glp_get_col_prim(ats->prob,2*c_mechs+2)); 1622 }
1363 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s %f\n", glp_get_col_name(ats->prob,2*c_mechs+3), glp_get_col_prim(ats->prob,2*c_mechs+3)); 1623 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s %f\n",
1364 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "objective value: %f\n", glp_mip_obj_val(ats->prob)); 1624 _lp_get_col_name(ats->prob,2*c_mechs+1),
1365 } 1625 _lp_get_col_prim(ats->prob,2*c_mechs+1));
1626 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s %f\n",
1627 _lp_get_col_name(ats->prob,2*c_mechs+2),
1628 _lp_get_col_prim(ats->prob,2*c_mechs+2));
1629 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s %f\n",
1630 _lp_get_col_name(ats->prob,2*c_mechs+3),
1631 _lp_get_col_prim(ats->prob,2*c_mechs+3));
1632 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "objective value: %f\n",
1633 _lp_mip_obj_val(ats->prob));
1634 }
1366#endif 1635#endif
1367} 1636}
1368 1637
1369 1638
1370void ats_shutdown (struct ATS_info * ats) 1639void ats_shutdown (struct ATS_Handle * ats)
1371{ 1640{
1372#if DEBUG_ATS 1641#if !HAVE_LIBGLPK
1373 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ats_destroy\n"); 1642 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS not active\n");
1643 return;
1374#endif 1644#endif
1375 if (ats->ats_task != GNUNET_SCHEDULER_NO_TASK)
1376 GNUNET_SCHEDULER_cancel(ats->ats_task);
1377 ats->ats_task = GNUNET_SCHEDULER_NO_TASK;
1378 1645
1379#if HAVE_LIBGLPK 1646#if DEBUG_ATS
1380 ats_delete_problem (ats); 1647 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "ATS shutdown\n");
1381 glp_free_env();
1382#endif 1648#endif
1383 GNUNET_free (ats); 1649 if (ats->ats_task != GNUNET_SCHEDULER_NO_TASK)
1650 GNUNET_SCHEDULER_cancel(ats->ats_task);
1651 ats->ats_task = GNUNET_SCHEDULER_NO_TASK;
1652 ats_delete_problem (ats);
1653 _lp_free_env();
1654
1655 GNUNET_free (ats);
1384} 1656}
1385 1657
1386void ats_update_problem_qm (struct ATS_info * ats) 1658void ats_update_problem_qm (struct ATS_Handle * ats)
1387{ 1659{
1388 int array_index; 1660#if !HAVE_LIBGLPK
1389 int row_index; 1661 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS not active\n");
1390 int c, c2; 1662 return;
1391 int c_q_metrics = available_quality_metrics; 1663#endif
1664
1665 int array_index;
1666 int row_index;
1667 int c, c2;
1668 int c_q_metrics = available_quality_metrics;
1392 1669
1393 int *ja = GNUNET_malloc ((1 + ats->stat.c_mechs*2 + 3 + available_quality_metrics) * sizeof (int)); 1670 int *ja = GNUNET_malloc ((1 + ats->stat.c_mechs*2 + 3 +
1394 double *ar = GNUNET_malloc ((1 + ats->stat.c_mechs*2 + 3 + available_quality_metrics) * sizeof (double)); 1671 available_quality_metrics) * sizeof (int));
1672 double *ar = GNUNET_malloc ((1 + ats->stat.c_mechs*2 + 3 +
1673 available_quality_metrics) * sizeof (double));
1395#if DEBUG_ATS 1674#if DEBUG_ATS
1396 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating problem quality metrics\n"); 1675 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating problem quality metrics\n");
1397#endif 1676#endif
1398 row_index = ats->stat.begin_qm; 1677 row_index = ats->stat.begin_qm;
1399 1678
1400 for (c=1; c <= c_q_metrics; c++) 1679 for (c=1; c <= c_q_metrics; c++)
1401 { 1680 {
1402 array_index = 1; 1681 array_index = 1;
1403 double value = 1; 1682 double value = 1;
1404#if VERBOSE_ATS
1405 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index);
1406#endif
1407
1408 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 0.0, 0.0);
1409 for (c2=1; c2<=ats->stat.c_mechs; c2++)
1410 {
1411 ja[array_index] = c2;
1412
1413 GNUNET_assert (ats->mechanisms[c2].addr != NULL);
1414 GNUNET_assert (ats->mechanisms[c2].peer != NULL);
1415
1416 if (qm[c-1].atis_index == GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY)
1417 {
1418 double v0 = 0, v1 = 0, v2 = 0;
1419
1420 v0 = ats->mechanisms[c2].addr->quality[c-1].values[0];
1421 if (v1 < 1) v0 = 0.1;
1422 v1 = ats->mechanisms[c2].addr->quality[c-1].values[1];
1423 if (v1 < 1) v0 = 0.1;
1424 v2 = ats->mechanisms[c2].addr->quality[c-1].values[2];
1425 if (v1 < 1) v0 = 0.1;
1426 value = 100.0 / ((v0 + 2 * v1 + 3 * v2) / 6.0);
1427 //value = 1;
1428 }
1429 if (qm[c-1].atis_index == GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE)
1430 {
1431 double v0 = 0, v1 = 0, v2 = 0;
1432 v0 = ats->mechanisms[c2].addr->quality[c-1].values[0];
1433 if (v0 < 1) v0 = 1;
1434 v1 = ats->mechanisms[c2].addr->quality[c-1].values[1];
1435 if (v1 < 1) v1 = 1;
1436 v2 = ats->mechanisms[c2].addr->quality[c-1].values[2];
1437 if (v2 < 1) v2 = 1;
1438 value = (v0 + 2 * v1 + 3 * v2) / 6.0;
1439 if (value >= 1)
1440 value = (double) 10 / value;
1441 else
1442 value = 10;
1443 }
1444 ar[array_index] = (ats->mechanisms[c2].peer->f) * value;
1445#if VERBOSE_ATS 1683#if VERBOSE_ATS
1446 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: %s [%i,%i]=%f \n",array_index, qm[c-1].name, row_index, ja[array_index], ar[array_index]); 1684 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] \n",row_index);
1447#endif 1685#endif
1448 array_index++; 1686 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 0.0, 0.0);
1449 } 1687 for (c2=1; c2<=ats->stat.c_mechs; c2++)
1450 ja[array_index] = ats->stat.col_qm + c - 1; 1688 {
1451 ar[array_index] = -1; 1689 ja[array_index] = c2;
1690 GNUNET_assert (ats->mechanisms[c2].addr != NULL);
1691 GNUNET_assert (ats->mechanisms[c2].peer != NULL);
1452 1692
1693 if (qm[c-1].atis_index == GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY)
1694 {
1695 double v0 = 0, v1 = 0, v2 = 0;
1696
1697 v0 = ats->mechanisms[c2].addr->quality[c-1].values[0];
1698 if (v1 < 1) v0 = 0.1;
1699 v1 = ats->mechanisms[c2].addr->quality[c-1].values[1];
1700 if (v1 < 1) v0 = 0.1;
1701 v2 = ats->mechanisms[c2].addr->quality[c-1].values[2];
1702 if (v1 < 1) v0 = 0.1;
1703 value = 100.0 / ((v0 + 2 * v1 + 3 * v2) / 6.0);
1704 //value = 1;
1705 }
1706 if (qm[c-1].atis_index == GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE)
1707 {
1708 double v0 = 0, v1 = 0, v2 = 0;
1709 v0 = ats->mechanisms[c2].addr->quality[c-1].values[0];
1710 if (v0 < 1) v0 = 1;
1711 v1 = ats->mechanisms[c2].addr->quality[c-1].values[1];
1712 if (v1 < 1) v1 = 1;
1713 v2 = ats->mechanisms[c2].addr->quality[c-1].values[2];
1714 if (v2 < 1) v2 = 1;
1715 value = (v0 + 2 * v1 + 3 * v2) / 6.0;
1716 if (value >= 1)
1717 value = (double) 10 / value;
1718 else
1719 value = 10;
1720 }
1721 ar[array_index] = (ats->mechanisms[c2].peer->f) * value;
1453#if VERBOSE_ATS 1722#if VERBOSE_ATS
1454 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, row_index, ja[array_index], ar[array_index]); 1723 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: %s [%i,%i]=%f \n",
1724 array_index,
1725 qm[c-1].name,
1726 row_index,
1727 ja[array_index],
1728 ar[array_index]);
1455#endif 1729#endif
1456 _lp_set_mat_row (ats->prob, row_index, array_index, ja, ar); 1730 array_index++;
1457
1458 array_index = 1;
1459 row_index++;
1460 } 1731 }
1732 ja[array_index] = ats->stat.col_qm + c - 1;
1733 ar[array_index] = -1;
1461 1734
1462 GNUNET_free_non_null (ja); 1735#if VERBOSE_ATS
1463 GNUNET_free_non_null (ar); 1736 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
1737 array_index,
1738 row_index,
1739 ja[array_index],
1740 ar[array_index]);
1741#endif
1742 _lp_set_mat_row (ats->prob, row_index, array_index, ja, ar);
1743 array_index = 1;
1744 row_index++;
1745 }
1746 GNUNET_free_non_null (ja);
1747 GNUNET_free_non_null (ar);
1464} 1748}
1465 1749
1466 1750
1467void 1751void
1468ats_calculate_bandwidth_distribution (struct ATS_info * ats, struct GNUNET_STATISTICS_Handle *stats, struct NeighbourList *neighbours) 1752ats_calculate_bandwidth_distribution (struct ATS_Handle * ats,
1753 struct GNUNET_STATISTICS_Handle *stats,
1754 struct NeighbourList *neighbours)
1469{ 1755{
1470#if HAVE_LIBGLPK 1756#if !HAVE_LIBGLPK
1757 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS not active\n");
1758 return;
1759#endif
1471 1760
1472 struct GNUNET_TIME_Absolute start; 1761 struct GNUNET_TIME_Absolute start;
1473 struct GNUNET_TIME_Relative creation; 1762 struct GNUNET_TIME_Relative creation;
1474 struct GNUNET_TIME_Relative solving; 1763 struct GNUNET_TIME_Relative solving;
1475 char *text = "unmodified"; 1764 char *text = "unmodified";
1476 1765
1477 struct GNUNET_TIME_Relative delta = GNUNET_TIME_absolute_get_difference (ats->last, GNUNET_TIME_absolute_get()); 1766 struct GNUNET_TIME_Relative delta = GNUNET_TIME_absolute_get_difference (ats->last,
1478 if (delta.rel_value < ats->min_delta.rel_value) 1767 GNUNET_TIME_absolute_get());
1479 { 1768 if (delta.rel_value < ats->min_delta.rel_value)
1769 {
1480#if DEBUG_ATS 1770#if DEBUG_ATS
1481 GNUNET_log (GNUNET_ERROR_TYPE_BULK, "Minimum time between cycles not reached\n"); 1771 GNUNET_log (GNUNET_ERROR_TYPE_BULK,
1772 "Minimum time between cycles not reached\n");
1482#endif 1773#endif
1483 return; 1774 return;
1484 } 1775 }
1485 1776
1486#if FIXME_WACHS 1777#if FIXME_WACHS
1487 int dur; 1778 int dur;
1488 if (INT_MAX < ats->max_exec_duration.rel_value) 1779 if (INT_MAX < ats->max_exec_duration.rel_value)
1489 dur = INT_MAX; 1780 dur = INT_MAX;
1490 else 1781 else
1491 dur = (int) ats->max_exec_duration.rel_value; 1782 dur = (int) ats->max_exec_duration.rel_value;
1492#endif 1783#endif
1493 1784
1494 ats->stat.simplex_rerun_required = GNUNET_NO; 1785 ats->stat.simplex_rerun_required = GNUNET_NO;
1495 start = GNUNET_TIME_absolute_get(); 1786 start = GNUNET_TIME_absolute_get();
1496 if ((ats->stat.recreate_problem == GNUNET_YES) || (ats->prob==NULL) || (ats->stat.valid == GNUNET_NO)) 1787 if ((ats->stat.recreate_problem == GNUNET_YES) ||
1497 { 1788 (ats->prob==NULL) ||
1498 text = "new"; 1789 (ats->stat.valid == GNUNET_NO))
1499 ats->stat.recreate_problem = GNUNET_YES; 1790 {
1500 ats_delete_problem (ats); 1791 text = "new";
1501 ats_create_problem (ats, neighbours, ats->D, ats->U, ats->R, ats->v_b_min, ats->v_n_min, &ats->stat); 1792 ats->stat.recreate_problem = GNUNET_YES;
1793 ats_delete_problem (ats);
1794 ats_create_problem (ats,
1795 neighbours,
1796 ats->D,
1797 ats->U,
1798 ats->R,
1799 ats->v_b_min,
1800 ats->v_n_min,
1801 &ats->stat);
1502#if DEBUG_ATS 1802#if DEBUG_ATS
1503 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Peers/Addresses were modified... new problem: %i peer, %i mechs\n", ats->stat.c_peers, ats->stat.c_mechs); 1803 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1804 "Peers/Addresses were modified... new problem: %i peer, %i mechs\n",
1805 ats->stat.c_peers,
1806 ats->stat.c_mechs);
1504#endif 1807#endif
1505 } 1808 }
1506
1507 else if ((ats->stat.recreate_problem == GNUNET_NO) && (ats->stat.modified_resources == GNUNET_YES) && (ats->stat.valid == GNUNET_YES))
1508 {
1509 text = "modified resources";
1510 ats_update_problem_cr (ats);
1511 }
1512 else if ((ats->stat.recreate_problem == GNUNET_NO) && (ats->stat.modified_quality == GNUNET_YES) && (ats->stat.valid == GNUNET_YES))
1513 {
1514 text = "modified quality";
1515 ats_update_problem_qm (ats);
1516 //ats_update_problem_qm_TEST ();
1517 1809
1518 } 1810 else if ((ats->stat.recreate_problem == GNUNET_NO) &&
1811 (ats->stat.modified_resources == GNUNET_YES) &&
1812 (ats->stat.valid == GNUNET_YES))
1813 {
1814 text = "modified resources";
1815 ats_update_problem_cr (ats);
1816 }
1817 else if ((ats->stat.recreate_problem == GNUNET_NO) &&
1818 (ats->stat.modified_quality == GNUNET_YES) &&
1819 (ats->stat.valid == GNUNET_YES))
1820 {
1821 text = "modified quality";
1822 ats_update_problem_qm (ats);
1823 //ats_update_problem_qm_TEST ();
1824 }
1519#if DEBUG_ATS 1825#if DEBUG_ATS
1520 else GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Problem is unmodified\n"); 1826 else GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Problem is unmodified\n");
1521#endif 1827#endif
1522 1828
1523 creation = GNUNET_TIME_absolute_get_difference(start,GNUNET_TIME_absolute_get()); 1829 creation = GNUNET_TIME_absolute_get_difference(start,GNUNET_TIME_absolute_get());
1524 start = GNUNET_TIME_absolute_get(); 1830 start = GNUNET_TIME_absolute_get();
1525 1831
1526 ats->stat.solution = GLP_UNDEF; 1832 ats->stat.solution = GLP_UNDEF;
1527 if (ats->stat.valid == GNUNET_YES) 1833 if (ats->stat.valid == GNUNET_YES)
1528 { 1834 {
1529 ats_solve_problem(ats, ats->max_iterations, ats->max_exec_duration.rel_value, ats->stat.c_peers, ats->stat.c_mechs, &ats->stat); 1835 ats_solve_problem(ats,
1530 } 1836 ats->max_iterations,
1531 solving = GNUNET_TIME_absolute_get_difference(start,GNUNET_TIME_absolute_get()); 1837 ats->max_exec_duration.rel_value,
1838 ats->stat.c_peers,
1839 ats->stat.c_mechs,
1840 &ats->stat);
1841 }
1842 solving = GNUNET_TIME_absolute_get_difference(start,GNUNET_TIME_absolute_get());
1532 1843
1533 if (ats->stat.valid == GNUNET_YES) 1844 if (ats->stat.valid == GNUNET_YES)
1534 { 1845 {
1535 int msg_type = GNUNET_ERROR_TYPE_DEBUG; 1846 int msg_type = GNUNET_ERROR_TYPE_DEBUG;
1536#if DEBUG_ATS 1847#if DEBUG_ATS
1537 msg_type = GNUNET_ERROR_TYPE_ERROR; 1848 msg_type = GNUNET_ERROR_TYPE_ERROR;
1538#endif 1849#endif
1539 GNUNET_log (msg_type, "MLP %s: creation time: %llu, execution time: %llu, %i mechanisms, simplex rerun: %s, solution %s\n", 1850 GNUNET_log (msg_type,
1540 text, creation.rel_value, solving.rel_value, 1851 "MLP %s: creation time: %llu, execution time: %llu, %i mechanisms, simplex rerun: %s, solution %s\n",
1541 ats->stat.c_mechs, 1852 text,
1542 (ats->stat.simplex_rerun_required == GNUNET_NO) ? "NO" : "YES", (ats->stat.solution == 5) ? "OPTIMAL" : "INVALID"); 1853 creation.rel_value,
1543 ats->successful_executions ++; 1854 solving.rel_value,
1544 GNUNET_STATISTICS_set (stats, "# ATS successful executions", ats->successful_executions, GNUNET_NO); 1855 ats->stat.c_mechs,
1545 1856 (ats->stat.simplex_rerun_required == GNUNET_NO) ? "NO" : "YES",
1546 if ((ats->stat.recreate_problem == GNUNET_YES) || (ats->prob==NULL)) 1857 (ats->stat.solution == 5) ? "OPTIMAL" : "INVALID");
1547 GNUNET_STATISTICS_set (stats, "ATS state",ATS_NEW, GNUNET_NO); 1858 ats->successful_executions ++;
1548 else if ((ats->stat.modified_resources == GNUNET_YES) && 1859 GNUNET_STATISTICS_set (stats, "# ATS successful executions",
1549 (ats->stat.modified_quality == GNUNET_NO)) 1860 ats->successful_executions,
1550 GNUNET_STATISTICS_set (stats, "ATS state", ATS_C_UPDATED, GNUNET_NO); 1861 GNUNET_NO);
1551 else if ((ats->stat.modified_resources == GNUNET_NO) && 1862
1552 (ats->stat.modified_quality == GNUNET_YES) && 1863 if ((ats->stat.recreate_problem == GNUNET_YES) || (ats->prob==NULL))
1553 (ats->stat.simplex_rerun_required == GNUNET_NO)) 1864 GNUNET_STATISTICS_set (stats, "ATS state",ATS_NEW, GNUNET_NO);
1554 GNUNET_STATISTICS_set (stats, "ATS state", ATS_Q_UPDATED, GNUNET_NO); 1865 else if ((ats->stat.modified_resources == GNUNET_YES) &&
1555 else if ((ats->stat.modified_resources == GNUNET_YES) && 1866 (ats->stat.modified_quality == GNUNET_NO))
1556 (ats->stat.modified_quality == GNUNET_YES) && 1867 GNUNET_STATISTICS_set (stats, "ATS state", ATS_C_UPDATED, GNUNET_NO);
1557 (ats->stat.simplex_rerun_required == GNUNET_NO)) 1868 else if ((ats->stat.modified_resources == GNUNET_NO) &&
1558 GNUNET_STATISTICS_set (stats, "ATS state", ATS_QC_UPDATED, GNUNET_NO); 1869 (ats->stat.modified_quality == GNUNET_YES) &&
1559 else if (ats->stat.simplex_rerun_required == GNUNET_NO) 1870 (ats->stat.simplex_rerun_required == GNUNET_NO))
1560 GNUNET_STATISTICS_set (stats, "ATS state", ATS_UNMODIFIED, GNUNET_NO); 1871 GNUNET_STATISTICS_set (stats, "ATS state", ATS_Q_UPDATED, GNUNET_NO);
1872 else if ((ats->stat.modified_resources == GNUNET_YES) &&
1873 (ats->stat.modified_quality == GNUNET_YES) &&
1874 (ats->stat.simplex_rerun_required == GNUNET_NO))
1875 GNUNET_STATISTICS_set (stats, "ATS state", ATS_QC_UPDATED, GNUNET_NO);
1876 else if (ats->stat.simplex_rerun_required == GNUNET_NO)
1877 GNUNET_STATISTICS_set (stats, "ATS state", ATS_UNMODIFIED, GNUNET_NO);
1878 }
1879 else
1880 {
1881 if (ats->stat.c_peers != 0)
1882 {
1883 ats->invalid_executions ++;
1884 GNUNET_STATISTICS_set (stats, "# ATS invalid executions",
1885 ats->invalid_executions, GNUNET_NO);
1886 }
1887 else
1888 {
1889 GNUNET_STATISTICS_set (stats, "# ATS successful executions",
1890 ats->successful_executions, GNUNET_NO);
1891 }
1892 }
1893
1894 GNUNET_STATISTICS_set (stats,
1895 "ATS duration", solving.rel_value + creation.rel_value, GNUNET_NO);
1896 GNUNET_STATISTICS_set (stats,
1897 "ATS mechanisms", ats->stat.c_mechs, GNUNET_NO);
1898 GNUNET_STATISTICS_set (stats,
1899 "ATS peers", ats->stat.c_peers, GNUNET_NO);
1900 GNUNET_STATISTICS_set (stats,
1901 "ATS solution", ats->stat.solution, GNUNET_NO);
1902 GNUNET_STATISTICS_set (stats,
1903 "ATS timestamp", start.abs_value, GNUNET_NO);
1904
1905 if ((ats->save_mlp == GNUNET_YES) &&
1906 (ats->stat.c_mechs >= ats->dump_min_peers) &&
1907 (ats->stat.c_mechs >= ats->dump_min_addr))
1908 {
1909 char * filename;
1910 if (ats->dump_overwrite == GNUNET_NO)
1911 {
1912 GNUNET_asprintf (&filename, "ats_mlp_p%i_m%i_%s_%llu.mlp",
1913 ats->stat.c_peers,
1914 ats->stat.c_mechs,
1915 text,
1916 GNUNET_TIME_absolute_get().abs_value);
1917 _lp_write_lp ((void *) ats->prob, NULL, filename);
1561 } 1918 }
1562 else 1919 else
1563 { 1920 {
1564 if (ats->stat.c_peers != 0) 1921 GNUNET_asprintf (&filename, "ats_mlp_p%i_m%i.mlp",
1565 { 1922 ats->stat.c_peers, ats->stat.c_mechs );
1566 ats->invalid_executions ++; 1923 _lp_write_lp ((void *) ats->prob, NULL, filename);
1567 GNUNET_STATISTICS_set (stats, "# ATS invalid executions", ats->invalid_executions, GNUNET_NO);
1568 }
1569 else
1570 {
1571 GNUNET_STATISTICS_set (stats, "# ATS successful executions", ats->successful_executions, GNUNET_NO);
1572 }
1573 } 1924 }
1574 1925 GNUNET_free (filename);
1575 GNUNET_STATISTICS_set (stats, "ATS duration", solving.rel_value + creation.rel_value, GNUNET_NO); 1926 }
1576 GNUNET_STATISTICS_set (stats, "ATS mechanisms", ats->stat.c_mechs, GNUNET_NO); 1927 if ((ats->save_solution == GNUNET_YES) &&
1577 GNUNET_STATISTICS_set (stats, "ATS peers", ats->stat.c_peers, GNUNET_NO); 1928 (ats->stat.c_mechs >= ats->dump_min_peers) &&
1578 GNUNET_STATISTICS_set (stats, "ATS solution", ats->stat.solution, GNUNET_NO); 1929 (ats->stat.c_mechs >= ats->dump_min_addr))
1579 GNUNET_STATISTICS_set (stats, "ATS timestamp", start.abs_value, GNUNET_NO); 1930 {
1580 1931 char * filename;
1581 if ((ats->save_mlp == GNUNET_YES) && (ats->stat.c_mechs >= ats->dump_min_peers) && (ats->stat.c_mechs >= ats->dump_min_addr)) 1932 if (ats->dump_overwrite == GNUNET_NO)
1582 { 1933 {
1583 char * filename; 1934 GNUNET_asprintf (&filename, "ats_mlp_p%i_m%i_%s_%llu.sol",
1584 if (ats->dump_overwrite == GNUNET_NO) 1935 ats->stat.c_peers,
1585 { 1936 ats->stat.c_mechs,
1586 GNUNET_asprintf (&filename, "ats_mlp_p%i_m%i_%s_%llu.mlp", 1937 text,
1587 ats->stat.c_peers, ats->stat.c_mechs, text, GNUNET_TIME_absolute_get().abs_value); 1938 GNUNET_TIME_absolute_get().abs_value);
1588 _lp_write_lp (ats->prob, NULL, filename); 1939 _lp_print_sol (ats->prob, filename);
1589 }
1590 else
1591 {
1592 GNUNET_asprintf (&filename, "ats_mlp_p%i_m%i.mlp",
1593 ats->stat.c_peers, ats->stat.c_mechs );
1594 _lp_write_lp (ats->prob, NULL, filename);
1595 }
1596 GNUNET_free (filename);
1597 } 1940 }
1598 if ((ats->save_solution == GNUNET_YES) && (ats->stat.c_mechs >= ats->dump_min_peers) && (ats->stat.c_mechs >= ats->dump_min_addr)) 1941 else
1599 { 1942 {
1600 char * filename; 1943 GNUNET_asprintf (&filename, "ats_mlp_p%i_m%i.sol",
1601 if (ats->dump_overwrite == GNUNET_NO) 1944 ats->stat.c_peers, ats->stat.c_mechs);
1602 { 1945 _lp_print_sol (ats->prob, filename);
1603 GNUNET_asprintf (&filename, "ats_mlp_p%i_m%i_%s_%llu.sol",
1604 ats->stat.c_peers, ats->stat.c_mechs, text, GNUNET_TIME_absolute_get().abs_value);
1605 glp_print_sol (ats->prob, filename);
1606 }
1607 else
1608 {
1609 GNUNET_asprintf (&filename, "ats_mlp_p%i_m%i.sol",
1610 ats->stat.c_peers, ats->stat.c_mechs);
1611 glp_print_sol (ats->prob, filename);
1612 }
1613 GNUNET_free (filename);
1614 } 1946 }
1615 1947 GNUNET_free (filename);
1616 ats->last = GNUNET_TIME_absolute_get(); 1948 }
1617 ats->stat.recreate_problem = GNUNET_NO; 1949 ats->last = GNUNET_TIME_absolute_get();
1618 ats->stat.modified_resources = GNUNET_NO; 1950 ats->stat.recreate_problem = GNUNET_NO;
1619 ats->stat.modified_quality = GNUNET_NO; 1951 ats->stat.modified_resources = GNUNET_NO;
1620#endif 1952 ats->stat.modified_quality = GNUNET_NO;
1621} 1953}
1622 1954
1955/**
1956 * Evaluate the result of the last simplex or mlp solving
1957 * @param result return value returned by the solver
1958 * @param solution solution state
1959 * @param problem mlp or lp
1960 * @return GNUNET_NO if solution is invalid, GNUNET_YES if solution is
1961 * valid
1962 */
1963
1623int ats_evaluate_results (int result, int solution, char * problem) 1964int ats_evaluate_results (int result, int solution, char * problem)
1624{ 1965{
1625 int cont = GNUNET_NO; 1966#if !HAVE_LIBGLPK
1967 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS not active\n");
1968 return GNUNET_NO;
1969#endif
1970
1971 int cont = GNUNET_NO;
1626#if DEBUG_ATS || VERBOSE_ATS 1972#if DEBUG_ATS || VERBOSE_ATS
1627 int error_kind = GNUNET_ERROR_TYPE_DEBUG; 1973 int error_kind = GNUNET_ERROR_TYPE_DEBUG;
1628#endif 1974#endif
1629#if VERBOSE_ATS 1975#if VERBOSE_ATS
1630 error_kind = GNUNET_ERROR_TYPE_ERROR; 1976 error_kind = GNUNET_ERROR_TYPE_ERROR;
1631#endif 1977#endif
1632 1978 switch (result) {
1633 switch (result) { 1979 case GNUNET_SYSERR : /* GNUNET problem, not GLPK related */
1634 case GNUNET_SYSERR : /* GNUNET problem, not GLPK related */
1635#if DEBUG_ATS || VERBOSE_ATS 1980#if DEBUG_ATS || VERBOSE_ATS
1636 GNUNET_log (error_kind, "%s , GLPK solving not executed\n", problem); 1981 GNUNET_log (error_kind,
1982 "%s, GLPK solving not executed\n", problem);
1637#endif 1983#endif
1638 break; 1984 break;
1639 case GLP_ESTOP : /* search terminated by application */ 1985 case GLP_ESTOP : /* search terminated by application */
1640#if DEBUG_ATS || VERBOSE_ATS 1986#if DEBUG_ATS || VERBOSE_ATS
1641 GNUNET_log (error_kind, "%s , Search terminated by application\n", problem); 1987 GNUNET_log (error_kind,
1988 "%s , Search terminated by application\n", problem);
1642#endif 1989#endif
1643 break; 1990 break;
1644 case GLP_EITLIM : /* iteration limit exceeded */ 1991 case GLP_EITLIM : /* iteration limit exceeded */
1645#if DEBUG_ATS || VERBOSE_ATS 1992#if DEBUG_ATS || VERBOSE_ATS
1646 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s Iteration limit exceeded\n", problem); 1993 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1994 "%s Iteration limit exceeded\n", problem);
1647#endif 1995#endif
1648 break; 1996 break;
1649 case GLP_ETMLIM : /* time limit exceeded */ 1997 case GLP_ETMLIM : /* time limit exceeded */
1650#if DEBUG_ATS || VERBOSE_ATS 1998#if DEBUG_ATS || VERBOSE_ATS
1651 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%s Time limit exceeded\n", problem); 1999 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2000 "%s Time limit exceeded\n", problem);
1652#endif 2001#endif
1653 break; 2002 break;
1654 case GLP_ENOPFS : /* no primal feasible solution */ 2003 case GLP_ENOPFS : /* no primal feasible solution */
1655 case GLP_ENODFS : /* no dual feasible solution */ 2004 case GLP_ENODFS : /* no dual feasible solution */
1656#if DEBUG_ATS || VERBOSE_ATS 2005#if DEBUG_ATS || VERBOSE_ATS
1657 GNUNET_log (error_kind, "%s No feasible solution\n", problem); 2006 GNUNET_log (error_kind,
2007 "%s No feasible solution\n", problem);
1658#endif 2008#endif
1659 break; 2009 break;
1660 2010 case GLP_EBADB : /* invalid basis */
1661 case GLP_EBADB : /* invalid basis */ 2011 case GLP_ESING : /* singular matrix */
1662 case GLP_ESING : /* singular matrix */ 2012 case GLP_ECOND : /* ill-conditioned matrix */
1663 case GLP_ECOND : /* ill-conditioned matrix */ 2013 case GLP_EBOUND : /* invalid bounds */
1664 case GLP_EBOUND : /* invalid bounds */ 2014 case GLP_EFAIL : /* solver failed */
1665 case GLP_EFAIL : /* solver failed */ 2015 case GLP_EOBJLL : /* objective lower limit reached */
1666 case GLP_EOBJLL : /* objective lower limit reached */ 2016 case GLP_EOBJUL : /* objective upper limit reached */
1667 case GLP_EOBJUL : /* objective upper limit reached */ 2017 case GLP_EROOT : /* root LP optimum not provided */
1668 case GLP_EROOT : /* root LP optimum not provided */
1669#if DEBUG_ATS || VERBOSE_ATS 2018#if DEBUG_ATS || VERBOSE_ATS
1670 GNUNET_log (error_kind, "%s Invalid Input data: %i\n", problem, result); 2019 GNUNET_log (error_kind,
2020 "%s Invalid Input data: %i\n",
2021 problem, result);
1671#endif 2022#endif
1672 break; 2023 break;
1673 2024 case 0:
1674 case 0:
1675#if DEBUG_ATS || VERBOSE_ATS 2025#if DEBUG_ATS || VERBOSE_ATS
1676 GNUNET_log (error_kind, "%s Problem has been solved\n", problem); 2026 GNUNET_log (error_kind,
2027 "%s Problem has been solved\n", problem);
1677#endif 2028#endif
1678 break; 2029 break;
1679 } 2030 }
1680 2031
1681 switch (solution) { 2032 switch (solution) {
1682 case GLP_UNDEF: 2033 case GLP_UNDEF:
1683#if DEBUG_ATS || VERBOSE_ATS 2034#if DEBUG_ATS || VERBOSE_ATS
1684 GNUNET_log (error_kind, "%s solution is undefined\n", problem); 2035 GNUNET_log (error_kind,
2036 "%s solution is undefined\n", problem);
1685#endif 2037#endif
1686 break; 2038 break;
1687 case GLP_OPT: 2039 case GLP_OPT:
1688#if DEBUG_ATS || VERBOSE_ATS 2040#if DEBUG_ATS || VERBOSE_ATS
1689 GNUNET_log (error_kind, "%s solution is optimal\n", problem); 2041 GNUNET_log (error_kind,
2042 "%s solution is optimal\n", problem);
1690#endif 2043#endif
1691 cont=GNUNET_YES; 2044 cont=GNUNET_YES;
1692 break; 2045 break;
1693 case GLP_FEAS: 2046 case GLP_FEAS:
1694#if DEBUG_ATS || VERBOSE_ATS 2047#if DEBUG_ATS || VERBOSE_ATS
1695 GNUNET_log (error_kind, "%s solution is %s feasible, however, its optimality (or non-optimality) has not been proven, \n", problem, (0==strcmp(problem,"LP")?"":"integer")); 2048 GNUNET_log (error_kind,
2049 "%s solution is %s feasible, however, its optimality (or non-optimality) has not been proven\n",
2050 problem, (0==strcmp(problem,"LP")?"":"integer"));
1696#endif 2051#endif
1697 cont=GNUNET_YES; 2052 cont=GNUNET_YES;
1698 break; 2053 break;
1699 case GLP_NOFEAS: 2054 case GLP_NOFEAS:
1700#if DEBUG_ATS || VERBOSE_ATS 2055#if DEBUG_ATS || VERBOSE_ATS
1701 GNUNET_log (error_kind, "%s problem has no %sfeasible solution\n", problem, (0==strcmp(problem,"LP")?"":"integer ")); 2056 GNUNET_log (error_kind, "%s problem has no %sfeasible solution\n",
2057 problem, (0==strcmp(problem,"LP")?"":"integer "));
1702#endif 2058#endif
1703 break; 2059 break;
1704 case GLP_INFEAS: 2060 case GLP_INFEAS:
1705#if DEBUG_ATS || VERBOSE_ATS 2061#if DEBUG_ATS || VERBOSE_ATS
1706 GNUNET_log (error_kind, "%s problem is infeasible \n", problem); 2062 GNUNET_log (error_kind, "%s problem is infeasible \n", problem);
1707#endif 2063#endif
1708 break; 2064 break;
1709 case GLP_UNBND: 2065 case GLP_UNBND:
1710#if DEBUG_ATS || VERBOSE_ATS 2066#if DEBUG_ATS || VERBOSE_ATS
1711 GNUNET_log (error_kind, "%s problem is unbounded \n", problem); 2067 GNUNET_log (error_kind, "%s problem is unbounded \n", problem);
1712#endif 2068#endif
1713 default: 2069 default:
1714 break; 2070 break;
1715 } 2071 }
1716return cont; 2072return cont;
1717} 2073}
1718 2074
1719void ats_update_problem_cr (struct ATS_info * ats) 2075void ats_update_problem_cr (struct ATS_Handle * ats)
1720{ 2076{
2077#if !HAVE_LIBGLPK
2078 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS not active\n");
2079 return;
2080#endif
1721 2081
1722 int array_index; 2082 int array_index;
1723 int row_index; 2083 int row_index;
1724 int c, c2; 2084 int c, c2;
1725 double ct_max, ct_min; 2085 double ct_max, ct_min;
1726 2086
1727 int *ja = GNUNET_malloc ((1 + ats->stat.c_mechs*2 + 3 + available_quality_metrics) * sizeof (int)); 2087 int *ja = GNUNET_malloc ((1 + ats->stat.c_mechs*2 + 3 +
1728 double *ar = GNUNET_malloc ((1 + ats->stat.c_mechs*2 + 3 + available_quality_metrics) * sizeof (double)); 2088 available_quality_metrics) * sizeof (int));
2089 double *ar = GNUNET_malloc ((1 + ats->stat.c_mechs*2 + 3 +
2090 available_quality_metrics) * sizeof (double));
1729 2091
1730 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating problem quality metrics\n"); 2092 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating problem quality metrics\n");
1731 row_index = ats->stat.begin_cr; 2093 row_index = ats->stat.begin_cr;
1732 array_index = 1; 2094 array_index = 1;
1733 2095
1734 for (c=0; c<available_ressources; c++) 2096 for (c=0; c<available_ressources; c++)
1735 { 2097 {
1736 ct_max = ressources[c].c_max; 2098 ct_max = ressources[c].c_max;
1737 ct_min = ressources[c].c_min; 2099 ct_min = ressources[c].c_min;
1738#if VERBOSE_ATS 2100#if VERBOSE_ATS
1739 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] %f..%f\n",row_index, ct_min, ct_max); 2101 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "bounds [row]=[%i] %f..%f\n",
2102 row_index,
2103 ct_min,
2104 ct_max);
1740#endif 2105#endif
1741 _lp_set_row_bnds(ats->prob, row_index, GLP_DB, ct_min, ct_max); 2106 _lp_set_row_bnds(ats->prob, row_index, GLP_DB, ct_min, ct_max);
1742 2107 for (c2=1; c2<=ats->stat.c_mechs; c2++)
1743 for (c2=1; c2<=ats->stat.c_mechs; c2++) 2108 {
1744 { 2109 double value = 0;
1745 double value = 0; 2110 GNUNET_assert (ats->mechanisms[c2].addr != NULL);
1746 2111 GNUNET_assert (ats->mechanisms[c2].peer != NULL);
1747 GNUNET_assert (ats->mechanisms[c2].addr != NULL);
1748 GNUNET_assert (ats->mechanisms[c2].peer != NULL);
1749 2112
1750 ja[array_index] = c2; 2113 ja[array_index] = c2;
1751 value = ats->mechanisms[c2].addr->ressources[c].c; 2114 value = ats->mechanisms[c2].addr->ressources[c].c;
1752 ar[array_index] = value; 2115 ar[array_index] = value;
1753#if VERBOSE_ATS 2116#if VERBOSE_ATS
1754 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",array_index, row_index, ja[array_index], ar[array_index]); 2117 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: [%i,%i]=%f \n",
2118 array_index,
2119 row_index,
2120 ja[array_index],
2121 ar[array_index]);
1755#endif 2122#endif
1756 array_index++; 2123 array_index++;
1757 } 2124 }
1758 _lp_set_mat_row (ats->prob, row_index, array_index, ja, ar); 2125 _lp_set_mat_row (ats->prob, row_index, array_index, ja, ar);
1759 2126 row_index ++;
1760 row_index ++; 2127 }
1761 } 2128 GNUNET_free_non_null (ja);
1762 2129 GNUNET_free_non_null (ar);
1763
1764 GNUNET_free_non_null (ja);
1765 GNUNET_free_non_null (ar);
1766} 2130}
1767 2131
1768#if 0 2132#if 0
1769static void ats_update_problem_qm_TEST () 2133static void ats_update_problem_qm_TEST ()
1770{ 2134{
1771 int row_index; 2135 int row_index;
1772 int c, c2; 2136 int c
1773 2137 int c2;
1774 int old_ja[ats->stat.c_mechs + 2]; 2138 int c_old;
1775 double old_ar[ats->stat.c_mechs + 2]; 2139 int changed = 0;
1776 int c_old; 2140
1777 int changed = 0; 2141 int old_ja[ats->stat.c_mechs + 2];
1778 2142 double old_ar[ats->stat.c_mechs + 2];
1779 int *ja = GNUNET_malloc ((1 + ats->stat.c_mechs*2 + 3 + available_quality_metrics) * sizeof (int)); 2143
1780 double *ar = GNUNET_malloc ((1 + ats->stat.c_mechs*2 + 3 + available_quality_metrics) * sizeof (double)); 2144 int *ja = GNUNET_malloc ((1 + ats->stat.c_mechs*2 + 3 +
2145 available_quality_metrics) * sizeof (int));
2146 double *ar = GNUNET_malloc ((1 + ats->stat.c_mechs*2 + 3 +
2147 available_quality_metrics) * sizeof (double));
1781#if DEBUG_ATS 2148#if DEBUG_ATS
1782 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Updating problem quality metrics TEST\n"); 2149 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2150 "Updating problem quality metrics TEST\n");
1783#endif 2151#endif
1784 if (ats->stat.begin_qm >0) 2152 if (ats->stat.begin_qm >0)
1785 row_index = ats->stat.begin_qm; 2153 row_index = ats->stat.begin_qm;
1786 else 2154 else
1787 return; 2155 return;
1788 2156 for (c=0; c<available_quality_metrics; c++)
1789 2157 {
1790 for (c=0; c<available_quality_metrics; c++) 2158 c_old = _lp_get_mat_row (ats->prob, row_index, old_ja, old_ar);
2159 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 0.0, 0.0);
2160 for (c2=1; c2<=c_old; c2++)
2161 {
2162 ja[c2] = old_ja[c2];
2163 if ((changed < 3) && (c2>2) && (old_ar[c2] != -1))
1791 { 2164 {
1792 2165 ar[c2] = old_ar[c2] + 5 - changed;
1793 c_old = glp_get_mat_row (ats->prob, row_index, old_ja, old_ar); 2166 changed ++;
1794
1795 _lp_set_row_bnds(ats->prob, row_index, GLP_FX, 0.0, 0.0);
1796
1797 for (c2=1; c2<=c_old; c2++)
1798 {
1799 ja[c2] = old_ja[c2];
1800 if ((changed < 3) && (c2>2) && (old_ar[c2] != -1))
1801 {
1802 ar[c2] = old_ar[c2] + 5 - changed;
1803 changed ++;
1804 }
1805 else
1806 ar[c2] = old_ar[c2];
1807#if VERBOSE_ATS
1808 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "[index]=[%i]: old [%i,%i]=%f new [%i,%i]=%f\n",c2, row_index, old_ja[c2], old_ar[c2], row_index, ja[c2], ar[c2]);
1809#endif
1810 }
1811 _lp_set_mat_row (ats->prob, row_index, c_old, ja, ar);
1812
1813 row_index ++;
1814 } 2167 }
1815 2168 else
1816 GNUNET_free_non_null (ja); 2169 ar[c2] = old_ar[c2];
1817 GNUNET_free_non_null (ar); 2170#if VERBOSE_ATS
2171 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2172 "[index]=[%i]: old [%i,%i]=%f new [%i,%i]=%f\n",
2173 c2,
2174 row_index,
2175 old_ja[c2],
2176 old_ar[c2],
2177 row_index,
2178 ja[c2],
2179 ar[c2]);
2180#endif
2181 }
2182 _lp_set_mat_row (ats->prob, row_index, c_old, ja, ar);
2183 row_index ++;
2184 }
2185 GNUNET_free_non_null (ja);
2186 GNUNET_free_non_null (ar);
1818} 2187}
1819#endif 2188#endif
1820 2189