*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,41 +35,32 @@ void ftDwlQueue::run()
sleep(1);
#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
* queue will exceed the download limit */
if (dwl + 1 > downloadLimit) continue;
* the queue will exceed the download limit */
unsigned int sDwl = totalSystemDwl();
if (sDwl + 1 > downloadLimit) continue;
/* now get the next dwl from the queue
* and request for it */
DwlDetails details;
if (!getNext(details)) continue;
/* if the download was paused restart it
* else try a new request for download it */
if (!mFtController->FileRequest(details.fname, details.hash, details.count, details.dest, details.flags, details.srcIds)) {
/* reque the download but with lower priority */
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 (details.retries < retryLimit - 1) {
details.retries ++;
if (details.priority > 0) {
details.priority = (DwlPriority) (details.priority - 1);
}
details.paused = false;
prmtx.lock(); {
priorities.push_back(details);
priorities.sort(PriorityCompare());
}
prmtx.unlock();
if (details.retries < retryLimit - 1) {
details.retries ++;
if (details.priority > 0) {
details.priority = (DwlPriority) (details.priority - 1);
}
prmtx.lock(); {
priorities.push_back(details);
priorities.sort(PriorityCompare());
}
prmtx.unlock();
}
}
}
@ -94,38 +85,32 @@ void ftDwlQueue::insertDownload(const DwlDetails & details) {
std::cerr << std::endl;
#endif
if (!mFtController->FileRequest(_details.fname, _details.hash, _details.count, _details.dest, _details.flags, _details.srcIds)) {
/* reque the download but with lower priority */
/* 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 */
if (_details.retries < (retryLimit - 1)) {
_details.retries ++;
if (_details.priority > 0) {
_details.priority = (DwlPriority) (_details.priority - 1);
}
_details.paused = false;
unsigned int sDwl = totalSystemDwl();
prmtx.lock(); {
priorities.push_back(_details);
priorities.sort(PriorityCompare());
RsStackMutex stack(prmtx);
if (priorities.empty() && (sDwl + 1 <= downloadLimit)) {
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)) {
_details.retries ++;
if (_details.priority > 0) {
_details.priority = (DwlPriority) (_details.priority - 1);
}
priorities.push_back(_details);
priorities.sort(PriorityCompare());
}
prmtx.unlock();
}
} 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.sort(PriorityCompare());
}
priorities.push_back(_details);
priorities.sort(PriorityCompare());
}
}
@ -219,28 +204,27 @@ bool ftDwlQueue::clearDownload(const std::string hash) {
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);
std::list<DwlDetails>::iterator it;
for (it = priorities.begin(); it != priorities.end(); it ++) {
details.push_back(*it);
}
}
void ftDwlQueue::clearQueue() {
#ifdef DEBUG_QUEUE
std::cerr << "ftDwlQueue::clearQueue()" << std::endl;
#endif
priorities.clear();
}
unsigned int ftDwlQueue::totalQueuedDwl() {
RsStackMutex stack(prmtx);
/* count only paused dwls from the queue */
int total = 0;
std::list<DwlDetails>::iterator it;
for (it = priorities.begin(); it != priorities.end(); it ++) {
if (it->paused) {
total ++;
}
}
return total;
priorities.clear();
}
unsigned int ftDwlQueue::totalSystemDwl() {
@ -258,9 +242,7 @@ unsigned int ftDwlQueue::totalSystemDwl() {
if (!rsFiles->FileDetails(*it, flags, info)) continue;
/* i'm not sure here what other types should be counted
* but state waiting is very important here - dwls that
* are just requested but not in downloading state */
/* i'm not sure what other types should be counted here */
if (info.downloadStatus == FT_STATE_DOWNLOADING || info.downloadStatus == FT_STATE_WAITING)
totalDwl ++;
}

View File

@ -14,32 +14,31 @@
#include <list>
#include <string>
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), retries(0), priority(priority), paused(false) {
return;
}
/* download details */
std::string fname;
std::string hash;
int count;
std::string dest;
uint32_t flags;
std::list<std::string> srcIds;
unsigned int retries;
/* internally used in download queue */
DwlPriority priority;
bool paused;
};
//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;
//};
/* comparator class used when sorting list */
class PriorityCompare {
@ -89,6 +88,7 @@ public:
virtual bool getPriority(const std::string hash, DwlPriority & priority);
virtual bool clearDownload(const std::string hash);
virtual void clearQueue();
virtual void getDwlDetails(std::list<DwlDetails> & details);
private:
unsigned int downloadLimit;
@ -99,7 +99,6 @@ private:
RsMutex prmtx;
std::list<DwlDetails> priorities;
unsigned int totalQueuedDwl();
unsigned int totalSystemDwl();
};

View File

@ -290,6 +290,11 @@ void ftServer::clearQueue()
mFtDwlQueue->clearQueue();
}
void ftServer::getDwlDetails(std::list<DwlDetails> & details)
{
mFtDwlQueue->getDwlDetails(details);
}
/* Directory Handling */
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 clearDownload(const std::string hash);
virtual void clearQueue();
virtual void getDwlDetails(std::list<DwlDetails> & 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 clearDownload(const std::string hash) = 0;
virtual void clearQueue() = 0;
virtual void getDwlDetails(std::list<DwlDetails> & details) = 0;
/***
* Download / Upload Details.

View File

@ -33,9 +33,9 @@
#include <stdint.h>
typedef std::string RsCertId;
typedef std::string RsChanId;
typedef std::string RsMsgId;
typedef std::string RsAuthId;
typedef std::string RsChanId;
typedef std::string RsMsgId;
typedef std::string RsAuthId;
const uint32_t FT_STATE_FAILED = 0x0000;
const uint32_t FT_STATE_OKAY = 0x0001;
@ -82,7 +82,7 @@ static const int kRsFiStatusDone = 2;
std::string hash;
std::string ext;
uint64_t size;
uint64_t size;
uint64_t avail; /* how much we have */
int status;
@ -177,7 +177,7 @@ class Condition
class SearchRequest
{
public:
int searchId;
int searchId;
RsCertId toId; /* all zeros for everyone! */
std::list<Condition> tests;
};
@ -243,7 +243,30 @@ class FileDetail
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

View File

@ -40,6 +40,7 @@
#include "rsiface/rsfiles.h"
#include "rsiface/rspeers.h"
#include "rsiface/rsdisc.h"
#include "rsiface/rstypes.h"
#include <algorithm>
#include "util/misc.h"
@ -648,34 +649,6 @@ void TransfersDialog::insertTransfers()
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;
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++)
{

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 clearDownload(const std::string hash) = 0;
virtual void clearQueue() = 0;
virtual void getDwlDetails(std::list<DwlDetails> & details) = 0;
/***
* Download / Upload Details.

View File

@ -33,9 +33,9 @@
#include <stdint.h>
typedef std::string RsCertId;
typedef std::string RsChanId;
typedef std::string RsMsgId;
typedef std::string RsAuthId;
typedef std::string RsChanId;
typedef std::string RsMsgId;
typedef std::string RsAuthId;
const uint32_t FT_STATE_FAILED = 0x0000;
const uint32_t FT_STATE_OKAY = 0x0001;
@ -82,7 +82,7 @@ static const int kRsFiStatusDone = 2;
std::string hash;
std::string ext;
uint64_t size;
uint64_t size;
uint64_t avail; /* how much we have */
int status;
@ -176,7 +176,7 @@ class Condition
class SearchRequest
{
public:
int searchId;
int searchId;
RsCertId toId; /* all zeros for everyone! */
std::list<Condition> tests;
};
@ -242,7 +242,30 @@ class FileDetail
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