SiRoB, on Mar 28 2006, 06:38 AM, said:
@BlueSonicBoy
Nice mathematical demonstration, i already know it.
But you don't understand my purpose.
I will make a proper change to correctly work arround what i noticed to improve not only the end completion.
That's cool, but if you are outside of the DBR code's working range (110Mb)
the next block(s) requested will be EMBLOCKSIZE and there are drawbacks to starting a 10k too, (The main one I didn't even think of until Netfinity pointed it out!
).
Netfinity's more complex DBR code address the issue of end of Part I believe.
AFAIK the idea of
this code is to fix the worst effected point of a DL and hopefully get the fix into the official.
As I see it, making a small request of a client when there is plenty of the part you are requesting the block from left is of little help in most cases. However if you are down to the last few blocks in a part then it's a good idea.
But I think this should be outside of the DBR code.
Something like...?
bool CPartFile::GetNextRequestedBlock(CUpDownClient* sender, on Requested_Block_Struct** newblocks, uint16* count), said:
// BEGIN netfinty: Dynamic Block Requests
uint64 bytesPerRequest = EMBLOCKSIZE;
#if !defined DONT_USE_DBR
uint64 bytesLeftToDownload = GetFileSize() - GetCompletedSize();
uint32 fileDatarate = max(GetDatarate(), UPLOAD_CLIENT_DATARATE); // Always assume file is being downloaded at atleast 3 kB/s
uint32 sourceDatarate = max(sender->GetDownloadDatarate(), 10); // Always assume client is uploading at atleast 10 B/s
uint32 timeToFileCompletion = max((uint32) (bytesLeftToDownload / (uint64) fileDatarate) + 1, 10); // Always assume it will take atleast 10 seconds to complete
//bytesPerRequest = (sourceDatarate * timeToFileCompletion) / 2;
bytesPerRequest = (sourceDatarate * timeToFileCompletion) >> 1;
if (bytesPerRequest > EMBLOCKSIZE) bytesPerRequest = EMBLOCKSIZE;
else
if (bytesPerRequest < 10240)
{
// Let an other client request this packet if we are close to completion and source is slow
// Use the true file datarate here, otherwise we might get stuck in NNP state
if (!requestedblocks_list.IsEmpty() && timeToFileCompletion < 30 && bytesPerRequest < 3400 && 5 * sourceDatarate < GetDatarate())
{
DebugLog(_T("No request block given as source is slow and file near completion!"));
return false;
}
bytesPerRequest = 10240;
}
#endif
// END netfinty: Dynamic Block Requests
// Main loop
uint16 newBlockCount = 0;
while(newBlockCount != *count){
// Create a request block stucture if a chunk has been previously selected
if(sender->m_lastPartAsked != (uint16)-1){
//Reduce end of part block size for first block/slow source
if(bytesPerRequest == EMBLOCKSIZE && sender->IsEmuleClient() && sender->GetDownloadDatarate()<400 && DataRemainingInPart(sender->m_lastPartAsked)<3072000)
{
bytesPerRequest = 30720;
}
Requested_Block_Struct* pBlock = new Requested_Block_Struct;
if(GetNextEmptyBlockInPart(sender->m_lastPartAsked, pBlock, bytesPerRequest) == true){
// Keep a track of all pending requested blocks
requestedblocks_list.AddTail(pBlock);
// Update list of blocks to return
newblocks[newBlockCount++] = pBlock;
// Skip end of loop (=> CPU load)
continue;
}
else {
uint32 CPartFile::DataRemainingInPart(uint16 m_PartAsked) said:
uint32 CPartFile::DataRemainingInPart(uint16 m_PartAsked)
{
/* Calculate how much of the part is left in bytes (based on code from GetNextRequestedBlock() )*/
// Offsets of 'this' chunk
const uint64 uStart = (uint64)m_PartAsked * PARTSIZE;
const uint64 uEnd = (GetFileSize() - (uint64)1 < (uStart + PARTSIZE - 1)) ?
GetFileSize() - (uint64)1 : (uStart + PARTSIZE - 1);
ASSERT( uStart <= uEnd );
if(uStart >= uEnd) return PARTSIZE;
uint32 remainingdata = 0;
//gets bytes remaining
for(POSITION pos = gaplist.GetHeadPosition(); pos != NULL; )
{
const Gap_Struct* cur_gap = gaplist.GetNext(pos);
//Check if Gap is into the limit
if(cur_gap->start < uStart)
{
if(cur_gap->end > uStart && cur_gap->end < uEnd) remainingdata += cur_gap->end - uStart + 1;
else if(cur_gap->end >= uEnd) return PARTSIZE;
} else
if(cur_gap->start <= uEnd)
{
if(cur_gap->end < uEnd) remainingdata += cur_gap->end - cur_gap->start + 1;
else remainingdata += uEnd - cur_gap->start + 1;
}
}
return remainingdata;
}
edit:thresholds from 200 to 400 / 2048000 to 3072000
This post has been edited by BlueSonicBoy: 29 March 2006 - 03:11 AM