void ChunkManager::downloadPriorityChanged(TorrentFile* tf,Priority newpriority,Priority oldpriority) { if (newpriority == EXCLUDED) { downloadStatusChanged(tf, false); return; } if (oldpriority == EXCLUDED) { downloadStatusChanged(tf, true); return; } savePriorityInfo(); Uint32 first = tf->getFirstChunk(); Uint32 last = tf->getLastChunk(); // first and last chunk may be part of multiple files // so we can't just exclude them QValueList<Uint32> files; // get list of files where first chunk lies in tor.calcChunkPos(first,files); Chunk* c = chunks[first]; // if one file in the list needs to be downloaded,increment first for (QValueList<Uint32>::iterator i = files.begin();i != files.end();i++) { Priority np = tor.getFile(*i).getPriority(); if (np > newpriority && *i != tf->getIndex()) { // make sure we don't go past last if (first == last) return; first++; break; } } files.clear(); // get list of files where last chunk lies in tor.calcChunkPos(last,files); c = chunks[last]; // if one file in the list needs to be downloaded,decrement last for (QValueList<Uint32>::iterator i = files.begin();i != files.end();i++) { Priority np = tor.getFile(*i).getPriority(); if (np > newpriority && *i != tf->getIndex()) { // make sure we don't wrap around if (last == 0 || last == first) return; last--; break; } } // last smaller then first is not normal, so just return if (last < first) { return; } prioritise(first,last,newpriority); if (newpriority == ONLY_SEED_PRIORITY) excluded(first,last); }
void ChunkManager::downloadPriorityChanged(TorrentFile* tf,Priority newpriority,Priority oldpriority) { if (newpriority == EXCLUDED) { d->downloadStatusChanged(tf, false); // dumpPriority(tf); return; } if (oldpriority == EXCLUDED) { d->downloadStatusChanged(tf, true); } d->savePriorityInfo(); Uint32 first = tf->getFirstChunk(); Uint32 last = tf->getLastChunk(); if (oldpriority == ONLY_SEED_PRIORITY) include(first,last); if (first == last) { if (d->isBorderChunk(first)) d->setBorderChunkPriority(first,newpriority); else prioritise(first,first,newpriority); if (newpriority == ONLY_SEED_PRIORITY) excluded(first,last); } else { // if the first one is a border chunk use setBorderChunkPriority and make the range smaller if (d->isBorderChunk(first)) { d->setBorderChunkPriority(first,newpriority); first++; } // if the last one is a border chunk use setBorderChunkPriority and make the range smaller if (d->isBorderChunk(last)) { d->setBorderChunkPriority(last,newpriority); last--; } // if we still have a valid range, prioritise it if (first <= last) { prioritise(first,last,newpriority); if (newpriority == ONLY_SEED_PRIORITY) excluded(first,last); } } // if it is a multimedia file, make sure we haven't overridden preview priority if (tf->isMultimedia()) { d->doPreviewPriority(*tf); } //dumpPriority(tf); }
void ChunkManager::downloadStatusChanged(TorrentFile* tf,bool download) { Uint32 first = tf->getFirstChunk(); Uint32 last = tf->getLastChunk(); if (download) { // include the chunks include(first,last); // if it is a multimedia file, prioritise first and last chunks of file if (tf->isMultimedia()) { Uint32 chunkOffset; chunkOffset = ((last - first) / 100) + 1; prioritise(first,first+chunkOffset,PREVIEW_PRIORITY); if (last - first > 2) { prioritise(last - chunkOffset, last, PREVIEW_PRIORITY); //prioritise(last -1,last, PREVIEW_PRIORITY); } } } else { // Out(SYS_DIO|LOG_DEBUG) << "Excluding chunks " << first << " to " << last << endl; // first and last chunk may be part of multiple files // so we can't just exclude them QValueList<Uint32> files,last_files; // get list of files where first chunk lies in tor.calcChunkPos(first,files); tor.calcChunkPos(last,last_files); // check for exceptional case which causes very long loops if (first == last && files.count() > 1) { cache->downloadStatusChanged(tf,download); savePriorityInfo(); return; } // go over all chunks from first to last and mark them as not downloaded // (first and last not included) for (Uint32 i = first + 1;i < last;i++) resetChunk(i); // if the first chunk only lies in one file, reset it if (files.count() == 1 && first != 0) { // Out(SYS_DIO|LOG_DEBUG) << "Resetting first " << first << endl; resetChunk(first); } // if the last chunk only lies in one file reset it if (last != first && last_files.count() == 1) { // Out(SYS_DIO|LOG_DEBUG) << "Resetting last " << last << endl; resetChunk(last); } Priority maxp = ONLY_SEED_PRIORITY; bool reprioritise_border_chunk = false; bool modified = false; // if one file in the list needs to be downloaded,increment first for (QValueList<Uint32>::iterator i = files.begin();i != files.end();i++) { if (*i == tf->getIndex()) continue; const TorrentFile & other = tor.getFile(*i); if (!other.doNotDownload()) { if (first != last && !modified) { first++; reprioritise_border_chunk = true; modified = true; } if (other.getPriority() > maxp) maxp = other.getPriority(); } } // in case we have incremented first, we better reprioritise the border chunk if (reprioritise_border_chunk) prioritise(first-1,first-1,maxp); maxp = ONLY_SEED_PRIORITY; reprioritise_border_chunk = false; modified = false; // if one file in the list needs to be downloaded,decrement last for (QValueList<Uint32>::iterator i = last_files.begin();i != last_files.end();i++) { if (*i == tf->getIndex()) continue; const TorrentFile & other = tor.getFile(*i); if (!other.doNotDownload()) { if (first != last && last > 0 && !modified) { last--; reprioritise_border_chunk = true; modified = true; } if (other.getPriority() > maxp) maxp = other.getPriority(); } } if (reprioritise_border_chunk) prioritise(last+1,last+1,maxp); // last smaller then first is not normal, so just return if (last < first) { cache->downloadStatusChanged(tf,download); savePriorityInfo(); return; } // Out(SYS_DIO|LOG_DEBUG) << "exclude " << first << " to " << last << endl; exclude(first,last); } // alert the cache but first put things in critical operation mode cache->downloadStatusChanged(tf,download); savePriorityInfo(); }