void ChunkDownload::notDownloaded(const Request & r,bool reject) { // find the peer DownloadStatus* ds = dstatus.find(r.getPeer()); if (ds) { // Out() << "ds != 0" << endl; Uint32 p = r.getOffset() / MAX_PIECE_LEN; ds->remove(p); } // go over all PD's and do requets again for (QPtrList<PeerDownloader>::iterator i = pdown.begin();i != pdown.end();++i) sendRequests(*i); }
void ChunkDownload::endgameCancel(const Piece & p) { QPtrList<PeerDownloader>::iterator i = pdown.begin(); while (i != pdown.end()) { PeerDownloader* pd = *i; DownloadStatus* ds = dstatus.find(pd->getPeer()->getID()); Uint32 pp = p.getOffset() / MAX_PIECE_LEN; if (ds && ds->contains(pp)) { pd->cancel(Request(p)); ds->remove(pp); } i++; } }
bool ChunkDownload::piece(const Piece & p,bool & ok) { ok = false; timer.update(); Uint32 pp = p.getOffset() / MAX_PIECE_LEN; Uint32 len = pp == num - 1 ? last_size : MAX_PIECE_LEN; if (pp >= num || pieces.get(pp) || p.getLength() != len) return false; DownloadStatus* ds = dstatus.find(p.getPieceDownloader()); if (ds) ds->remove(pp); PieceData::Ptr buf = chunk->getPiece(p.getOffset(),p.getLength(),false); if (buf && buf->write(p.getData(),p.getLength()) == p.getLength()) { piece_data[pp] = buf; ok = true; pieces.set(pp,true); piece_providers.insert(p.getPieceDownloader()); num_downloaded++; if (pdown.count() > 1) { endgameCancel(p); } updateHash(); if (num_downloaded >= num) { // finalize hash hash_gen.end(); releaseAllPDs(); return true; } } sendRequests(); return false; }
void ChunkDownload::sendCancels(PeerDownloader* pd) { DownloadStatus* ds = dstatus.find(pd->getPeer()->getID()); if (!ds) return; DownloadStatus::iterator itr = ds->begin(); while (itr != ds->end()) { Uint32 i = *itr; pd->cancel( Request( chunk->getIndex(), i*MAX_PIECE_LEN, i+1<num ? MAX_PIECE_LEN : last_size,0)); itr++; } ds->clear(); timer.update(); }
void ChunkDownload::sendRequests(PeerDownloader* pd) { timer.update(); DownloadStatus* ds = dstatus.find(pd->getPeer()->getID()); if (!ds) return; // if the peer is choked and we are not downloading an allowed fast chunk if (pd->isChoked()) return; Uint32 num_visited = 0; while (num_visited < piece_queue.count() && pd->canAddRequest()) { // get the first one in the queue Uint32 i = piece_queue.first(); if (!ds->contains(i)) { // send request pd->download( Request( chunk->getIndex(), i*MAX_PIECE_LEN, i+1<num ? MAX_PIECE_LEN : last_size, pd->getPeer()->getID())); ds->add(i); } // move to the back so that it will take a while before it's turn is up piece_queue.pop_front(); piece_queue.append(i); num_visited++; } if (piece_queue.count() < 2 && piece_queue.count() > 0) pd->setNearlyDone(true); }