Changeset 4340
- Timestamp:
- Dec 26, 2007, 7:25:50 AM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libtransmission/peer-mgr.c
r4326 r4340 701 701 getPreferredBlocks( Torrent * t, uint64_t * setmeCount ) 702 702 { 703 int s; 703 704 uint32_t i; 704 705 uint32_t pieceCount; 706 uint32_t blockCount; 707 uint32_t unreqCount[3], reqCount[3]; 705 708 uint32_t * pieces; 706 uint64_t * req, *unreq, *ret, *walk;707 int reqCount, unreqCount;709 uint64_t * ret, * walk; 710 uint64_t * unreq[3], *req[3]; 708 711 const tr_torrent * tor = t->tor; 709 712 … … 712 715 pieces = getPreferredPieces( t, &pieceCount ); 713 716 714 req = tr_new( uint64_t, pieceCount * tor->blockCountInPiece ); 715 reqCount = 0; 716 unreq = tr_new( uint64_t, pieceCount * tor->blockCountInPiece ); 717 unreqCount = 0; 718 719 for( i=0; i<pieceCount; ++i ) { 717 /** 718 * Now we walk through those preferred pieces to find all the blocks 719 * are still missing from them. We put unrequested blocks first, 720 * of course, but by including requested blocks afterwards, endgame 721 * handling happens naturally. 722 * 723 * By doing this once per priority we also effectively get an endgame 724 * mode for each priority level. The helps keep high priority files 725 * from getting stuck at 99% due of unresponsive peers. 726 */ 727 728 /* make temporary bins for the four tiers of blocks */ 729 for( i=0; i<3; ++i ) { 730 req[i] = tr_new( uint64_t, pieceCount * tor->blockCountInPiece ); 731 reqCount[i] = 0; 732 unreq[i] = tr_new( uint64_t, pieceCount * tor->blockCountInPiece ); 733 unreqCount[i] = 0; 734 } 735 736 /* sort the blocks into our temp bins */ 737 for( i=blockCount=0; i<pieceCount; ++i ) 738 { 720 739 const uint32_t index = pieces[i]; 740 const int priorityIndex = tor->info.pieces[index].priority + 1; 721 741 const int begin = tr_torPieceFirstBlock( tor, index ); 722 742 const int end = begin + tr_torPieceCountBlocks( tor, (int)index ); 723 743 int block; 744 724 745 for( block=begin; block<end; ++block ) 746 { 725 747 if( tr_cpBlockIsComplete( tor->completion, block ) ) 726 748 continue; 727 else if( tr_bitfieldHas( t->requested, block ) ) 728 req[reqCount++] = block; 749 750 ++blockCount; 751 752 if( tr_bitfieldHas( t->requested, block ) ) 753 { 754 const uint32_t n = reqCount[priorityIndex]++; 755 req[priorityIndex][n] = block; 756 } 729 757 else 730 unreq[unreqCount++] = block; 731 } 732 733 ret = walk = tr_new( uint64_t, unreqCount + reqCount ); 734 memcpy( walk, unreq, sizeof(uint64_t) * unreqCount ); 735 walk += unreqCount; 736 memcpy( walk, req, sizeof(uint64_t) * reqCount ); 737 walk += reqCount; 738 assert( ( walk - ret ) == ( unreqCount + reqCount ) ); 739 *setmeCount = walk - ret; 740 741 tr_free( req ); 742 tr_free( unreq ); 758 { 759 const uint32_t n = unreqCount[priorityIndex]++; 760 unreq[priorityIndex][n] = block; 761 } 762 } 763 } 764 765 /* join the bins together, going from highest priority to lowest so 766 * the the blocks we want to request first will be first in the list */ 767 ret = walk = tr_new( uint64_t, blockCount ); 768 for( s=2; s>=0; --s ) { 769 memcpy( walk, unreq[s], sizeof(uint64_t) * unreqCount[s] ); 770 walk += unreqCount[s]; 771 memcpy( walk, req[s], sizeof(uint64_t) * reqCount[s] ); 772 walk += reqCount[s]; 773 } 774 assert( ( walk - ret ) == blockCount ); 775 *setmeCount = blockCount; 776 777 /* cleanup */ 743 778 tr_free( pieces ); 744 779 for( i=0; i<3; ++i ) { 780 tr_free( unreq[i] ); 781 tr_free( req[i] ); 782 } 745 783 return ret; 746 784 }
Note: See TracChangeset
for help on using the changeset viewer.