1
0
Fork 0
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:
Charles Kerr 2007-06-19 06:01:30 +00:00
parent 5128d0a434
commit d4e1c19e32

View file

@ -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;