Skip to content

Commit abde68f

Browse files
Fix ETA for match-all share limits
1 parent 8cded3c commit abde68f

4 files changed

Lines changed: 106 additions & 1 deletion

File tree

src/base/bittorrent/sharelimits.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,12 @@
2929

3030
#pragma once
3131

32+
#include <algorithm>
33+
3234
#include <QMetaEnum>
3335

36+
#include "base/types.h"
37+
3438
namespace BitTorrent
3539
{
3640
inline const qreal DEFAULT_RATIO_LIMIT = -2;
@@ -83,4 +87,28 @@ namespace BitTorrent
8387

8488
friend bool operator==(const ShareLimits &lhs, const ShareLimits &rhs) = default;
8589
};
90+
91+
inline qlonglong shareLimitsEta(const ShareLimits &shareLimits, const qlonglong ratioEta
92+
, const qlonglong seedingTimeEta, const qlonglong inactiveSeedingTimeEta)
93+
{
94+
const bool matchAll = (shareLimits.mode == ShareLimitsMode::MatchAll);
95+
qlonglong result = (matchAll ? 0 : MAX_ETA);
96+
bool hasLimit = false;
97+
98+
const auto applyEta = [&](const bool enabled, const qlonglong eta)
99+
{
100+
if (!enabled)
101+
return;
102+
103+
hasLimit = true;
104+
const qlonglong normalizedEta = std::max<qlonglong>(eta, 0);
105+
result = (matchAll ? std::max(result, normalizedEta) : std::min(result, normalizedEta));
106+
};
107+
108+
applyEta((shareLimits.ratioLimit >= 0), ratioEta);
109+
applyEta((shareLimits.seedingTimeLimit >= 0), seedingTimeEta);
110+
applyEta((shareLimits.inactiveSeedingTimeLimit >= 0), inactiveSeedingTimeEta);
111+
112+
return (hasLimit ? result : MAX_ETA);
113+
}
86114
}

src/base/bittorrent/torrentimpl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1422,7 +1422,7 @@ qlonglong TorrentImpl::eta() const
14221422
inactiveSeedingTimeEta = std::max<qlonglong>(inactiveSeedingTimeEta, 0);
14231423
}
14241424

1425-
return std::min({ratioEta, seedingTimeEta, inactiveSeedingTimeEta});
1425+
return shareLimitsEta(shareLimits, ratioEta, seedingTimeEta, inactiveSeedingTimeEta);
14261426
}
14271427

14281428
if (!speedAverage.download) return MAX_ETA;

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ include_directories("../src")
88
set(testFiles
99
testalgorithm.cpp
1010
testbittorrentpeeraddress.cpp
11+
testbittorrentsharelimits.cpp
1112
testbittorrenttrackerentry.cpp
1213
testconceptsexplicitlyconvertibleto.cpp
1314
testconceptsstringable.cpp

test/testbittorrentsharelimits.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Bittorrent Client using Qt and libtorrent.
3+
* Copyright (C) 2026 Andy Ye
4+
*
5+
* This program is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU General Public License
7+
* as published by the Free Software Foundation; either version 2
8+
* of the License, or (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18+
*
19+
* In addition, as a special exception, the copyright holders give permission to
20+
* link this program with the OpenSSL project's "OpenSSL" library (or with
21+
* modified versions of it that use the same license as the "OpenSSL" library),
22+
* and distribute the linked executables. You must obey the GNU General Public
23+
* License in all respects for all of the code used other than "OpenSSL". If you
24+
* modify file(s), you may extend this exception to your version of the file(s),
25+
* but you are not obligated to do so. If you do not wish to do so, delete this
26+
* exception statement from your version.
27+
*/
28+
29+
#include <QObject>
30+
#include <QTest>
31+
32+
#include "base/bittorrent/sharelimits.h"
33+
#include "base/types.h"
34+
35+
class TestBittorrentShareLimits final : public QObject
36+
{
37+
Q_OBJECT
38+
Q_DISABLE_COPY_MOVE(TestBittorrentShareLimits)
39+
40+
public:
41+
TestBittorrentShareLimits() = default;
42+
43+
private slots:
44+
void testShareLimitsEta() const
45+
{
46+
BitTorrent::ShareLimits shareLimits
47+
{
48+
.ratioLimit = 1.0,
49+
.seedingTimeLimit = 100,
50+
.inactiveSeedingTimeLimit = 200,
51+
.mode = BitTorrent::ShareLimitsMode::MatchAny
52+
};
53+
54+
QCOMPARE(BitTorrent::shareLimitsEta(shareLimits, 120, 300, 600), 120);
55+
56+
shareLimits.mode = BitTorrent::ShareLimitsMode::MatchAll;
57+
QCOMPARE(BitTorrent::shareLimitsEta(shareLimits, 120, 300, 600), 600);
58+
59+
shareLimits.ratioLimit = BitTorrent::NO_RATIO_LIMIT;
60+
QCOMPARE(BitTorrent::shareLimitsEta(shareLimits, 120, 300, 600), 600);
61+
62+
shareLimits.mode = BitTorrent::ShareLimitsMode::MatchAny;
63+
QCOMPARE(BitTorrent::shareLimitsEta(shareLimits, 120, 300, 600), 300);
64+
65+
shareLimits.ratioLimit = 1.0;
66+
QCOMPARE(BitTorrent::shareLimitsEta(shareLimits, -20, 300, 600), 0);
67+
68+
shareLimits.ratioLimit = BitTorrent::NO_RATIO_LIMIT;
69+
shareLimits.seedingTimeLimit = BitTorrent::NO_SEEDING_TIME_LIMIT;
70+
shareLimits.inactiveSeedingTimeLimit = BitTorrent::NO_SEEDING_TIME_LIMIT;
71+
QCOMPARE(BitTorrent::shareLimitsEta(shareLimits, 120, 300, 600), MAX_ETA);
72+
}
73+
};
74+
75+
QTEST_APPLESS_MAIN(TestBittorrentShareLimits)
76+
#include "testbittorrentsharelimits.moc"

0 commit comments

Comments
 (0)