*redesign of dwl queue - dwls will be enqueued and picked from there;

*changes to display the dwl queue in the transfers dialog 

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@1447 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
alexandrut 2009-07-28 10:21:19 +00:00
parent fdfc02a1c1
commit e68d874406
9 changed files with 201 additions and 142 deletions

View File

@ -35,34 +35,26 @@ void ftDwlQueue::run()
sleep(1); sleep(1);
#endif #endif
unsigned int sDwl = totalSystemDwl();
unsigned int qDwl = totalQueuedDwl();
unsigned int dwl = 0;
if (sDwl - qDwl >= 0) {
dwl = sDwl - qDwl; /* real downloads, not in the queue */
}
/* we have to know if the next download from /* we have to know if the next download from
* queue will exceed the download limit */ * the queue will exceed the download limit */
if (dwl + 1 > downloadLimit) continue;
unsigned int sDwl = totalSystemDwl();
if (sDwl + 1 > downloadLimit) continue;
/* now get the next dwl from the queue
* and request for it */
DwlDetails details; DwlDetails details;
if (!getNext(details)) continue; if (!getNext(details)) continue;
/* if the download was paused restart it
* else try a new request for download it */
if (details.paused == true) {
rsFiles->FileControl(details.hash, RS_FILE_CTRL_START);
} else {
if (!mFtController->FileRequest(details.fname, details.hash, details.count, details.dest, details.flags, details.srcIds)) { if (!mFtController->FileRequest(details.fname, details.hash, details.count, details.dest, details.flags, details.srcIds)) {
/* reque the download but with lower priority */
if (details.retries < retryLimit - 1) { if (details.retries < retryLimit - 1) {
details.retries ++; details.retries ++;
if (details.priority > 0) { if (details.priority > 0) {
details.priority = (DwlPriority) (details.priority - 1); details.priority = (DwlPriority) (details.priority - 1);
} }
details.paused = false;
prmtx.lock(); { prmtx.lock(); {
priorities.push_back(details); priorities.push_back(details);
@ -72,7 +64,6 @@ void ftDwlQueue::run()
} }
} }
} }
}
} }
void ftDwlQueue::insertDownload(const DwlDetails & details) { void ftDwlQueue::insertDownload(const DwlDetails & details) {
@ -94,6 +85,16 @@ void ftDwlQueue::insertDownload(const DwlDetails & details) {
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
/* if queue is empty and # of dwls does not
* exceed limit, start the download without
* putting it in the queue, else put it back
* in the queue */
unsigned int sDwl = totalSystemDwl();
RsStackMutex stack(prmtx);
if (priorities.empty() && (sDwl + 1 <= downloadLimit)) {
if (!mFtController->FileRequest(_details.fname, _details.hash, _details.count, _details.dest, _details.flags, _details.srcIds)) { if (!mFtController->FileRequest(_details.fname, _details.hash, _details.count, _details.dest, _details.flags, _details.srcIds)) {
/* reque the download but with lower priority */ /* reque the download but with lower priority */
@ -102,31 +103,15 @@ void ftDwlQueue::insertDownload(const DwlDetails & details) {
if (_details.priority > 0) { if (_details.priority > 0) {
_details.priority = (DwlPriority) (_details.priority - 1); _details.priority = (DwlPriority) (_details.priority - 1);
} }
_details.paused = false;
prmtx.lock(); {
priorities.push_back(_details); priorities.push_back(_details);
priorities.sort(PriorityCompare()); priorities.sort(PriorityCompare());
} }
prmtx.unlock();
} }
} else { } else {
/* continue a download only if queue is empty - no
* other paused dwls are waiting - and the number
* of downloads are not exceeding the limit, else
* stop it and put in queue */
unsigned int sDwl = totalSystemDwl();
RsStackMutex stack(prmtx);
if ((!priorities.empty()) || (sDwl > downloadLimit)) {
rsFiles->FileControl(_details.hash, RS_FILE_CTRL_PAUSE);
_details.paused = true;
priorities.push_back(_details); priorities.push_back(_details);
priorities.sort(PriorityCompare()); priorities.sort(PriorityCompare());
} }
}
} }
bool ftDwlQueue::getNext(DwlDetails & details) { bool ftDwlQueue::getNext(DwlDetails & details) {
@ -219,28 +204,27 @@ bool ftDwlQueue::clearDownload(const std::string hash) {
return false; return false;
} }
void ftDwlQueue::clearQueue() { void ftDwlQueue::getDwlDetails(std::list<DwlDetails> & details) {
#ifdef DEBUG_QUEUE
std::cerr << "ftDwlQueue::getDwlDetails()" << std::endl;
#endif
details.clear();
RsStackMutex stack(prmtx); RsStackMutex stack(prmtx);
std::list<DwlDetails>::iterator it;
for (it = priorities.begin(); it != priorities.end(); it ++) {
details.push_back(*it);
}
}
void ftDwlQueue::clearQueue() {
#ifdef DEBUG_QUEUE #ifdef DEBUG_QUEUE
std::cerr << "ftDwlQueue::clearQueue()" << std::endl; std::cerr << "ftDwlQueue::clearQueue()" << std::endl;
#endif #endif
priorities.clear();
}
unsigned int ftDwlQueue::totalQueuedDwl() {
RsStackMutex stack(prmtx); RsStackMutex stack(prmtx);
/* count only paused dwls from the queue */ priorities.clear();
int total = 0;
std::list<DwlDetails>::iterator it;
for (it = priorities.begin(); it != priorities.end(); it ++) {
if (it->paused) {
total ++;
}
}
return total;
} }
unsigned int ftDwlQueue::totalSystemDwl() { unsigned int ftDwlQueue::totalSystemDwl() {
@ -258,9 +242,7 @@ unsigned int ftDwlQueue::totalSystemDwl() {
if (!rsFiles->FileDetails(*it, flags, info)) continue; if (!rsFiles->FileDetails(*it, flags, info)) continue;
/* i'm not sure here what other types should be counted /* i'm not sure what other types should be counted here */
* but state waiting is very important here - dwls that
* are just requested but not in downloading state */
if (info.downloadStatus == FT_STATE_DOWNLOADING || info.downloadStatus == FT_STATE_WAITING) if (info.downloadStatus == FT_STATE_DOWNLOADING || info.downloadStatus == FT_STATE_WAITING)
totalDwl ++; totalDwl ++;
} }

View File

@ -14,32 +14,31 @@
#include <list> #include <list>
#include <string> #include <string>
enum DwlPriority { Low = 0, Normal, High, Auto }; //enum DwlPriority { Low = 0, Normal, High, Auto };
//
/* class which encapsulates download details */ ///* class which encapsulates download details */
class DwlDetails { //class DwlDetails {
public: //public:
DwlDetails() { return; } // DwlDetails() { return; }
DwlDetails(std::string fname, std::string hash, int count, std::string dest, // DwlDetails(std::string fname, std::string hash, int count, std::string dest,
uint32_t flags, std::list<std::string> srcIds, DwlPriority priority) // uint32_t flags, std::list<std::string> srcIds, DwlPriority priority)
: fname(fname), hash(hash), count(count), dest(dest), flags(flags), // : fname(fname), hash(hash), count(count), dest(dest), flags(flags),
srcIds(srcIds), retries(0), priority(priority), paused(false) { // srcIds(srcIds), priority(priority), retries(0) { return; }
return; //
} // /* download details */
// std::string fname;
/* download details */ // std::string hash;
std::string fname; // int count;
std::string hash; // std::string dest;
int count; // uint32_t flags;
std::string dest; // std::list<std::string> srcIds;
uint32_t flags; //
std::list<std::string> srcIds; // /* internally used in download queue */
unsigned int retries; // DwlPriority priority;
//
/* internally used in download queue */ // /* how many times a failed dwl will be requeued */
DwlPriority priority; // unsigned int retries;
bool paused; //};
};
/* comparator class used when sorting list */ /* comparator class used when sorting list */
class PriorityCompare { class PriorityCompare {
@ -89,6 +88,7 @@ public:
virtual bool getPriority(const std::string hash, DwlPriority & priority); virtual bool getPriority(const std::string hash, DwlPriority & priority);
virtual bool clearDownload(const std::string hash); virtual bool clearDownload(const std::string hash);
virtual void clearQueue(); virtual void clearQueue();
virtual void getDwlDetails(std::list<DwlDetails> & details);
private: private:
unsigned int downloadLimit; unsigned int downloadLimit;
@ -99,7 +99,6 @@ private:
RsMutex prmtx; RsMutex prmtx;
std::list<DwlDetails> priorities; std::list<DwlDetails> priorities;
unsigned int totalQueuedDwl();
unsigned int totalSystemDwl(); unsigned int totalSystemDwl();
}; };

View File

@ -290,6 +290,11 @@ void ftServer::clearQueue()
mFtDwlQueue->clearQueue(); mFtDwlQueue->clearQueue();
} }
void ftServer::getDwlDetails(std::list<DwlDetails> & details)
{
mFtDwlQueue->getDwlDetails(details);
}
/* Directory Handling */ /* Directory Handling */
void ftServer::setDownloadDirectory(std::string path) void ftServer::setDownloadDirectory(std::string path)
{ {

View File

@ -129,6 +129,7 @@ virtual bool changePriority(const std::string hash, int priority);
virtual bool getPriority(const std::string hash, int & priority); virtual bool getPriority(const std::string hash, int & priority);
virtual bool clearDownload(const std::string hash); virtual bool clearDownload(const std::string hash);
virtual void clearQueue(); virtual void clearQueue();
virtual void getDwlDetails(std::list<DwlDetails> & details);
/*** /***
* Download/Upload Details * Download/Upload Details

View File

@ -114,6 +114,7 @@ virtual bool changePriority(const std::string hash, int priority) = 0;
virtual bool getPriority(const std::string hash, int & priority) = 0; virtual bool getPriority(const std::string hash, int & priority) = 0;
virtual bool clearDownload(const std::string hash) = 0; virtual bool clearDownload(const std::string hash) = 0;
virtual void clearQueue() = 0; virtual void clearQueue() = 0;
virtual void getDwlDetails(std::list<DwlDetails> & details) = 0;
/*** /***
* Download / Upload Details. * Download / Upload Details.

View File

@ -243,7 +243,30 @@ class FileDetail
uint32_t rank; uint32_t rank;
}; };
enum DwlPriority { Low = 0, Normal, High, Auto };
/* class which encapsulates download details */
class DwlDetails {
public:
DwlDetails() { return; }
DwlDetails(std::string fname, std::string hash, int count, std::string dest,
uint32_t flags, std::list<std::string> srcIds, DwlPriority priority)
: fname(fname), hash(hash), count(count), dest(dest), flags(flags),
srcIds(srcIds), priority(priority), retries(0) { return; }
/* download details */
std::string fname;
std::string hash;
int count;
std::string dest;
uint32_t flags;
std::list<std::string> srcIds;
/* internally used in download queue */
DwlPriority priority;
/* how many times a failed dwl will be requeued */
unsigned int retries;
};
#endif #endif

View File

@ -40,6 +40,7 @@
#include "rsiface/rsfiles.h" #include "rsiface/rsfiles.h"
#include "rsiface/rspeers.h" #include "rsiface/rspeers.h"
#include "rsiface/rsdisc.h" #include "rsiface/rsdisc.h"
#include "rsiface/rstypes.h"
#include <algorithm> #include <algorithm>
#include "util/misc.h" #include "util/misc.h"
@ -648,34 +649,6 @@ void TransfersDialog::insertTransfers()
status = tr("Unknown"); break; status = tr("Unknown"); break;
} }
/* a paused download remains with Downloading status;
* check to see if download is in download queue to
* update his status properly */
int priority;
if (rsFiles->getPriority(*it, priority)) {
QString spriority;
switch (priority) {
case 0:
spriority = tr("Low");
break;
case 1:
spriority = tr("Normal");
break;
case 2:
spriority = tr("High");
break;
case 3:
spriority = tr("Auto");
break;
default:
spriority = tr("");
break;
}
status = tr("Queued [") + spriority + tr("]");
}
completed = info.transfered; completed = info.transfered;
remaining = (info.size - info.transfered) / (info.tfRate * 1024.0); remaining = (info.size - info.transfered) / (info.tfRate * 1024.0);
@ -751,6 +724,57 @@ void TransfersDialog::insertTransfers()
} }
} }
/* here i will insert files from the download queue - which are
* not started yet and can't be find in FileDownloads
* */
std::list<DwlDetails> details;
std::list<DwlDetails>::iterator dit;
rsFiles->getDwlDetails(details);
for (dit = details.begin(); dit != details.end(); dit ++)
{
name = QString::fromStdString(dit->fname);
coreId = QString::fromStdString(dit->hash);
fileSize = dit->count;
progress = 0;
dlspeed = 0;
sources = "";
completed = 0;
remaining = 0;
int priority = dit->priority;
QString spriority;
switch (dit->priority) {
case 0:
spriority = tr("Low");
break;
case 1:
spriority = tr("Normal");
break;
case 2:
spriority = tr("High");
break;
case 3:
spriority = tr("Auto");
break;
default:
spriority = tr("");
break;
}
status = tr("Queued [") + spriority + tr("]");
addItem("", name, coreId, fileSize, progress, dlspeed, sources, status, completed, remaining);
/* if found in selectedIds -> select again */
if (selectedIds.end() != std::find(selectedIds.begin(), selectedIds.end(), dit->hash)) {
selection->select(DLListModel->index(dlCount, 0),
QItemSelectionModel::Rows | QItemSelectionModel::SelectCurrent);
}
dlCount++;
}
for(it = upHashes.begin(); it != upHashes.end(); it++) for(it = upHashes.begin(); it != upHashes.end(); it++)
{ {

View File

@ -114,6 +114,7 @@ virtual bool changePriority(const std::string hash, int priority) = 0;
virtual bool getPriority(const std::string hash, int & priority) = 0; virtual bool getPriority(const std::string hash, int & priority) = 0;
virtual bool clearDownload(const std::string hash) = 0; virtual bool clearDownload(const std::string hash) = 0;
virtual void clearQueue() = 0; virtual void clearQueue() = 0;
virtual void getDwlDetails(std::list<DwlDetails> & details) = 0;
/*** /***
* Download / Upload Details. * Download / Upload Details.

View File

@ -242,7 +242,30 @@ class FileDetail
uint32_t rank; uint32_t rank;
}; };
enum DwlPriority { Low = 0, Normal, High, Auto };
/* class which encapsulates download details */
class DwlDetails {
public:
DwlDetails() { return; }
DwlDetails(std::string fname, std::string hash, int count, std::string dest,
uint32_t flags, std::list<std::string> srcIds, DwlPriority priority)
: fname(fname), hash(hash), count(count), dest(dest), flags(flags),
srcIds(srcIds), priority(priority), retries(0) { return; }
/* download details */
std::string fname;
std::string hash;
int count;
std::string dest;
uint32_t flags;
std::list<std::string> srcIds;
/* internally used in download queue */
DwlPriority priority;
/* how many times a failed dwl will be requeued */
unsigned int retries;
};
#endif #endif