summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorerdgeist <>2007-01-13 19:06:39 +0000
committererdgeist <>2007-01-13 19:06:39 +0000
commitad6c1b2019a368ae41508599bbddb265c1374308 (patch)
tree41ec2a710b60b3b5484dc788faa55093922e3d63
parent25781604c235bd80bb54dd4e0b36b433eeb42a0f (diff)
New, fixpoint distinct random algorithm for choosing peers from the list... may contain bugs. Feedback welcome
-rw-r--r--trackerlogic.c42
1 files changed, 29 insertions, 13 deletions
diff --git a/trackerlogic.c b/trackerlogic.c
index b3aacc0..e4ea0ea 100644
--- a/trackerlogic.c
+++ b/trackerlogic.c
@@ -229,7 +229,6 @@ ot_torrent *add_peer_to_torrent( ot_hash *hash, ot_peer *peer ) {
229size_t return_peers_for_torrent( ot_torrent *torrent, unsigned int amount, char *reply ) { 229size_t return_peers_for_torrent( ot_torrent *torrent, unsigned int amount, char *reply ) {
230 char *r = reply; 230 char *r = reply;
231 unsigned int peer_count, seed_count, index; 231 unsigned int peer_count, seed_count, index;
232 int pool_offset = -1, pool_index = 0, wert = -1;
233 232
234#ifdef WANT_CLOSED_TRACKER 233#ifdef WANT_CLOSED_TRACKER
235 if( torrent == OT_TORRENT_NOT_ON_WHITELIST ) { 234 if( torrent == OT_TORRENT_NOT_ON_WHITELIST ) {
@@ -254,19 +253,36 @@ size_t return_peers_for_torrent( ot_torrent *torrent, unsigned int amount, char
254 if( peer_count < amount ) amount = peer_count; 253 if( peer_count < amount ) amount = peer_count;
255 254
256 r += sprintf( r, "d8:completei%ie10:incompletei%ie8:intervali600e5:peers%i:", seed_count, peer_count-seed_count, 6*amount ); 255 r += sprintf( r, "d8:completei%ie10:incompletei%ie8:intervali600e5:peers%i:", seed_count, peer_count-seed_count, 6*amount );
257 for( index = 0; index < amount; ++index ) { 256 if( amount ) {
258 double step = 1.8*((double)( peer_count - wert - 1 ))/((double)( amount - index )); 257 unsigned int pool_offset, pool_index = 0;;
259 int off = random() % (int)step; 258 unsigned int shifted_pc = peer_count;
260 off = 1 + ( off % ( peer_count - wert - 1 )); 259 unsigned int shifted_step = 0;
261 wert += off; pool_offset += off; 260 unsigned int shift = 0;
262 261
263 while( pool_offset >= torrent->peer_list->peers[pool_index].size ) { 262 /* Make fixpoint arithmetic as exact as possible */
264 pool_offset -= torrent->peer_list->peers[pool_index].size; 263#define MAXPRECBIT (1<<(8*sizeof(int)-3))
265 pool_index++; 264 while( !(shifted_pc & MAXPRECBIT ) ) { shifted_pc <<= 1; shift++; }
266 } 265 shifted_step = shifted_pc/amount;
266#undef MAXPRECBIT
267
268 /* Initialize somewhere in the middle of peers so that
269 fixpoint's aliasing doesn't alway miss the same peers */
270 pool_offset = random() % peer_count;
271
272 for( index = 0; index < amount; ++index ) {
273 /* This is the aliased, non shifted range, next value may fall into */
274 unsigned int diff = ( ( ( index + 1 ) * shifted_step ) >> shift ) -
275 ( ( index * shifted_step ) >> shift );
276 pool_offset += 1 + random() % diff;
277
278 while( pool_offset >= torrent->peer_list->peers[pool_index].size ) {
279 pool_offset -= torrent->peer_list->peers[pool_index].size;
280 pool_index = ( pool_index + 1 ) % OT_POOLS_COUNT;
281 }
267 282
268 memmove( r, ((ot_peer*)torrent->peer_list->peers[pool_index].data) + pool_offset, 6 ); 283 memmove( r, ((ot_peer*)torrent->peer_list->peers[pool_index].data) + pool_offset, 6 );
269 r += 6; 284 r += 6;
285 }
270 } 286 }
271 *r++ = 'e'; 287 *r++ = 'e';
272 288