Changeset 9782
- Timestamp:
- Dec 15, 2009, 8:13:34 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/peer-mgr.c
r9730 r9782 567 567 const struct block_request * a = va; 568 568 const struct block_request * b = vb; 569 570 /* primary key: block */ 569 571 if( a->block < b->block ) return -1; 570 572 if( a->block > b->block ) return 1; 573 574 /* secondary key: peer */ 575 if( a->peer < b->peer ) return -1; 576 if( a->peer > b->peer ) return 1; 577 571 578 return 0; 572 579 } … … 577 584 const struct block_request * a = va; 578 585 const struct block_request * b = vb; 586 587 /* primary key: time */ 579 588 if( a->sentAt < b->sentAt ) return -1; 580 589 if( a->sentAt > b->sentAt ) return 1; 590 591 /* secondary key: peer */ 592 if( a->peer < b->peer ) return -1; 593 if( a->peer > b->peer ) return 1; 594 581 595 return 0; 582 596 } … … 647 661 648 662 static struct block_request * 649 requestListLookup( Torrent * t, tr_block_index_t block )663 requestListLookup( Torrent * t, tr_block_index_t block, const tr_peer * peer ) 650 664 { 651 665 struct block_request key; 652 666 key.block = block; 667 key.peer = (tr_peer*) peer; 653 668 654 669 requestListSort( t, REQ_SORTED_BY_BLOCK ); … … 659 674 } 660 675 661 static void 662 requestListRemove( Torrent * t, tr_block_index_t block ) 663 { 664 const struct block_request * b = requestListLookup( t, block ); 676 static int 677 countBlockRequests( Torrent * t, tr_block_index_t block ) 678 { 679 tr_bool exact; 680 int i, n, pos; 681 struct block_request key; 682 683 requestListSort( t, REQ_SORTED_BY_BLOCK ); 684 key.block = block; 685 key.peer = NULL; 686 pos = tr_lowerBound( &key, t->requests, t->requestCount, 687 sizeof( struct block_request ), 688 compareReqByBlock, &exact ); 689 690 assert( !exact ); /* shouldn't have a request with .peer == NULL */ 691 692 n = 0; 693 for( i=pos; i<t->requestCount; ++i ) { 694 if( t->requests[i].block == block ) 695 ++n; 696 else 697 break; 698 } 699 700 return n; 701 } 702 703 static void 704 requestListRemove( Torrent * t, tr_block_index_t block, const tr_peer * peer ) 705 { 706 const struct block_request * b = requestListLookup( t, block, peer ); 665 707 if( b != NULL ) 666 708 { … … 921 963 { 922 964 struct weighted_piece * p = pieces + i; 965 const int missing = tr_cpMissingBlocksInPiece( &tor->completion, p->index ); 966 const int maxDuplicatesPerBlock = t->isInEndgame ? 3 : 1; 967 968 if( p->requestCount > ( missing * maxDuplicatesPerBlock ) ) 969 continue; 923 970 924 971 /* if the peer has this piece that we want... */ … … 930 977 for( ; b!=e && got<numwant; ++b ) 931 978 { 932 struct block_request * breq;933 934 979 /* don't request blocks we've already got */ 935 980 if( tr_cpBlockIsCompleteFast( &tor->completion, b ) ) 936 981 continue; 937 982 938 /* don't request blocks we've already requested (FIXME) */ 939 breq = requestListLookup( t, b ); 940 if( breq != NULL ) { 941 assert( breq->peer != NULL ); 942 if( breq->peer == peer ) continue; 943 if( !t->isInEndgame ) continue; 944 } 945 983 /* don't send the same request to the same peer twice */ 984 if( tr_peerMgrDidPeerRequest( tor, peer, b ) ) 985 continue; 986 987 /* don't send the same request to any peer too many times */ 988 if( countBlockRequests( t, b ) > maxDuplicatesPerBlock ) 989 continue; 990 991 /* update the caller's table */ 946 992 setme[got++] = b; 947 993 948 994 /* update our own tables */ 949 if( breq == NULL ) 950 requestListAdd( t, now, b, peer ); 995 requestListAdd( t, now, b, peer ); 951 996 ++p->requestCount; 952 997 } … … 955 1000 956 1001 /* In most cases we've just changed the weights of a small number of pieces. 957 * So rather than qsort()ing the entire array, it's faster to sort justthe1002 * So rather than qsort()ing the entire array, it's faster to sort only the 958 1003 * changed ones, then do a standard merge-two-sorted-arrays pass on the 959 1004 * changed and unchanged pieces. */ … … 1002 1047 { 1003 1048 const Torrent * t = tor->torrentPeers; 1004 const struct block_request * b = requestListLookup( (Torrent*)t, block ); 1005 if( b == NULL ) return FALSE; 1006 if( b->peer == peer ) return TRUE; 1007 if( t->isInEndgame ) return TRUE; 1008 return FALSE; 1049 return requestListLookup( (Torrent*)t, block, peer ) != NULL; 1009 1050 } 1010 1051 … … 1152 1193 1153 1194 static void 1154 removeRequestFromTables( Torrent * t, tr_block_index_t block )1155 { 1156 requestListRemove( t, block );1195 removeRequestFromTables( Torrent * t, tr_block_index_t block, const tr_peer * peer ) 1196 { 1197 requestListRemove( t, block, peer ); 1157 1198 pieceListRemoveRequest( t, block ); 1158 1199 } … … 1171 1212 1172 1213 for( i=0; i<n; ++i ) 1173 removeRequestFromTables( t, blocks[i] );1214 removeRequestFromTables( t, blocks[i], peer ); 1174 1215 1175 1216 tr_free( blocks ); … … 1226 1267 1227 1268 case TR_PEER_CLIENT_GOT_REJ: 1228 removeRequestFromTables( t, _tr_block( t->tor, e->pieceIndex, e->offset ) );1269 removeRequestFromTables( t, _tr_block( t->tor, e->pieceIndex, e->offset ), peer ); 1229 1270 break; 1230 1271 … … 1296 1337 tr_block_index_t block = _tr_block( tor, e->pieceIndex, e->offset ); 1297 1338 1298 requestListRemove( t, block );1339 requestListRemove( t, block, peer ); 1299 1340 pieceListRemoveRequest( t, block ); 1300 1341
Note: See TracChangeset
for help on using the changeset viewer.