From e2a1b6d7e510657ace55fe8639fd28904afb9c3a Mon Sep 17 00:00:00 2001 From: orignal Date: Thu, 13 Aug 2026 21:29:48 -0400 Subject: [PATCH] try to request block from piece requested by another connection if no other pieces available --- libi2pd_client/Torrents.cpp | 35 ++++++++++++++++++++++++----------- libi2pd_client/Torrents.h | 3 ++- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/libi2pd_client/Torrents.cpp b/libi2pd_client/Torrents.cpp index 27a0f77c..b1cb4e7a 100644 --- a/libi2pd_client/Torrents.cpp +++ b/libi2pd_client/Torrents.cpp @@ -507,7 +507,7 @@ namespace torrents return complete; } - std::tuple Torrent::GetNextBlockToRequest (std::shared_ptr conn) + std::tuple Torrent::GetNextBlockToRequest (std::shared_ptr conn, bool skipRequested) { if (conn) { @@ -530,7 +530,7 @@ namespace torrents uint32_t ind = 0; for (auto& it: m_Pieces) { - if (!it.IsComplete () && conn->IsPieceAvailable (ind) && !it.IsRequested ()) + if (!it.IsComplete () && conn->IsPieceAvailable (ind) && (!skipRequested || !it.IsRequested ())) sortedByNumPeers.emplace (ind, it.GetNumPeers ()); ind++; } @@ -1279,21 +1279,34 @@ namespace torrents bool PeerConnection::RequestNextBlock () { if (!m_Torrent) return false; - auto [index, offset, len] = m_Torrent->GetNextBlockToRequest (shared_from_this ()); + auto [index, offset, len] = m_Torrent->GetNextBlockToRequest (shared_from_this (), true); // skip already requested pieces if (len > 0) + RequestNextBlock (index, offset, len); + else { - m_LastRequestedPieceIndex = index; - SendRequestMsg (index, offset, len); - m_NumRequests++; - } - else if (m_LastRequestedPieceIndex >= 0) - { - m_LastRequestedPieceIndex = -1; // no request - SendNotinterestedMsg (); + // try to get block from requested by another connection piece + auto [index1, offset1, len1] = m_Torrent->GetNextBlockToRequest (shared_from_this (), false); + if (len1 > 0) + { + len = len1; + RequestNextBlock (index1, offset1, len1); + } + else if (m_LastRequestedPieceIndex >= 0) + { + m_LastRequestedPieceIndex = -1; // no request + SendNotinterestedMsg (); + } } return len > 0; } + void PeerConnection::RequestNextBlock (uint32_t index, uint32_t offset, uint32_t len) + { + m_LastRequestedPieceIndex = index; + SendRequestMsg (index, offset, len); + m_NumRequests++; + } + void PeerConnection::RequestNextBlocks () { if (m_IsChoked || !m_Torrent || m_Torrent->IsComplete ()) return; diff --git a/libi2pd_client/Torrents.h b/libi2pd_client/Torrents.h index 0be21183..c9bf1e90 100644 --- a/libi2pd_client/Torrents.h +++ b/libi2pd_client/Torrents.h @@ -168,7 +168,7 @@ namespace torrents std::pair, bool> CreateBitfield () const; // (bitfield, empty) bool ApplyBitfield (const std::vector& bitfield); // return true if complete const std::unordered_set& GetPeers () const { return m_Peers; } - std::tuple GetNextBlockToRequest (std::shared_ptr conn); // return (index, offset, len) + std::tuple GetNextBlockToRequest (std::shared_ptr conn, bool skipRequested = true); // return (index, offset, len) std::vector GetPieceFileFragments (int index) const; bool UpdateStatus (uint64_t ts); // return true if complete @@ -265,6 +265,7 @@ namespace torrents void HandleChokeMsg (); bool RequestNextBlock (); + void RequestNextBlock (uint32_t index, uint32_t offset, uint32_t len); void RequestNextBlocks (); bool SendRequestedBlock (const RequestedBlock& requestedBlock);