mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-22 04:24:23 +00:00
- ETA calculation now relies on average speed over all sessions
- New ETA calculation system saves memory - Updated Changelog
This commit is contained in:
parent
9b67807926
commit
e5b6a5605a
@ -2,6 +2,10 @@
|
|||||||
- FEATURE: Based on libtorrent-rasterbar v0.14
|
- FEATURE: Based on libtorrent-rasterbar v0.14
|
||||||
- FEATURE: Improved ratio calculation system
|
- FEATURE: Improved ratio calculation system
|
||||||
- FEATURE: Torrent creation code cleanup
|
- FEATURE: Torrent creation code cleanup
|
||||||
|
- FEATURE: Allow to set maximum number of active seeds (queueing)
|
||||||
|
- FEATURE: Now seeds priorities are handled automatically by libtorrent-rasterbar (queueing)
|
||||||
|
- FEATURE: Code cleanup and optimization (save memory and cpu)
|
||||||
|
- FEATURE: ETA calculation now relies on average speed over all sessions
|
||||||
|
|
||||||
* Unknown - Christophe Dumez <chris@qbittorrent.org> - v1.2.1
|
* Unknown - Christophe Dumez <chris@qbittorrent.org> - v1.2.1
|
||||||
- BUGFIX: Fixed possible crash when deleting a torrent permanently
|
- BUGFIX: Fixed possible crash when deleting a torrent permanently
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
#define MAX_TRACKER_ERRORS 2
|
#define MAX_TRACKER_ERRORS 2
|
||||||
|
|
||||||
// Main constructor
|
// Main constructor
|
||||||
bittorrent::bittorrent() : timerScan(0), DHTEnabled(false), preAllocateAll(false), addInPause(false), maxConnecsPerTorrent(500), maxUploadsPerTorrent(4), max_ratio(-1), UPnPEnabled(false), NATPMPEnabled(false), LSDEnabled(false), folderScanInterval(5), queueingEnabled(false), calculateETA(true) {
|
bittorrent::bittorrent() : timerScan(0), DHTEnabled(false), preAllocateAll(false), addInPause(false), maxConnecsPerTorrent(500), maxUploadsPerTorrent(4), max_ratio(-1), UPnPEnabled(false), NATPMPEnabled(false), LSDEnabled(false), folderScanInterval(5), queueingEnabled(false) {
|
||||||
// To avoid some exceptions
|
// To avoid some exceptions
|
||||||
fs::path::default_name_check(fs::no_check);
|
fs::path::default_name_check(fs::no_check);
|
||||||
// Creating bittorrent session
|
// Creating bittorrent session
|
||||||
@ -128,24 +128,6 @@ void bittorrent::deleteBigRatios() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bittorrent::setETACalculation(bool enable) {
|
|
||||||
if(calculateETA != enable) {
|
|
||||||
calculateETA = enable;
|
|
||||||
if(calculateETA) {
|
|
||||||
foreach(QString hash, unfinishedTorrents) {
|
|
||||||
QTorrentHandle h = getTorrentHandle(hash);
|
|
||||||
if(!h.is_paused()) {
|
|
||||||
TorrentsStartData[hash] = h.total_payload_download();
|
|
||||||
TorrentsStartTime[hash] = QDateTime::currentDateTime();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
TorrentsStartData.clear();
|
|
||||||
TorrentsStartTime.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void bittorrent::setDownloadLimit(QString hash, long val) {
|
void bittorrent::setDownloadLimit(QString hash, long val) {
|
||||||
QTorrentHandle h = getTorrentHandle(hash);
|
QTorrentHandle h = getTorrentHandle(hash);
|
||||||
if(h.is_valid())
|
if(h.is_valid())
|
||||||
@ -201,7 +183,6 @@ void bittorrent::setQueueingEnabled(bool enable) {
|
|||||||
int bittorrent::getDlTorrentPriority(QString hash) const {
|
int bittorrent::getDlTorrentPriority(QString hash) const {
|
||||||
Q_ASSERT(queueingEnabled);
|
Q_ASSERT(queueingEnabled);
|
||||||
QTorrentHandle h = getTorrentHandle(hash);
|
QTorrentHandle h = getTorrentHandle(hash);
|
||||||
qDebug("Priority for %s is %d", h.name().toUtf8().data(), h.queue_position());
|
|
||||||
return h.queue_position();
|
return h.queue_position();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,31 +195,18 @@ int bittorrent::getUpTorrentPriority(QString hash) const {
|
|||||||
// Calculate the ETA using GASA
|
// Calculate the ETA using GASA
|
||||||
// GASA: global Average Speed Algorithm
|
// GASA: global Average Speed Algorithm
|
||||||
qlonglong bittorrent::getETA(QString hash) const {
|
qlonglong bittorrent::getETA(QString hash) const {
|
||||||
Q_ASSERT(calculateETA);
|
QTorrentHandle h = getTorrentHandle(hash);
|
||||||
QTorrentHandle h = getTorrentHandle(hash);
|
if(!h.is_valid()) return -1;
|
||||||
if(!h.is_valid()) return -1;
|
switch(h.state()) {
|
||||||
switch(h.state()) {
|
|
||||||
case torrent_status::downloading: {
|
case torrent_status::downloading: {
|
||||||
if(!TorrentsStartTime.contains(hash)) return -1;
|
if(h.active_time() == 0)
|
||||||
int timeElapsed = TorrentsStartTime.value(hash).secsTo(QDateTime::currentDateTime());
|
return -1;
|
||||||
double avg_speed;
|
double avg_speed = (double)h.all_time_download() / h.active_time();
|
||||||
if(timeElapsed) {
|
return (qlonglong) floor((double) (h.actual_size() - h.total_wanted_done()) / avg_speed);
|
||||||
size_type data_origin = TorrentsStartData.value(hash, 0);
|
}
|
||||||
avg_speed = (double)(h.total_payload_download()-data_origin) / (double)timeElapsed;
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if(avg_speed) {
|
|
||||||
return (qlonglong) floor((double) (h.actual_size() - h.total_wanted_done()) / avg_speed);
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the torrent handle, given its hash
|
// Return the torrent handle, given its hash
|
||||||
@ -302,11 +270,6 @@ void bittorrent::deleteTorrent(QString hash, bool permanent) {
|
|||||||
foreach(file, files) {
|
foreach(file, files) {
|
||||||
torrentBackup.remove(file);
|
torrentBackup.remove(file);
|
||||||
}
|
}
|
||||||
// Remove it from TorrentsStartTime hash table
|
|
||||||
if(calculateETA) {
|
|
||||||
TorrentsStartTime.remove(hash);
|
|
||||||
TorrentsStartData.remove(hash);
|
|
||||||
}
|
|
||||||
// Remove tracker errors
|
// Remove tracker errors
|
||||||
trackersErrors.remove(hash);
|
trackersErrors.remove(hash);
|
||||||
int index = finishedTorrents.indexOf(hash);
|
int index = finishedTorrents.indexOf(hash);
|
||||||
@ -352,10 +315,6 @@ void bittorrent::setUnfinishedTorrent(QString hash) {
|
|||||||
if(!unfinishedTorrents.contains(hash)) {
|
if(!unfinishedTorrents.contains(hash)) {
|
||||||
unfinishedTorrents << hash;
|
unfinishedTorrents << hash;
|
||||||
QTorrentHandle h = getTorrentHandle(hash);
|
QTorrentHandle h = getTorrentHandle(hash);
|
||||||
if(calculateETA) {
|
|
||||||
TorrentsStartData[hash] = h.total_payload_download();
|
|
||||||
TorrentsStartTime[hash] = QDateTime::currentDateTime();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//emit torrentSwitchedtoUnfinished(hash);
|
//emit torrentSwitchedtoUnfinished(hash);
|
||||||
}
|
}
|
||||||
@ -374,11 +333,6 @@ void bittorrent::setFinishedTorrent(QString hash) {
|
|||||||
if(index != -1) {
|
if(index != -1) {
|
||||||
unfinishedTorrents.removeAt(index);
|
unfinishedTorrents.removeAt(index);
|
||||||
}
|
}
|
||||||
// Remove it from TorrentsStartTime hash table
|
|
||||||
if(calculateETA) {
|
|
||||||
TorrentsStartTime.remove(hash);
|
|
||||||
TorrentsStartData.remove(hash);
|
|
||||||
}
|
|
||||||
//emit torrentSwitchedtoFinished(hash);
|
//emit torrentSwitchedtoFinished(hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,11 +359,6 @@ bool bittorrent::pauseTorrent(QString hash) {
|
|||||||
paused_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
paused_file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||||
paused_file.write(QByteArray::number((double)h.progress()));
|
paused_file.write(QByteArray::number((double)h.progress()));
|
||||||
paused_file.close();
|
paused_file.close();
|
||||||
// Remove it from TorrentsStartTime hash table
|
|
||||||
if(calculateETA) {
|
|
||||||
TorrentsStartTime.remove(hash);
|
|
||||||
TorrentsStartData.remove(hash);
|
|
||||||
}
|
|
||||||
if(change) {
|
if(change) {
|
||||||
addConsoleMessage(tr("'%1' paused.", "e.g: xxx.avi paused.").arg(h.name()));
|
addConsoleMessage(tr("'%1' paused.", "e.g: xxx.avi paused.").arg(h.name()));
|
||||||
}
|
}
|
||||||
@ -421,11 +370,6 @@ bool bittorrent::resumeTorrent(QString hash) {
|
|||||||
bool change = false;
|
bool change = false;
|
||||||
QTorrentHandle h = getTorrentHandle(hash);
|
QTorrentHandle h = getTorrentHandle(hash);
|
||||||
if(h.is_valid() && h.is_paused()) {
|
if(h.is_valid() && h.is_paused()) {
|
||||||
// Save Addition DateTime
|
|
||||||
if(calculateETA) {
|
|
||||||
TorrentsStartData[hash] = h.total_payload_download();
|
|
||||||
TorrentsStartTime[hash] = QDateTime::currentDateTime();
|
|
||||||
}
|
|
||||||
h.resume();
|
h.resume();
|
||||||
change = true;
|
change = true;
|
||||||
emit resumedTorrent(hash);
|
emit resumedTorrent(hash);
|
||||||
@ -1325,13 +1269,6 @@ void bittorrent::readAlerts() {
|
|||||||
if(h.is_valid()){
|
if(h.is_valid()){
|
||||||
QString hash = h.hash();
|
QString hash = h.hash();
|
||||||
qDebug("%s have just finished checking", hash.toUtf8().data());
|
qDebug("%s have just finished checking", hash.toUtf8().data());
|
||||||
if(!h.is_paused()) {
|
|
||||||
// Save Addition DateTime
|
|
||||||
if(calculateETA) {
|
|
||||||
TorrentsStartTime[hash] = QDateTime::currentDateTime();
|
|
||||||
TorrentsStartData[hash] = h.total_payload_download();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emit torrentFinishedChecking(hash);
|
emit torrentFinishedChecking(hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,8 +54,6 @@ class bittorrent : public QObject {
|
|||||||
bool DHTEnabled;
|
bool DHTEnabled;
|
||||||
downloadThread *downloader;
|
downloadThread *downloader;
|
||||||
QString defaultSavePath;
|
QString defaultSavePath;
|
||||||
QHash<QString, QDateTime> TorrentsStartTime;
|
|
||||||
QHash<QString, size_type> TorrentsStartData;
|
|
||||||
QHash<QString, QHash<QString, QString> > trackersErrors;
|
QHash<QString, QHash<QString, QString> > trackersErrors;
|
||||||
QStringList consoleMessages;
|
QStringList consoleMessages;
|
||||||
QStringList peerBanMessages;
|
QStringList peerBanMessages;
|
||||||
@ -74,7 +72,6 @@ class bittorrent : public QObject {
|
|||||||
QString filterPath;
|
QString filterPath;
|
||||||
int folderScanInterval; // in seconds
|
int folderScanInterval; // in seconds
|
||||||
bool queueingEnabled;
|
bool queueingEnabled;
|
||||||
bool calculateETA;
|
|
||||||
QStringList url_skippingDlg;
|
QStringList url_skippingDlg;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -92,7 +89,6 @@ class bittorrent : public QObject {
|
|||||||
float getPayloadUploadRate() const;
|
float getPayloadUploadRate() const;
|
||||||
session_status getSessionStatus() const;
|
session_status getSessionStatus() const;
|
||||||
int getListenPort() const;
|
int getListenPort() const;
|
||||||
qlonglong getETA(QString hash) const;
|
|
||||||
float getRealRatio(QString hash) const;
|
float getRealRatio(QString hash) const;
|
||||||
session* getSession() const;
|
session* getSession() const;
|
||||||
QHash<QString, QString> getTrackersErrors(QString hash) const;
|
QHash<QString, QString> getTrackersErrors(QString hash) const;
|
||||||
@ -113,6 +109,7 @@ class bittorrent : public QObject {
|
|||||||
QStringList getConsoleMessages() const;
|
QStringList getConsoleMessages() const;
|
||||||
QStringList getPeerBanMessages() const;
|
QStringList getPeerBanMessages() const;
|
||||||
float getUncheckedTorrentProgress(QString hash) const;
|
float getUncheckedTorrentProgress(QString hash) const;
|
||||||
|
qlonglong getETA(QString hash) const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false);
|
void addTorrent(QString path, bool fromScanDir = false, QString from_url = QString(), bool resumed = false);
|
||||||
@ -166,7 +163,6 @@ class bittorrent : public QObject {
|
|||||||
void enableLSD(bool b);
|
void enableLSD(bool b);
|
||||||
bool enableDHT(bool b);
|
bool enableDHT(bool b);
|
||||||
void setTimerScanInterval(int secs);
|
void setTimerScanInterval(int secs);
|
||||||
void setETACalculation(bool enable);
|
|
||||||
void addConsoleMessage(QString msg, QColor color=QApplication::palette().color(QPalette::WindowText));
|
void addConsoleMessage(QString msg, QColor color=QApplication::palette().color(QPalette::WindowText));
|
||||||
void addPeerBanMessage(QString msg, bool from_ipfilter);
|
void addPeerBanMessage(QString msg, bool from_ipfilter);
|
||||||
|
|
||||||
|
@ -318,19 +318,11 @@ void DownloadingTorrents::hideOrShowColumn(int index) {
|
|||||||
downloadList->setColumnHidden(index, true);
|
downloadList->setColumnHidden(index, true);
|
||||||
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
|
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_cancel.png")));
|
||||||
--nbVisibleColumns;
|
--nbVisibleColumns;
|
||||||
if(index == ETA) {
|
|
||||||
BTSession->setETACalculation(false);
|
|
||||||
qDebug("Disable ETA calculation");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// User want to display the column
|
// User want to display the column
|
||||||
downloadList->setColumnHidden(index, false);
|
downloadList->setColumnHidden(index, false);
|
||||||
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
|
getActionHoSCol(index)->setIcon(QIcon(QString::fromUtf8(":/Icons/button_ok.png")));
|
||||||
++nbVisibleColumns;
|
++nbVisibleColumns;
|
||||||
if(index == ETA) {
|
|
||||||
BTSession->setETACalculation(true);
|
|
||||||
qDebug("Enable ETA calculation");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//resize all others non-hidden columns
|
//resize all others non-hidden columns
|
||||||
for(unsigned int i=0; i<nbCols; ++i) {
|
for(unsigned int i=0; i<nbCols; ++i) {
|
||||||
|
@ -291,6 +291,11 @@ bool QTorrentHandle::is_auto_managed() const {
|
|||||||
return h.is_auto_managed();
|
return h.is_auto_managed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int QTorrentHandle::active_time() const {
|
||||||
|
Q_ASSERT(h.is_valid());
|
||||||
|
return h.status().active_time;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Setters
|
// Setters
|
||||||
//
|
//
|
||||||
|
@ -95,6 +95,7 @@ class QTorrentHandle {
|
|||||||
int num_uploads() const;
|
int num_uploads() const;
|
||||||
bool is_seed() const;
|
bool is_seed() const;
|
||||||
bool is_auto_managed() const;
|
bool is_auto_managed() const;
|
||||||
|
int active_time() const;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Setters
|
// Setters
|
||||||
|
Loading…
x
Reference in New Issue
Block a user