Improvements to the file transfer algorithm.

Increased max individual file speed to 1MB/s



git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@826 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2008-11-19 01:12:21 +00:00
parent 3d3f4bfec9
commit 7c596231e1
3 changed files with 91 additions and 10 deletions

View File

@ -326,8 +326,8 @@ bool ftController::completeFile(std::string hash)
/********************** Controller Access **********************/
/***************************************************************/
const uint32_t FT_CNTRL_STANDARD_RATE = 100 * 1024;
const uint32_t FT_CNTRL_SLOW_RATE = 10 * 1024;
const uint32_t FT_CNTRL_STANDARD_RATE = 1024 * 1024;
const uint32_t FT_CNTRL_SLOW_RATE = 10 * 1024;
bool ftController::FileRequest(std::string fname, std::string hash,
uint64_t size, std::string dest, uint32_t flags,

View File

@ -27,8 +27,6 @@
* #define FT_DEBUG 1
******/
#define FT_DEBUG 1
#include "fttransfermodule.h"
/*************************************************************************
@ -50,9 +48,15 @@
const double FT_TM_MAX_PEER_RATE = 1024 * 1024; /* 1MB/s */
const uint32_t FT_TM_MAX_RESETS = 5;
const uint32_t FT_TM_MINIMUM_CHUNK = 1024; /* ie 1Kb / sec */
const uint32_t FT_TM_MINIMUM_CHUNK = 128; /* ie 1/8Kb / sec */
const uint32_t FT_TM_RESTART_DOWNLOAD = 20; /* 20 seconds */
const uint32_t FT_TM_DOWNLOAD_TIMEOUT = 18; /* 18 seconds */
const uint32_t FT_TM_DOWNLOAD_TIMEOUT = 10; /* 10 seconds */
const double FT_TM_MAX_INCREASE = 1.00;
const double FT_TM_MIN_INCREASE = -0.10;
const int32_t FT_TM_FAST_RTT = 1.0;
const int32_t FT_TM_STD_RTT = 5.0;
const int32_t FT_TM_SLOW_RTT = 9.0;
ftTransferModule::ftTransferModule(ftFileCreator *fc, ftDataMultiplex *dm, ftController *c)
:mFileCreator(fc), mMultiplexor(dm), mFtController(c), mFlag(0)
@ -175,7 +179,8 @@ bool ftTransferModule::setPeerState(std::string peerId,uint32_t state,uint32_t m
(mit->second).state=state;
(mit->second).desiredRate=maxRate;
(mit->second).actualRate=maxRate; /* should give big kick in right direction */
// Start it off at zero....
// (mit->second).actualRate=maxRate; /* should give big kick in right direction */
std::list<std::string>::iterator it;
it = std::find(mOnlinePeers.begin(), mOnlinePeers.end(), peerId);
@ -574,8 +579,29 @@ bool ftTransferModule::locked_tickPeerTransfer(peerInfo &info)
info.actualRate = info.actualRate * 0.75 + 0.25 * info.lastTransfers;
info.lastTransfers = 0;
/* request at 10% more than actual rate */
uint32_t next_req = info.actualRate * 1.25;
/****************
* NOTE: If we continually increase the request rate thus: ...
* uint32_t next_req = info.actualRate * 1.25;
*
* then we will achieve max data rate, but we will fill up
* peers out queue and/or network buffers.....
*
* we must therefore monitor the RTT to tell us if this is happening.
*/
/* emergency shutdown if we are stuck in x 1.25 mode
* probably not needed
*/
if ((info.rttActive) && (ts - info.rttStart > FT_TM_SLOW_RTT))
{
if (info.mRateIncrease > 0)
{
info.mRateIncrease = 0;
}
}
/* request at more than current rate */
uint32_t next_req = info.actualRate * (1.0 + info.mRateIncrease);
if (next_req > info.desiredRate * 1.1)
next_req = info.desiredRate * 1.1;
@ -587,6 +613,7 @@ bool ftTransferModule::locked_tickPeerTransfer(peerInfo &info)
next_req = FT_TM_MINIMUM_CHUNK;
info.lastTS = ts;
/* do request */
uint64_t req_offset = 0;
@ -596,6 +623,14 @@ bool ftTransferModule::locked_tickPeerTransfer(peerInfo &info)
{
info.state = PQIPEER_DOWNLOADING;
requestData(info.peerId,req_offset,next_req);
/* start next rtt measurement */
if (!info.rttActive)
{
info.rttStart = ts;
info.rttActive = true;
info.rttOffset = req_offset + next_req;
}
}
else
{
@ -604,6 +639,8 @@ bool ftTransferModule::locked_tickPeerTransfer(peerInfo &info)
}
}
else mFlag = 1;
return true;
}
@ -627,6 +664,41 @@ bool ftTransferModule::locked_recvPeerData(peerInfo &info, uint64_t offset,
info.state = PQIPEER_DOWNLOADING;
info.lastTransfers += chunk_size;
if ((info.rttActive) && (info.rttOffset == offset + chunk_size))
{
/* update tip */
int32_t rtt = time(NULL) - info.rttStart;
/*
* FT_TM_FAST_RTT = 1 sec. mRateIncrease = 1.00
* FT_TM_SLOW_RTT = 9 sec. mRateIncrease = 0
* 11 sec. mRateIncrease = -0.25
* if it is slower than this allow fast data increase.
* initial guess - linear with rtt.
* change if this leads to wild oscillations
*
*/
info.mRateIncrease = (FT_TM_SLOW_RTT - rtt) *
(FT_TM_MAX_INCREASE / (FT_TM_SLOW_RTT - FT_TM_FAST_RTT));
if (info.mRateIncrease > FT_TM_MAX_INCREASE)
info.mRateIncrease = FT_TM_MAX_INCREASE;
if (info.mRateIncrease < FT_TM_MIN_INCREASE)
info.mRateIncrease = FT_TM_MIN_INCREASE;
info.rtt = rtt;
info.rttActive = false;
#ifdef FT_DEBUG
std::cerr << "ftTransferModule::locked_recvPeerData()";
std::cerr << "Updated Rate based on RTT: " << rtt;
std::cerr << " Rate: " << info.mRateIncrease;
std::cerr << std::endl;
#endif
}
return true;
}

View File

@ -63,7 +63,9 @@ public:
peerInfo(std::string peerId_in,uint32_t state_in,uint32_t maxRate_in):
peerId(peerId_in),state(state_in),desiredRate(maxRate_in),actualRate(0),
offset(0),chunkSize(0),receivedSize(0),lastTS(0),
recvTS(0), lastTransfers(0), nResets(0)
recvTS(0), lastTransfers(0), nResets(0),
rtt(0), rttActive(false), rttStart(0), rttOffset(0),
mRateIncrease(1)
{
return;
}
@ -83,6 +85,13 @@ public:
time_t recvTS; /* last Recv */
uint32_t lastTransfers; /* data recvd in last second */
uint32_t nResets; /* count to disable non-existant files */
/* rrt rate control */
uint32_t rtt; /* last rtt */
bool rttActive; /* have we initialised an rtt measurement */
time_t rttStart; /* ts of request */
uint64_t rttOffset; /* end of request */
float mRateIncrease; /* current rate */
};
class ftFileStatus