mirror of
https://github.com/transmission/transmission
synced 2025-02-03 04:53:27 +00:00
better algorithm to decide on a good piece size. (SoftwareElves & charles_)
This commit is contained in:
parent
5128d0a434
commit
d4e1c19e32
1 changed files with 30 additions and 12 deletions
|
@ -8,6 +8,7 @@
|
|||
* the Transmission project.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
@ -73,22 +74,39 @@ getFiles( const char * dir,
|
|||
}
|
||||
|
||||
static int
|
||||
bestPieceSize( uint64_t totalSize )
|
||||
bestPieceSize( uint64_t totalSize, uint64_t fileCount )
|
||||
{
|
||||
const int MiB = 1048576;
|
||||
const int GiB = totalSize / (uint64_t)1073741824;
|
||||
int pieceSize = 1;
|
||||
const int minPieceSize = 65536; /* arbitrary; 2^16 */
|
||||
const int maxPieceSize = 16777216; /* arbitrary; 2^24 */
|
||||
const int desiredMinPiecesPerFile = 15; /* arbitrary */
|
||||
uint64_t log;
|
||||
|
||||
/* almost always best to have a piee size of 512 or 256 kb.
|
||||
common practice seems to be to bump up to 1MB pieces at
|
||||
at total size of around 8GiB or so */
|
||||
/* start off in the range of (1024..2048] pieces
|
||||
for "normal" torrents... */
|
||||
log = totalSize;
|
||||
while( log > 2048 ) {
|
||||
log >>= 1;
|
||||
pieceSize <<= 1;
|
||||
}
|
||||
|
||||
if( GiB >= 8 )
|
||||
return MiB;
|
||||
/* special case 1: torrents with a lot of small files.
|
||||
try to have a reasonable number of pieces per file,
|
||||
which will reduce overhead on selective downloading
|
||||
and increase swarm speed. */
|
||||
while( totalSize/pieceSize < (fileCount * desiredMinPiecesPerFile) ) {
|
||||
const int swap = pieceSize >> 1;
|
||||
if( swap < minPieceSize )
|
||||
break;
|
||||
pieceSize = swap;
|
||||
}
|
||||
|
||||
if( GiB >= 1 )
|
||||
return MiB / 2;
|
||||
/* special case 2: enormous single-file torrents. our normal
|
||||
case creates unwieldly piece sizes in that case */
|
||||
while( pieceSize < maxPieceSize )
|
||||
pieceSize >>= 1;
|
||||
|
||||
return MiB / 4;
|
||||
return pieceSize;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -148,7 +166,7 @@ tr_metaInfoBuilderCreate( tr_handle_t * handle, const char * topFile )
|
|||
sizeof(tr_metainfo_builder_file_t),
|
||||
builderFileCompare );
|
||||
|
||||
ret->pieceSize = bestPieceSize( ret->totalSize );
|
||||
ret->pieceSize = bestPieceSize( ret->totalSize, ret->fileCount );
|
||||
ret->pieceCount = (int)( ret->totalSize / ret->pieceSize);
|
||||
if( ret->totalSize % ret->pieceSize )
|
||||
++ret->pieceCount;
|
||||
|
|
Loading…
Reference in a new issue