From 5d9912c21c5014db75e6db03412b2cfcdd0e2b77 Mon Sep 17 00:00:00 2001 From: Auska Date: Tue, 4 Feb 2025 10:08:35 +0800 Subject: [PATCH] add-download-sequentially --- src/download/chunk_selector.cc | 23 +++++++++++++++-------- src/download/chunk_selector.h | 11 +++++++++++ src/torrent/download.cc | 11 +++++++++++ src/torrent/download.h | 4 ++++ 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/download/chunk_selector.cc b/src/download/chunk_selector.cc index 81fd65059..ea6365ae3 100644 --- a/src/download/chunk_selector.cc +++ b/src/download/chunk_selector.cc @@ -80,8 +80,13 @@ ChunkSelector::update_priorities() { m_sharedQueue.clear(); - if (m_position == invalid_chunk) - m_position = random() % size(); + if (m_position == invalid_chunk) { + if (m_sequential) { + m_position = 0; + } else { + m_position = random() % size(); + } + } advance_position(); } @@ -99,12 +104,14 @@ ChunkSelector::find(PeerChunks* pc, [[maybe_unused]] bool highPriority) { // set. rak::partial_queue* queue = pc->is_seeder() ? &m_sharedQueue : pc->download_cache(); - // Randomize position on average every 16 chunks to prevent - // inefficient distribution with a slow seed and fast peers - // all arriving at the same position. - if ((random() & 63) == 0) { - m_position = random() % size(); - queue->clear(); + if (!m_sequential) { + // Randomize position on average every 16 chunks to prevent + // inefficient distribution with a slow seed and fast peers + // all arriving at the same position. + if ((random() & 63) == 0) { + m_position = random() % size(); + queue->clear(); + } } if (queue->is_enabled()) { diff --git a/src/download/chunk_selector.h b/src/download/chunk_selector.h index ab1b8c175..6b5f2ce3c 100644 --- a/src/download/chunk_selector.h +++ b/src/download/chunk_selector.h @@ -76,6 +76,15 @@ class ChunkSelector { void initialize(ChunkStatistics* cs); void cleanup(); + // Sequential chunk selection + bool is_sequential_enabled() { + return m_sequential; + }; + void set_sequential_enabled(bool enabled) { + m_sequential = enabled; + }; + + // Call this once you've modified the bitfield or priorities to // update cached information. This must be called once before using // find. @@ -118,6 +127,8 @@ class ChunkSelector { rak::partial_queue m_sharedQueue; uint32_t m_position; + + bool m_sequential = false; }; } diff --git a/src/torrent/download.cc b/src/torrent/download.cc index 2f49bf8f0..b32a641ad 100644 --- a/src/torrent/download.cc +++ b/src/torrent/download.cc @@ -247,6 +247,17 @@ Download::set_pex_enabled(bool enabled) { m_ptr->info()->unset_flags(DownloadInfo::flag_pex_enabled); } +bool +Download::is_sequential_enabled() { + return m_ptr->main()->chunk_selector()->is_sequential_enabled(); +} + +void +Download::set_sequential_enabled(bool enabled) { + m_ptr->main()->chunk_selector()->set_sequential_enabled(enabled); +} + + Object* Download::bencode() { return m_ptr->bencode(); diff --git a/src/torrent/download.h b/src/torrent/download.h index 4968c2de2..7837e8b37 100644 --- a/src/torrent/download.h +++ b/src/torrent/download.h @@ -99,6 +99,10 @@ class LIBTORRENT_EXPORT Download { void set_pex_enabled(bool enabled); + // Sequential download + bool is_sequential_enabled(); + void set_sequential_enabled(bool enabled); + Object* bencode(); const Object* bencode() const;