diff options
Diffstat (limited to 'trackerlogic.c')
-rw-r--r-- | trackerlogic.c | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/trackerlogic.c b/trackerlogic.c index ece3261..762ad69 100644 --- a/trackerlogic.c +++ b/trackerlogic.c | |||
@@ -15,11 +15,19 @@ | |||
15 | #include "scan.h" | 15 | #include "scan.h" |
16 | #include "byte.h" | 16 | #include "byte.h" |
17 | 17 | ||
18 | // GLOBAL VARIABLES | ||
19 | // | ||
20 | static ot_vector all_torrents[256]; | ||
21 | |||
18 | // Helper functions for binary_find | 22 | // Helper functions for binary_find |
19 | // | 23 | // |
20 | int compare_hash( const void *hash1, const void *hash2 ) { return memcmp( hash1, hash2, sizeof( ot_hash )); } | 24 | int compare_hash( const void *hash1, const void *hash2 ) { return memcmp( hash1, hash2, sizeof( ot_hash )); } |
21 | int compare_ip_port( const void *peer1, const void *peer2 ) { return memcmp( peer1, peer2, 6 ); } | 25 | int compare_ip_port( const void *peer1, const void *peer2 ) { return memcmp( peer1, peer2, 6 ); } |
22 | 26 | ||
27 | // This function gives us a binary search that returns a pointer, even if | ||
28 | // no exact match is found. In that case it sets exactmatch 0 and gives | ||
29 | // calling functions the chance to insert data | ||
30 | // | ||
23 | static void *binary_search( const void *key, const void *base, | 31 | static void *binary_search( const void *key, const void *base, |
24 | unsigned long member_count, const unsigned long member_size, | 32 | unsigned long member_count, const unsigned long member_size, |
25 | int (*compar) (const void *, const void *), | 33 | int (*compar) (const void *, const void *), |
@@ -48,9 +56,6 @@ static void *binary_search( const void *key, const void *base, | |||
48 | // | 56 | // |
49 | char ths[1+2*20];char*to_hex(ot_byte*s){char*m="0123456789ABCDEF";char*e=ths+40;char*t=ths;while(t<e){*t++=m[*s>>4];*t++=m[*s++&15];}*t=0;return ths;} | 57 | char ths[1+2*20];char*to_hex(ot_byte*s){char*m="0123456789ABCDEF";char*e=ths+40;char*t=ths;while(t<e){*t++=m[*s>>4];*t++=m[*s++&15];}*t=0;return ths;} |
50 | 58 | ||
51 | // GLOBAL VARIABLES | ||
52 | // | ||
53 | static ot_vector all_torrents[256]; | ||
54 | 59 | ||
55 | static void *vector_find_or_insert( ot_vector *vector, void *key, size_t member_size, int(*compare_func)(const void*, const void*), int *exactmatch ) { | 60 | static void *vector_find_or_insert( ot_vector *vector, void *key, size_t member_size, int(*compare_func)(const void*, const void*), int *exactmatch ) { |
56 | ot_byte *match = BINARY_FIND( key, vector->data, vector->size, member_size, compare_func, exactmatch ); | 61 | ot_byte *match = BINARY_FIND( key, vector->data, vector->size, member_size, compare_func, exactmatch ); |
@@ -58,14 +63,15 @@ static void *vector_find_or_insert( ot_vector *vector, void *key, size_t member_ | |||
58 | if( *exactmatch ) return match; | 63 | if( *exactmatch ) return match; |
59 | 64 | ||
60 | if( vector->size + 1 >= vector->space ) { | 65 | if( vector->size + 1 >= vector->space ) { |
61 | ot_byte *new_data = realloc( vector->data, vector->space ? 2 * vector->space : 1024 ); | 66 | size_t new_space = vector->space ? OT_VECTOR_GROW_RATIO * vector->space : OT_VECTOR_MIN_MEMBERS; |
67 | ot_byte *new_data = realloc( vector->data, new_space * member_size ); | ||
62 | if( !new_data ) return NULL; | 68 | if( !new_data ) return NULL; |
63 | 69 | ||
64 | // Adjust pointer if it moved by realloc | 70 | // Adjust pointer if it moved by realloc |
65 | match = match - (ot_byte*)vector->data + new_data; | 71 | match = match - (ot_byte*)vector->data + new_data; |
66 | 72 | ||
67 | vector->data = new_data; | 73 | vector->data = new_data; |
68 | vector->space = vector->space ? vector->space * 2 : 1024; | 74 | vector->space = new_space;; |
69 | } | 75 | } |
70 | MEMMOVE( match + member_size, match, ((ot_byte*)vector->data) + member_size * vector->size - match ); | 76 | MEMMOVE( match + member_size, match, ((ot_byte*)vector->data) + member_size * vector->size - match ); |
71 | vector->size++; | 77 | vector->size++; |
@@ -74,6 +80,7 @@ static void *vector_find_or_insert( ot_vector *vector, void *key, size_t member_ | |||
74 | 80 | ||
75 | static int vector_remove_peer( ot_vector *vector, ot_peer *peer ) { | 81 | static int vector_remove_peer( ot_vector *vector, ot_peer *peer ) { |
76 | int exactmatch; | 82 | int exactmatch; |
83 | ot_peer *end = ((ot_peer*)vector->data) + vector->size; | ||
77 | ot_peer *match; | 84 | ot_peer *match; |
78 | 85 | ||
79 | if( !vector->size ) return 0; | 86 | if( !vector->size ) return 0; |
@@ -81,8 +88,11 @@ static int vector_remove_peer( ot_vector *vector, ot_peer *peer ) { | |||
81 | 88 | ||
82 | if( !exactmatch ) return 0; | 89 | if( !exactmatch ) return 0; |
83 | exactmatch = OT_FLAG( match ) & PEER_FLAG_SEEDING ? 2 : 1; | 90 | exactmatch = OT_FLAG( match ) & PEER_FLAG_SEEDING ? 2 : 1; |
84 | MEMMOVE( match, match + 1, ((ot_peer*)vector->data) + vector->size - match - 1 ); | 91 | MEMMOVE( match, match + 1, end - match - 1 ); |
85 | vector->size--; | 92 | if( ( --vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) && ( vector->space > OT_VECTOR_MIN_MEMBERS ) ) { |
93 | vector->space /= OT_VECTOR_SHRINK_RATIO; | ||
94 | realloc( vector->data, vector->space * sizeof( ot_peer ) ); | ||
95 | } | ||
86 | return exactmatch; | 96 | return exactmatch; |
87 | } | 97 | } |
88 | 98 | ||
@@ -97,17 +107,19 @@ static void free_peerlist( ot_peerlist *peer_list ) { | |||
97 | static int vector_remove_torrent( ot_vector *vector, ot_hash *hash ) { | 107 | static int vector_remove_torrent( ot_vector *vector, ot_hash *hash ) { |
98 | int exactmatch; | 108 | int exactmatch; |
99 | ot_torrent *end = ((ot_torrent*)vector->data) + vector->size; | 109 | ot_torrent *end = ((ot_torrent*)vector->data) + vector->size; |
100 | ot_torrent *match = BINARY_FIND( hash, vector->data, vector->size, sizeof( ot_torrent ), compare_hash, &exactmatch ); | 110 | ot_torrent *match; |
111 | |||
112 | if( !vector->size ) return 0; | ||
113 | match = BINARY_FIND( hash, vector->data, vector->size, sizeof( ot_torrent ), compare_hash, &exactmatch ); | ||
101 | 114 | ||
102 | if( !exactmatch ) return -1; | 115 | if( !exactmatch ) return 0; |
103 | free_peerlist( match->peer_list ); | 116 | free_peerlist( match->peer_list ); |
104 | MEMMOVE( match, match + 1, end - match - 1 ); | 117 | MEMMOVE( match, match + 1, end - match - 1 ); |
105 | vector->size--; | 118 | if( ( --vector->size * OT_VECTOR_SHRINK_THRESH < vector->space ) && ( vector->space > OT_VECTOR_MIN_MEMBERS ) ) { |
106 | if( ( 3*vector->size < vector->space ) && ( vector->space > 1024 ) ) { | 119 | vector->space /= OT_VECTOR_SHRINK_RATIO; |
107 | realloc( vector->data, vector->space >> 1 ); | 120 | realloc( vector->data, vector->space * sizeof( ot_torrent ) ); |
108 | vector->space >>= 1; | ||
109 | } | 121 | } |
110 | return 0; | 122 | return 1; |
111 | } | 123 | } |
112 | 124 | ||
113 | // Returns 1, if torrent is gone, 0 otherwise | 125 | // Returns 1, if torrent is gone, 0 otherwise |
@@ -253,14 +265,18 @@ void remove_peer_from_torrent( ot_hash *hash, ot_peer *peer ) { | |||
253 | 265 | ||
254 | if( !exactmatch ) return; | 266 | if( !exactmatch ) return; |
255 | 267 | ||
268 | // Maybe this does the job | ||
269 | if( clean_peerlist( torrent->peer_list ) ) { | ||
270 | vector_remove_torrent( torrents_list, hash ); | ||
271 | return; | ||
272 | } | ||
273 | |||
256 | for( i=0; i<OT_POOLS_COUNT; ++i ) | 274 | for( i=0; i<OT_POOLS_COUNT; ++i ) |
257 | switch( vector_remove_peer( &torrent->peer_list->peers[i], peer ) ) { | 275 | switch( vector_remove_peer( &torrent->peer_list->peers[i], peer ) ) { |
258 | case 0: continue; | 276 | case 0: continue; |
259 | case 2: torrent->peer_list->seed_count[i]--; | 277 | case 2: torrent->peer_list->seed_count[i]--; |
260 | case 1: default: return; | 278 | case 1: default: return; |
261 | } | 279 | } |
262 | |||
263 | clean_peerlist( torrent->peer_list ); | ||
264 | } | 280 | } |
265 | 281 | ||
266 | void cleanup_torrents( void ) { | 282 | void cleanup_torrents( void ) { |