diff options
Diffstat (limited to 'backport_lt_all_01-partially_done_and_choke_group_fix.patch')
-rw-r--r-- | backport_lt_all_01-partially_done_and_choke_group_fix.patch | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/backport_lt_all_01-partially_done_and_choke_group_fix.patch b/backport_lt_all_01-partially_done_and_choke_group_fix.patch new file mode 100644 index 000000000000..7c812bdf9e3e --- /dev/null +++ b/backport_lt_all_01-partially_done_and_choke_group_fix.patch @@ -0,0 +1,282 @@ +--- a/src/download/download_wrapper.cc 2016-12-12 08:49:18.000000000 +0000 ++++ a/src/download/download_wrapper.cc 2017-04-30 21:25:15.511379804 +0100 +@@ -228,6 +228,7 @@ DownloadWrapper::receive_hash_done(Chunk + priority_queue_erase(&taskScheduler, &m_main->delay_partially_done()); + priority_queue_erase(&taskScheduler, &m_main->delay_partially_restarted()); + priority_queue_insert(&taskScheduler, &m_main->delay_partially_done(), cachedTime); ++ finished_download(); + } + + if (!m_main->have_queue()->empty() && m_main->have_queue()->front().first >= cachedTime) +@@ -325,8 +326,10 @@ DownloadWrapper::receive_tick(uint32_t t + + void + DownloadWrapper::receive_update_priorities() { +- if (m_main->chunk_selector()->empty()) ++ if (m_main->chunk_selector()->empty()) { ++ file_list()->set_selected_size_bytes(); + return; ++ } + + data()->mutable_high_priority()->clear(); + data()->mutable_normal_priority()->clear(); +@@ -373,11 +376,15 @@ DownloadWrapper::receive_update_prioriti + priority_queue_erase(&taskScheduler, &m_main->delay_partially_done()); + priority_queue_erase(&taskScheduler, &m_main->delay_partially_restarted()); + +- if (was_partial) ++ if (was_partial) { + priority_queue_insert(&taskScheduler, &m_main->delay_partially_done(), cachedTime); +- else ++ finished_download(); ++ } else { + priority_queue_insert(&taskScheduler, &m_main->delay_partially_restarted(), cachedTime); ++ } + } ++ ++ file_list()->set_selected_size_bytes(); + } + + void +--- a/src/manager.cc 2016-12-12 08:49:18.000000000 +0000 ++++ a/src/manager.cc 2017-04-30 21:15:43.000000000 +0100 +@@ -98,7 +98,7 @@ Manager::Manager() : + m_connectionManager->listen()->slot_accepted() = + std::bind(&HandshakeManager::add_incoming, m_handshakeManager, std::placeholders::_1, std::placeholders::_2); + +- m_resourceManager->push_group("default"); ++ m_resourceManager->push_group("default_leech"); + m_resourceManager->group_back()->up_queue()->set_heuristics(choke_queue::HEURISTICS_UPLOAD_LEECH); + m_resourceManager->group_back()->down_queue()->set_heuristics(choke_queue::HEURISTICS_DOWNLOAD_LEECH); + } +--- a/src/protocol/handshake_manager.cc 2016-12-12 08:49:18.000000000 +0000 ++++ a/src/protocol/handshake_manager.cc 2017-04-30 21:15:43.000000000 +0100 +@@ -232,7 +232,7 @@ HandshakeManager::receive_succeeded(Hand + + if (!download->info()->is_active()) + reason = e_handshake_inactive_download; +- else if (download->file_list()->is_done() && handshake->bitfield()->is_all_set()) ++ else if (download->file_list()->data()->is_partially_done() && handshake->bitfield()->is_all_set()) + reason = e_handshake_unwanted_connection; + else + reason = e_handshake_duplicate; +--- a/src/protocol/peer_connection_base.cc 2016-12-12 08:49:18.000000000 +0000 ++++ a/src/protocol/peer_connection_base.cc 2017-04-30 21:15:43.000000000 +0100 +@@ -197,7 +197,7 @@ PeerConnectionBase::initialize(DownloadM + + m_peerChunks.download_cache()->clear(); + +- if (!m_download->file_list()->is_done()) { ++ if (!m_download->file_list()->data()->is_partially_done()) { + m_sendInterested = true; + m_downInterested = true; + } +--- a/src/protocol/peer_connection_leech.cc 2016-12-12 08:49:18.000000000 +0000 ++++ a/src/protocol/peer_connection_leech.cc 2017-04-30 21:15:43.000000000 +0100 +@@ -691,7 +691,7 @@ PeerConnection<type>::read_have_chunk(ui + m_download->choke_group()->up_queue()->set_not_queued(this, &m_upChoke); + } + +- if (type != Download::CONNECTION_LEECH || m_download->file_list()->is_done()) ++ if (type != Download::CONNECTION_LEECH || m_download->file_list()->data()->is_partially_done()) + return; + + if (is_down_interested()) { +--- a/src/torrent/data/file_list.cc 2016-12-12 08:49:18.000000000 +0000 ++++ a/src/torrent/data/file_list.cc 2017-04-30 21:15:43.000000000 +0100 +@@ -86,6 +86,7 @@ FileList::FileList() : + m_isOpen(false), + + m_torrentSize(0), ++ m_selectedSize(0), + m_chunkSize(0), + m_maxFileSize(~uint64_t()) { + } +@@ -98,6 +99,7 @@ FileList::~FileList() { + + base_type::clear(); + m_torrentSize = 0; ++ m_selectedSize = 0; + } + + bool +@@ -193,6 +195,65 @@ FileList::set_max_file_size(uint64_t siz + m_maxFileSize = size; + } + ++// This function should be called from receive_update_priorities(). ++// It offloads continous calculation by updating the m_selectedSize property. ++// Its purpose is to replace size_bytes() with selected_size_bytes() ++// by taking into account partial downloads. ++void ++FileList::set_selected_size_bytes(uint64_t bytes) { ++ if (bytes > 0) { ++ m_selectedSize = bytes; ++ return; ++ } ++ ++ if (is_done()) { ++ m_selectedSize = m_torrentSize; ++ return; ++ } ++ ++ uint64_t completedBytes = completed_bytes(); ++ ++ if (data()->is_partially_done()) { ++ m_selectedSize = completedBytes; ++ return; ++ } ++ ++ uint32_t selectedSizeChunks = 0; ++ uint32_t prevChunk = -1; ++ bool areAllFilesSelected = true; ++ bool isLastFileSelected = false; ++ ++ for (FileList::const_iterator itr = begin(), last = end(); itr != last; itr++) { ++ ++ if ((*itr)->priority() != PRIORITY_OFF) { ++ selectedSizeChunks += (*itr)->size_chunks() - ((*itr)->range_first() == prevChunk ? 1 : 0); ++ prevChunk = (*itr)->range_second() - 1; ++ ++ if (itr == end() - 1) ++ isLastFileSelected = true; ++ } else { ++ areAllFilesSelected = false; ++ } ++ ++ } ++ ++ if (areAllFilesSelected) { ++ m_selectedSize = m_torrentSize; ++ return; ++ } ++ ++ uint64_t selectedSizeBytes = (uint64_t)selectedSizeChunks * (uint64_t)m_chunkSize; ++ ++ // Dealing with size of last chunk as it's usually smaller than the rest. ++ uint64_t remainder = m_torrentSize % (uint64_t)m_chunkSize; ++ ++ if (isLastFileSelected && remainder != 0) ++ selectedSizeBytes = selectedSizeBytes - (uint64_t)m_chunkSize + remainder; ++ ++ // Set completed bytes if some files (e.g. all of them) were set to Off later. ++ m_selectedSize = (selectedSizeBytes < completedBytes ? completedBytes : selectedSizeBytes); ++} ++ + // This function should really ensure that we arn't dealing files + // spread over multiple mount-points. + uint64_t +@@ -376,6 +432,7 @@ FileList::initialize(uint64_t torrentSiz + + m_chunkSize = chunkSize; + m_torrentSize = torrentSize; ++ m_selectedSize = torrentSize; + m_rootDir = "."; + + m_data.mutable_completed_bitfield()->set_size_bits((size_bytes() + chunk_size() - 1) / chunk_size()); +@@ -725,6 +782,7 @@ FileList::reset_filesize(int64_t size) { + close(); + m_chunkSize = size; + m_torrentSize = size; ++ m_selectedSize = size; + (*begin())->set_size_bytes(size); + (*begin())->set_range(m_chunkSize); + +--- a/src/torrent/data/file_list.h 2016-12-12 08:49:18.000000000 +0000 ++++ a/src/torrent/data/file_list.h 2017-04-30 21:15:43.000000000 +0100 +@@ -109,6 +109,9 @@ public: + uint64_t size_bytes() const { return m_torrentSize; } + uint32_t size_chunks() const { return bitfield()->size_bits(); } + ++ uint64_t selected_size_bytes() const { return m_selectedSize; } ++ void set_selected_size_bytes(uint64_t bytes = 0); ++ + uint32_t completed_chunks() const { return bitfield()->size_set(); } + uint64_t completed_bytes() const; + uint64_t left_bytes() const; +@@ -187,6 +190,7 @@ private: + uint64_t m_torrentSize; + uint32_t m_chunkSize; + uint64_t m_maxFileSize; ++ uint64_t m_selectedSize; + + std::string m_rootDir; + +--- a/src/torrent/download.cc 2016-12-12 08:49:18.000000000 +0000 ++++ a/src/torrent/download.cc 2017-04-30 21:15:43.000000000 +0100 +@@ -565,32 +565,6 @@ Download::set_connection_type(Connection + m_ptr->set_connection_type(t); + } + +-Download::HeuristicType +-Download::upload_choke_heuristic() const { +- return (Download::HeuristicType)m_ptr->main()->choke_group()->up_queue()->heuristics(); +-} +- +-void +-Download::set_upload_choke_heuristic(HeuristicType t) { +- if ((choke_queue::heuristics_enum)t >= choke_queue::HEURISTICS_MAX_SIZE) +- throw input_error("Invalid heuristics value."); +- +- m_ptr->main()->choke_group()->up_queue()->set_heuristics((choke_queue::heuristics_enum)t); +-} +- +-Download::HeuristicType +-Download::download_choke_heuristic() const { +- return (Download::HeuristicType)m_ptr->main()->choke_group()->down_queue()->heuristics(); +-} +- +-void +-Download::set_download_choke_heuristic(HeuristicType t) { +- if ((choke_queue::heuristics_enum)t >= choke_queue::HEURISTICS_MAX_SIZE) +- throw input_error("Invalid heuristics value."); +- +- m_ptr->main()->choke_group()->down_queue()->set_heuristics((choke_queue::heuristics_enum)t); +-} +- + void + Download::update_priorities() { + m_ptr->receive_update_priorities(); +--- a/src/torrent/download.h 2016-12-12 08:49:18.000000000 +0000 ++++ a/src/torrent/download.h 2017-04-30 21:15:43.000000000 +0100 +@@ -183,15 +183,6 @@ public: + ConnectionType connection_type() const; + void set_connection_type(ConnectionType t); + +- typedef enum { +- } HeuristicType; +- +- HeuristicType upload_choke_heuristic() const; +- void set_upload_choke_heuristic(HeuristicType t); +- +- HeuristicType download_choke_heuristic() const; +- void set_download_choke_heuristic(HeuristicType t); +- + // Call this when you want the modifications of the download priorities + // in the entries to take effect. It is slightly expensive as it rechecks + // all the peer bitfields to see if we are still interested. +--- a/src/torrent/peer/connection_list.cc 2016-12-12 08:49:18.000000000 +0000 ++++ a/src/torrent/peer/connection_list.cc 2017-04-30 21:15:43.000000000 +0100 +@@ -79,7 +79,7 @@ ConnectionList::clear() { + + bool + ConnectionList::want_connection(PeerInfo* p, Bitfield* bitfield) { +- if (m_download->file_list()->is_done() || m_download->initial_seeding() != NULL) ++ if (m_download->file_list()->data()->is_partially_done() || m_download->initial_seeding() != NULL) + return !bitfield->is_all_set(); + + if (!m_download->info()->is_accepting_seeders()) +--- a/src/torrent/utils/resume.cc 2016-12-12 08:49:18.000000000 +0000 ++++ a/src/torrent/utils/resume.cc 2017-04-30 21:15:43.000000000 +0100 +@@ -254,10 +254,7 @@ resume_save_progress(Download download, + + // } else if ((*listItr)->completed_chunks() == (*listItr)->size_chunks()) { + +- } else if (fileList->bitfield()->is_all_set()) { +- // Currently only checking if we're finished. This needs to be +- // smarter when it comes to downloading partial torrents, etc. +- ++ } else if (download.data()->is_partially_done()) { + // This assumes the syncs are properly called before + // resume_save_progress gets called after finishing a torrent. + filesItr->insert_key("mtime", (int64_t)fs.modified_time()); |