diff --git a/libretroshare/src/ft/ftcontroller.cc b/libretroshare/src/ft/ftcontroller.cc index 964ed2114..cca4f16cb 100644 --- a/libretroshare/src/ft/ftcontroller.cc +++ b/libretroshare/src/ft/ftcontroller.cc @@ -104,6 +104,7 @@ ftController::ftController(CacheStrapper *cs, ftDataMultiplex *dm, std::string / mDefaultChunkStrategy(FileChunksInfo::CHUNK_STRATEGY_RANDOM) { _max_active_downloads = 5 ; // default queue size + _min_prioritized_transfers = 3 ; /* TODO */ } @@ -228,7 +229,7 @@ void ftController::run() } time_t now = time(NULL) ; - if((int)now - (int)last_save_time > (int)SAVE_TRANSFERS_DELAY) + if(now > last_save_time + SAVE_TRANSFERS_DELAY) { cleanCacheDownloads() ; @@ -236,7 +237,7 @@ void ftController::run() last_save_time = now ; } - if((int)now - (int)last_clean_time > (int)INACTIVE_CHUNKS_CHECK_DELAY) + if(now > last_clean_time + INACTIVE_CHUNKS_CHECK_DELAY) { RsStackMutex stack(ctrlMutex); /******* LOCKED ********/ @@ -416,6 +417,37 @@ void ftController::checkDownloadQueue() it->second->mCreator->resetRecvTimeStamp() ; // very important! ++nb_moved ; } + + // Check that at least _min_prioritized_transfers are assigned to non cache transfers + + std::cerr << "Asserting that at least " << _min_prioritized_transfers << " are dedicated to user transfers." << std::endl; + + int user_transfers = 0 ; + std::vector to_move_before ; + std::vector to_move_after ; + + for(uint32_t p=0;p<_queue.size();++p) + { + if(p < _min_prioritized_transfers) + if(_queue[p]->mFlags & RS_FILE_HINTS_CACHE) // cache file. add to potential move list + to_move_before.push_back(p) ; + else + ++user_transfers ; // count one more user file in the prioritized range. + else + { + if(to_move_after.size() + user_transfers >= _min_prioritized_transfers) // we caught enough transfers to move back to the top of the queue. + break ; + + if(!(_queue[p]->mFlags & RS_FILE_HINTS_CACHE)) // non cache file. add to potential move list + to_move_after.push_back(p) ; + } + } + uint32_t to_move = (uint32_t)std::max(0,(int)_min_prioritized_transfers - (int)user_transfers) ; // we move as many transfers as needed to get _min_prioritized_transfers user transfers. + + std::cerr << " collected " << to_move << " transfers to move." << std::endl; + + for(uint32_t i=0;imFlags & RS_FILE_HINTS_CACHE)>0) + while(pos < _queue.size() && (pos < _min_prioritized_transfers || (_queue[pos]->mFlags & RS_FILE_HINTS_CACHE)>0) ) ++pos ; _queue.push_back(NULL) ; @@ -462,6 +498,18 @@ void ftController::locked_queueRemove(uint32_t pos) _queue.pop_back(); } +void ftController::setMinPrioritizedTransfers(uint32_t s) +{ + RsStackMutex mtx(ctrlMutex) ; + _min_prioritized_transfers = s ; +} +uint32_t ftController::getMinPrioritizedTransfers() +{ + RsStackMutex mtx(ctrlMutex) ; + return _min_prioritized_transfers ; +} + + void ftController::setQueueSize(uint32_t s) { RsStackMutex mtx(ctrlMutex) ; @@ -1829,6 +1877,7 @@ bool ftController::CancelCacheFile(RsPeerId id, std::string path, std::string ha } const std::string active_downloads_size_ss("MAX_ACTIVE_DOWNLOADS"); +const std::string min_prioritized_downl_ss("MIN_PRORITIZED_DOWNLOADS"); const std::string download_dir_ss("DOWN_DIR"); const std::string partial_dir_ss("PART_DIR"); const std::string default_chunk_strategy_ss("DEFAULT_CHUNK_STRATEGY"); @@ -1860,6 +1909,9 @@ bool ftController::saveList(bool &cleanup, std::list& saveData) std::list::iterator it; /* basic control parameters */ + std::ostringstream strn ; + strn << getMinPrioritizedTransfers() ; + configMap[min_prioritized_downl_ss] = strn.str() ; std::ostringstream strm ; strm << getQueueSize() ; configMap[active_downloads_size_ss] = strm.str() ; @@ -2052,7 +2104,14 @@ bool ftController::loadConfigMap(std::map &configMap) std::cerr << "Note: loading active max downloads: " << n << std::endl; setQueueSize(n); } - + if (configMap.end() != (mit = configMap.find(min_prioritized_downl_ss))) + { + std::istringstream i(mit->second) ; + int n=3 ; + i >> n ; + std::cerr << "Note: loading min prioritized downloads: " << n << std::endl; + setMinPrioritizedTransfers(n); + } if (configMap.end() != (mit = configMap.find(partial_dir_ss))) { setPartialsDirectory(mit->second); diff --git a/libretroshare/src/ft/ftcontroller.h b/libretroshare/src/ft/ftcontroller.h index d7c0aaceb..e8e05e334 100644 --- a/libretroshare/src/ft/ftcontroller.h +++ b/libretroshare/src/ft/ftcontroller.h @@ -157,6 +157,8 @@ class ftController: public CacheTransfer, public RsThread, public pqiMonitor, pu void clearQueue() ; void setQueueSize(uint32_t size) ; uint32_t getQueueSize() ; + void setMinPrioritizedTransfers(uint32_t size) ; + uint32_t getMinPrioritizedTransfers() ; /* get Details of File Transfers */ bool FileDownloads(std::list &hashs); @@ -255,6 +257,7 @@ class ftController: public CacheTransfer, public RsThread, public pqiMonitor, pu FileChunksInfo::ChunkStrategy mDefaultChunkStrategy ; uint32_t _max_active_downloads ; // maximum number of simultaneous downloads + uint32_t _min_prioritized_transfers ; // min number of non cache transfers in the top of the queue. }; #endif diff --git a/libretroshare/src/ft/ftserver.cc b/libretroshare/src/ft/ftserver.cc index a0e95f34d..c15f48d7b 100644 --- a/libretroshare/src/ft/ftserver.cc +++ b/libretroshare/src/ft/ftserver.cc @@ -332,7 +332,14 @@ bool ftServer::FileClearCompleted() { return mFtController->FileClearCompleted(); } - +void ftServer::setMinPrioritizedTransfers(uint32_t s) +{ + mFtController->setMinPrioritizedTransfers(s) ; +} +uint32_t ftServer::getMinPrioritizedTransfers() +{ + return mFtController->getMinPrioritizedTransfers() ; +} void ftServer::setQueueSize(uint32_t s) { mFtController->setQueueSize(s) ; diff --git a/libretroshare/src/ft/ftserver.h b/libretroshare/src/ft/ftserver.h index 795c10b7a..6275f0767 100644 --- a/libretroshare/src/ft/ftserver.h +++ b/libretroshare/src/ft/ftserver.h @@ -139,6 +139,8 @@ virtual void setFreeDiskSpaceLimit(uint32_t size_in_mb) ; /*** * Control of Downloads Priority. ***/ +virtual uint32_t getMinPrioritizedTransfers() ; +virtual void setMinPrioritizedTransfers(uint32_t s) ; virtual uint32_t getQueueSize() ; virtual void setQueueSize(uint32_t s) ; virtual bool changeQueuePosition(const std::string hash, QueueMove queue_mv); diff --git a/libretroshare/src/retroshare/rsfiles.h b/libretroshare/src/retroshare/rsfiles.h index 9f3a7e362..5d18098ab 100644 --- a/libretroshare/src/retroshare/rsfiles.h +++ b/libretroshare/src/retroshare/rsfiles.h @@ -122,6 +122,8 @@ class RsFiles /*** * Control of Downloads Priority. ***/ + virtual uint32_t getMinPrioritizedTransfers() = 0 ; + virtual void setMinPrioritizedTransfers(uint32_t s) = 0 ; virtual uint32_t getQueueSize() = 0 ; virtual void setQueueSize(uint32_t s) = 0 ; virtual bool changeQueuePosition(const std::string hash, QueueMove mv) = 0; diff --git a/retroshare-gui/src/gui/settings/TransferPage.cpp b/retroshare-gui/src/gui/settings/TransferPage.cpp index c799f1849..6ee9be6cf 100644 --- a/retroshare-gui/src/gui/settings/TransferPage.cpp +++ b/retroshare-gui/src/gui/settings/TransferPage.cpp @@ -39,6 +39,7 @@ TransferPage::TransferPage(QWidget * parent, Qt::WFlags flags) ui.setupUi(this); ui._queueSize_SB->setValue(rsFiles->getQueueSize()) ; + ui._minPrioritized_SB->setValue(rsFiles->getMinPrioritizedTransfers()) ; if(rsFiles->defaultChunkStrategy() == FileChunksInfo::CHUNK_STRATEGY_STREAMING) ui._defaultStrategy_CB->setCurrentIndex(0) ; @@ -48,6 +49,7 @@ TransferPage::TransferPage(QWidget * parent, Qt::WFlags flags) ui._diskSpaceLimit_SB->setValue(rsFiles->freeDiskSpaceLimit()) ; QObject::connect(ui._queueSize_SB,SIGNAL(valueChanged(int)),this,SLOT(updateQueueSize(int))) ; + QObject::connect(ui._minPrioritized_SB,SIGNAL(valueChanged(int)),this,SLOT(updateMinPrioritized(int))) ; QObject::connect(ui._defaultStrategy_CB,SIGNAL(activated(int)),this,SLOT(updateDefaultStrategy(int))) ; QObject::connect(ui._diskSpaceLimit_SB,SIGNAL(valueChanged(int)),this,SLOT(updateDiskSizeLimit(int))) ; @@ -76,7 +78,15 @@ void TransferPage::updateDiskSizeLimit(int s) rsFiles->setFreeDiskSpaceLimit(s) ; } +void TransferPage::updateMinPrioritized(int s) +{ + rsFiles->setMinPrioritizedTransfers(s) ; +} void TransferPage::updateQueueSize(int s) { + if(ui._minPrioritized_SB->value() > s) + { + ui._minPrioritized_SB->setValue(s) ; + } rsFiles->setQueueSize(s) ; } diff --git a/retroshare-gui/src/gui/settings/TransferPage.h b/retroshare-gui/src/gui/settings/TransferPage.h index d4604b03e..49aa2de95 100644 --- a/retroshare-gui/src/gui/settings/TransferPage.h +++ b/retroshare-gui/src/gui/settings/TransferPage.h @@ -42,6 +42,7 @@ class TransferPage: public ConfigPage public slots: void updateQueueSize(int) ; + void updateMinPrioritized(int) ; void updateDefaultStrategy(int) ; void updateDiskSizeLimit(int) ; diff --git a/retroshare-gui/src/gui/settings/TransferPage.ui b/retroshare-gui/src/gui/settings/TransferPage.ui index 2985ba18f..6d3c505c6 100644 --- a/retroshare-gui/src/gui/settings/TransferPage.ui +++ b/retroshare-gui/src/gui/settings/TransferPage.ui @@ -28,6 +28,13 @@ + + + + Slots reserved for non-cache transfers: + + + @@ -62,6 +69,24 @@ + + + + You can use this to force RetroShare to download your files rather +than cache files for as many slots as requested. Setting that number +to be equal to the queue size above will always prioritize your files +over cache. + +It is however recommended to leave at least a few slots for cache files. + + + 1 + + + 3 + + +