aboutsummaryrefslogtreecommitdiff
path: root/src/hostlist/hostlist-client.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2010-04-15 13:56:17 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2010-04-15 13:56:17 +0000
commite9ff71ca2db5c14b1587980a2914202664f40f09 (patch)
treeaa1a8b8e0d7fc6b4c2918246f1778a899414cea4 /src/hostlist/hostlist-client.c
parent906645273ff417be9d19818d75b2bb61909cb432 (diff)
downloadgnunet-e9ff71ca2db5c14b1587980a2914202664f40f09.tar.gz
gnunet-e9ff71ca2db5c14b1587980a2914202664f40f09.zip
And now for something completely different..complete implementation changed from hashmap to dll
Diffstat (limited to 'src/hostlist/hostlist-client.c')
-rw-r--r--src/hostlist/hostlist-client.c283
1 files changed, 160 insertions, 123 deletions
diff --git a/src/hostlist/hostlist-client.c b/src/hostlist/hostlist-client.c
index ec02f4545..d84d0eb82 100644
--- a/src/hostlist/hostlist-client.c
+++ b/src/hostlist/hostlist-client.c
@@ -124,12 +124,9 @@ static int learning;
124 */ 124 */
125static struct GNUNET_TIME_Absolute end_time; 125static struct GNUNET_TIME_Absolute end_time;
126 126
127/** 127struct GNUNET_Hostlist * dll_head;
128 * Hashmap of PeerIdentities to "struct GNUNET_Hostlist" 128struct GNUNET_Hostlist * dll_tail;
129 * (for fast lookup). NULL until the library 129int dll_size;
130 * is actually being used.
131 */
132static struct GNUNET_CONTAINER_MultiHashMap *hostlist_hashmap;
133 130
134/** 131/**
135 * Process downloaded bits by calling callback on each HELLO. 132 * Process downloaded bits by calling callback on each HELLO.
@@ -726,36 +723,151 @@ disconnect_handler (void *cls,
726 GNUNET_NO); 723 GNUNET_NO);
727} 724}
728 725
729struct compare_struct 726static int dll_contains ( char * uri)
730{ 727{
731 uint64_t lowest_quality; 728 struct GNUNET_Hostlist * actual = dll_head;
732 const GNUNET_HashCode * key; 729
733 struct GNUNET_Hostlist * value; 730 if (dll_size == 0)
734}; 731 return GNUNET_NO;
732 actual = dll_head;
735 733
736static int iterate_hashmap_for_replacing ( void *cls, const GNUNET_HashCode *key, void *value ) 734 while ( GNUNET_YES )
735 {
736 if ( 0 == strcmp(actual->hostlist_uri,uri) ) return GNUNET_YES;
737 if (actual == dll_tail) break;
738 actual = actual->next;
739 }
740
741 return GNUNET_NO;
742}
743
744struct GNUNET_Hostlist * dll_get ( char * uri )
737{ 745{
738 struct compare_struct * cmp = cls; 746 struct GNUNET_Hostlist * actual = dll_head;
739 747
740 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 748 if (dll_size == 0)
741 ("Now iterating over peer entry: %s\n"), GNUNET_i2s ( (const struct GNUNET_PeerIdentity *) key)); 749 return NULL;
742 if ( NULL == cmp->key ) 750 actual = dll_head;
751
752 while ( GNUNET_YES)
743 { 753 {
744 cmp->key = key; 754 if ( 0 == strcmp(actual->hostlist_uri,uri) ) return actual;
745 cmp->lowest_quality = ((struct GNUNET_Hostlist *) value)->quality; 755 if (actual == dll_tail) break;
746 cmp->value = (struct GNUNET_Hostlist *) value; 756 actual = actual->next;
747 } 757 }
748 else 758
759 return NULL;
760}
761
762struct GNUNET_Hostlist * dll_get_lowest_quality ( )
763{
764 struct GNUNET_Hostlist * actual = dll_head;
765 struct GNUNET_Hostlist * lowest = NULL;
766
767 if (dll_size == 0)
768 return lowest;
769
770 lowest = dll_tail;
771 actual = dll_head;
772
773 while ( GNUNET_YES)
749 { 774 {
750 if ( cmp->lowest_quality > ((struct GNUNET_Hostlist *) value)->quality) 775 if ( actual->quality < lowest->quality) lowest = actual;
751 { 776 if (actual == dll_tail) break;
752 cmp->lowest_quality = ((struct GNUNET_Hostlist *) value)->quality; 777 actual = actual->next;
753 cmp->key = key;
754 cmp->value = (struct GNUNET_Hostlist *) value;
755 }
756 } 778 }
757 779
758 return GNUNET_YES; 780 return lowest;
781}
782
783static int dll_insert ( struct GNUNET_Hostlist * elem)
784{
785 if (dll_size <= MAX_NUMBER_HOSTLISTS)
786 {
787 GNUNET_CONTAINER_DLL_insert(dll_head, dll_tail,elem);
788 dll_size++;
789 return GNUNET_OK;
790 }
791 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
792 "Maximum number of %u for hostlist entries reached, \n", MAX_NUMBER_HOSTLISTS );
793 return GNUNET_SYSERR;
794}
795
796static int dll_remove ( struct GNUNET_Hostlist * elem)
797{
798 if ( GNUNET_YES == dll_contains (elem->hostlist_uri))
799 {
800 GNUNET_CONTAINER_DLL_remove(dll_head, dll_tail,elem);
801 dll_size--;
802 return GNUNET_OK;
803 }
804 return GNUNET_SYSERR;
805}
806
807void create_dummy_entries ()
808{
809
810 /* test */
811 struct GNUNET_Hostlist * hostlist1;
812 hostlist1 = GNUNET_malloc ( sizeof (struct GNUNET_Hostlist) );
813 char * str = "uri_1";
814
815 GNUNET_CRYPTO_hash_create_random ( GNUNET_CRYPTO_QUALITY_WEAK , &hostlist1->peer.hashPubKey);
816 hostlist1->hello_count = 0;
817 hostlist1->hostlist_uri = GNUNET_malloc ( strlen(str) +1 );
818 strcpy(hostlist1->hostlist_uri,str);
819 hostlist1->time_creation = GNUNET_TIME_absolute_get();
820 hostlist1->time_last_usage = GNUNET_TIME_absolute_get_zero();
821 hostlist1->quality = HOSTLIST_INITIAL - 100;
822 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
823 "Adding test peer '%s' with URI %s and quality %u to dll \n", GNUNET_h2s (&hostlist1->peer.hashPubKey) , hostlist1->hostlist_uri, hostlist1->quality);
824 dll_insert (hostlist1);
825
826 struct GNUNET_Hostlist * hostlist2;
827 hostlist2 = GNUNET_malloc ( sizeof (struct GNUNET_Hostlist) );
828 char * str2 = "uri_2";
829
830 GNUNET_CRYPTO_hash_create_random ( GNUNET_CRYPTO_QUALITY_WEAK , &hostlist2->peer.hashPubKey);
831 hostlist2->hello_count = 0;
832 hostlist2->hostlist_uri = GNUNET_malloc ( strlen(str2) +1 );
833 strcpy(hostlist2->hostlist_uri,str2);
834 hostlist2->time_creation = GNUNET_TIME_absolute_get();
835 hostlist2->time_last_usage = GNUNET_TIME_absolute_get_zero();
836 hostlist2->quality = HOSTLIST_INITIAL - 200;
837 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
838 "Adding test peer '%s' with URI %s and quality %u to dll \n", GNUNET_h2s (&hostlist2->peer.hashPubKey) , hostlist2->hostlist_uri, hostlist2->quality);
839 dll_insert (hostlist2);
840
841 struct GNUNET_Hostlist * hostlist3;
842 hostlist3 = GNUNET_malloc ( sizeof (struct GNUNET_Hostlist) );
843 char * str3 = "uri_3";
844
845 GNUNET_CRYPTO_hash_create_random ( GNUNET_CRYPTO_QUALITY_WEAK , &hostlist3->peer.hashPubKey);
846 hostlist3->hello_count = 0;
847 hostlist3->hostlist_uri = GNUNET_malloc ( strlen(str3) +1 );
848 strcpy(hostlist3->hostlist_uri,str3);
849 hostlist3->time_creation = GNUNET_TIME_absolute_get();
850 hostlist3->time_last_usage = GNUNET_TIME_absolute_get_zero();
851 hostlist3->quality = HOSTLIST_INITIAL - 300;
852 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
853 "Adding test peer '%s' with URI %s and quality %u to dll \n", GNUNET_h2s (&hostlist3->peer.hashPubKey) , hostlist3->hostlist_uri, hostlist3->quality);
854 dll_insert (hostlist3);
855
856
857 struct GNUNET_Hostlist * hostlist4;
858 hostlist4 = GNUNET_malloc ( sizeof (struct GNUNET_Hostlist) );
859 char * str4 = "uri_4";
860
861 GNUNET_CRYPTO_hash_create_random ( GNUNET_CRYPTO_QUALITY_WEAK , &hostlist4->peer.hashPubKey);
862 hostlist4->hello_count = 0;
863 hostlist4->hostlist_uri = GNUNET_malloc ( strlen(str4) +1 );
864 strcpy(hostlist4->hostlist_uri,str4);
865 hostlist4->time_creation = GNUNET_TIME_absolute_get();
866 hostlist4->time_last_usage = GNUNET_TIME_absolute_get_zero();
867 hostlist4->quality = HOSTLIST_INITIAL - 400;
868 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
869 "Adding test peer '%s' with URI %s and quality %u to dll \n", GNUNET_h2s (&hostlist4->peer.hashPubKey) , hostlist4->hostlist_uri, hostlist4->quality);
870 dll_insert (hostlist4);
759} 871}
760 872
761/** 873/**
@@ -781,7 +893,6 @@ advertisement_handler (void *cls,
781 int uri_size = size - sizeof ( struct GNUNET_HOSTLIST_ADV_Message ); 893 int uri_size = size - sizeof ( struct GNUNET_HOSTLIST_ADV_Message );
782 char * uri = GNUNET_malloc ( uri_size ); 894 char * uri = GNUNET_malloc ( uri_size );
783 struct GNUNET_Hostlist * hostlist; 895 struct GNUNET_Hostlist * hostlist;
784 struct GNUNET_Hostlist * existing_hostlist;
785 896
786 if ( ntohs (message->type) != GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT) 897 if ( ntohs (message->type) != GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT)
787 return GNUNET_NO; 898 return GNUNET_NO;
@@ -791,7 +902,8 @@ advertisement_handler (void *cls,
791 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 902 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
792 "Hostlist client recieved advertisement from '%s' containing URI %s\n", GNUNET_i2s (peer), uri ); 903 "Hostlist client recieved advertisement from '%s' containing URI %s\n", GNUNET_i2s (peer), uri );
793 904
794 /* search in map for peer identity */ 905 create_dummy_entries();
906
795 hostlist = GNUNET_malloc ( sizeof (struct GNUNET_Hostlist) ); 907 hostlist = GNUNET_malloc ( sizeof (struct GNUNET_Hostlist) );
796 908
797 hostlist->peer = (*peer); 909 hostlist->peer = (*peer);
@@ -803,95 +915,43 @@ advertisement_handler (void *cls,
803 hostlist->times_used = 0; 915 hostlist->times_used = 0;
804 hostlist->quality = HOSTLIST_INITIAL; 916 hostlist->quality = HOSTLIST_INITIAL;
805 917
806 918 if ( GNUNET_YES != dll_contains (hostlist->hostlist_uri) )
807 GNUNET_HashCode * peer_ident_hash = (GNUNET_HashCode * ) &(peer->hashPubKey);
808
809 /* test */
810 struct GNUNET_Hostlist * hostlist2;
811 hostlist2 = GNUNET_malloc ( sizeof (struct GNUNET_Hostlist) );
812 char * str = "test";
813 GNUNET_HashCode * peer_ident_test = GNUNET_malloc ( sizeof (GNUNET_HashCode) );
814 GNUNET_CRYPTO_hash_from_string( "TEST", peer_ident_test);
815
816 hostlist2->peer.hashPubKey = (*peer_ident_test) ;
817 hostlist2->hello_count = 0;
818 hostlist2->hostlist_uri = GNUNET_malloc ( strlen(str) +1 );
819 strcpy(hostlist2->hostlist_uri,str);
820 hostlist2->time_creation = GNUNET_TIME_absolute_get();
821 hostlist2->time_last_usage = GNUNET_TIME_absolute_get_zero();
822 hostlist2->quality = HOSTLIST_INITIAL - 100;
823 GNUNET_CONTAINER_multihashmap_put ( hostlist_hashmap, peer_ident_test, hostlist2, GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE );
824 /* test */
825
826 if ( GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (hostlist_hashmap, peer_ident_hash) )
827 { 919 {
828 if ( MAX_NUMBER_HOSTLISTS > GNUNET_CONTAINER_multihashmap_size (hostlist_hashmap) ) 920 if ( MAX_NUMBER_HOSTLISTS > dll_size )
829 { 921 {
830 /* Entries available, add hostlist to hashmap */ 922 /* Entries available, add hostlist to dll */
831 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 923 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
832 "Adding peer '%s' to hashmap\n", GNUNET_i2s (peer) ); 924 "Adding uri '%s' to dll\n", hostlist->hostlist_uri );
833 GNUNET_CONTAINER_multihashmap_put ( hostlist_hashmap, peer_ident_hash, hostlist, GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE ); 925 dll_insert ( hostlist );
834 return GNUNET_YES; 926 return GNUNET_YES;
835 } 927 }
836 else 928 else
837 { 929 {
838 /* No free entries available, replace existing entry */ 930 /* No free entries available, replace existing entry */
839 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 931 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
840 "No free slots for hostlist available, searching for hostlist to replace\n", GNUNET_i2s (peer) ); 932 "No free slots for hostlist available, searching for hostlist to replace\n" );
841 /* iterate over all entries in hashmap */ 933
842 struct compare_struct * cmp = GNUNET_malloc( sizeof( struct compare_struct) ); 934 struct GNUNET_Hostlist * lowest_quality = dll_get_lowest_quality();
843 cmp->lowest_quality = 0;
844 cmp->key = NULL;
845 GNUNET_CONTAINER_multihashmap_iterate ( hostlist_hashmap,
846 &iterate_hashmap_for_replacing,
847 cmp );
848 935
849 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 936 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
850 "Peer %4s's hostlist has the worst quality of all peers with value %u \n", GNUNET_h2s (cmp->key), cmp->lowest_quality ); 937 "Hostlist with URI %s has the worst quality of all with value %u \n", lowest_quality->hostlist_uri, lowest_quality->quality );
851 /* replacing the entry with worst quality, if quality is below initial quality value */ 938 /* replacing the entry with worst quality, if quality is below initial quality value */
852 if ( cmp->lowest_quality < HOSTLIST_INITIAL) 939 if ( lowest_quality->quality < HOSTLIST_INITIAL)
853 { 940 {
941 dll_remove(lowest_quality);
854 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 942 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
855 "Peer %4s' removed, added peer %4s \n", GNUNET_h2s (cmp->key), GNUNET_h2s ( peer_ident_hash) ); 943 "URI '%s' removed \n",lowest_quality->hostlist_uri);
856 GNUNET_CONTAINER_multihashmap_remove ( hostlist_hashmap, cmp->key, cmp->value ); 944 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
857 GNUNET_CONTAINER_multihashmap_put ( hostlist_hashmap, peer_ident_hash, hostlist, GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE ); 945 "URI '%s' added %s\n", hostlist->hostlist_uri);
946 dll_insert ( hostlist );
858 } 947 }
859
860 return GNUNET_YES; 948 return GNUNET_YES;
861 } 949 }
862 } 950 }
863 else 951 else
864 { 952 {
865 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 953 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
866 "Peer already in hashmap\n"); 954 "Hostlist URI already in database\n");
867 /* hostlist entry already existing in hashmap */
868 /* compare uri to new uri and update if different */
869 /* update recieved date (vs using last download time to check reachability)? */
870 existing_hostlist = GNUNET_CONTAINER_multihashmap_get ( hostlist_hashmap, peer_ident_hash );
871 if ( 0 != strcmp (hostlist->hostlist_uri, ((struct GNUNET_Hostlist *) existing_hostlist)->hostlist_uri) )
872 {
873 /* uri is different */
874 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
875 "Updating peer '%s' from old URI '%s' to new URI '%s'\n", GNUNET_i2s (peer), existing_hostlist->hostlist_uri , hostlist->hostlist_uri);
876 existing_hostlist->hostlist_uri = GNUNET_realloc( existing_hostlist->hostlist_uri, strlen(hostlist->hostlist_uri) +1 );
877 if ( NULL != existing_hostlist->hostlist_uri )
878 {
879 strcpy(existing_hostlist->hostlist_uri,hostlist->hostlist_uri);
880 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
881 "URI updated to %s \n", existing_hostlist->hostlist_uri);
882 /* reset hostlist usage information*/
883 existing_hostlist->hello_count = 0;
884 existing_hostlist->time_last_usage = GNUNET_TIME_absolute_get_zero();
885 existing_hostlist->times_used = 0;
886 return GNUNET_YES;
887 }
888 else
889 {
890 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
891 "Updating peer '%s' failed \n", GNUNET_i2s (peer));
892 return GNUNET_NO;
893 }
894 }
895 } 955 }
896 956
897 /* since hostlist already existed in hashmap, object can be destroyed */ 957 /* since hostlist already existed in hashmap, object can be destroyed */
@@ -976,26 +1036,6 @@ static int load_hostlist_file ()
976 return GNUNET_OK; 1036 return GNUNET_OK;
977} 1037}
978 1038
979
980static int iterate_hashmap_for_saving ( void *cls, const GNUNET_HashCode *key, void *value )
981{
982 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
983 ("Now iterating over peer entry: %s\n"), GNUNET_i2s ( (const struct GNUNET_PeerIdentity *) key));
984
985 /* code to serialize hostlists to file*/
986 GNUNET_BIO_write_string ( (struct GNUNET_BIO_WriteHandle *) cls, ((struct GNUNET_Hostlist *) value)->hostlist_uri );
987
988 /* code to free hostlist */
989 if ( NULL != value )
990 {
991
992 GNUNET_free ( value );
993 GNUNET_free ( ((struct GNUNET_Hostlist *) value)->hostlist_uri );
994 }
995
996 return GNUNET_YES;
997}
998
999/** 1039/**
1000 * Method to load persistent hostlist file during hostlist client shutdown 1040 * Method to load persistent hostlist file during hostlist client shutdown
1001 * param c configuration to use 1041 * param c configuration to use
@@ -1027,10 +1067,7 @@ static int save_hostlist_file ()
1027 1067
1028 /* add code to write hostlists to file using bio */ 1068 /* add code to write hostlists to file using bio */
1029 1069
1030 /* iterate over all entries in hashmap */ 1070 /* iterate over all entries in dll */
1031 GNUNET_CONTAINER_multihashmap_iterate ( hostlist_hashmap,
1032 &iterate_hashmap_for_saving,
1033 wh );
1034 1071
1035 if ( GNUNET_OK != GNUNET_BIO_write_close ( wh ) ) 1072 if ( GNUNET_OK != GNUNET_BIO_write_close ( wh ) )
1036 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1073 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -1076,7 +1113,8 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
1076 *msgh = &advertisement_handler; 1113 *msgh = &advertisement_handler;
1077 1114
1078 learning = learn; 1115 learning = learn;
1079 hostlist_hashmap = GNUNET_CONTAINER_multihashmap_create ( MAX_NUMBER_HOSTLISTS ); 1116 dll_head = NULL;
1117 dll_tail = NULL;
1080 load_hostlist_file (); 1118 load_hostlist_file ();
1081 1119
1082 GNUNET_STATISTICS_get (stats, 1120 GNUNET_STATISTICS_get (stats,
@@ -1101,7 +1139,6 @@ GNUNET_HOSTLIST_client_stop ()
1101 "Hostlist client shutdown\n"); 1139 "Hostlist client shutdown\n");
1102#endif 1140#endif
1103 save_hostlist_file (); 1141 save_hostlist_file ();
1104 GNUNET_CONTAINER_multihashmap_destroy ( hostlist_hashmap );
1105 1142
1106 if (current_task != GNUNET_SCHEDULER_NO_TASK) 1143 if (current_task != GNUNET_SCHEDULER_NO_TASK)
1107 { 1144 {