2018-05-28 22:03:39 +02:00
/*******************************************************************************
* libretroshare / src / pqi : pqihandler . cc *
* *
* libretroshare : retroshare core library *
* *
* Copyright ( C ) 2004 - 2006 Robert Fernie *
* *
* This program is free software : you can redistribute it and / or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation , either version 3 of the *
* License , or ( at your option ) any later version . *
* *
* This program is distributed in the hope that it will be useful , *
* but WITHOUT ANY WARRANTY ; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the *
* GNU Lesser General Public License for more details . *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program . If not , see < https : //www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-11-15 03:18:48 +00:00
# include "pqi/pqihandler.h"
2016-08-25 11:33:11 +02:00
# include <stdlib.h> // for NULL
2018-10-07 01:34:05 +02:00
# include "util/rstime.h" // for time, rstime_t
2016-08-25 11:33:11 +02:00
# include <algorithm> // for sort
# include <iostream> // for dec
# include <string> // for string, char_traits, operator+, bas...
# include <utility> // for pair
# include "pqi/pqi_base.h" // for PQInterface, RsBwRates
# include "retroshare/rsconfig.h" // for RSTrafficClue
# include "retroshare/rsids.h" // for t_RsGenericIdType
# include "retroshare/rspeers.h" // for RsPeers, rsPeers
# include "serialiser/rsserial.h" // for RsItem, RsRawItem
# include "util/rsdebug.h" // for pqioutput, PQL_DEBUG_BASIC, PQL_ALERT
# include "util/rsstring.h" // for rs_sprintf_append
2015-12-23 15:49:05 +01:00
using std : : dec ;
# ifdef WINDOWS_SYS
# include <sys/timeb.h>
# endif
2016-06-18 13:00:15 +02:00
struct RsLog : : logInfo pqihandlerzoneInfo = { RsLog : : Default , " pqihandler " } ;
# define pqihandlerzone &pqihandlerzoneInfo
2007-11-15 03:18:48 +00:00
2017-07-15 14:53:04 +02:00
//static const int PQI_HANDLER_NB_PRIORITY_LEVELS = 10 ;
//static const float PQI_HANDLER_NB_PRIORITY_RATIO = 2 ;
2011-09-04 20:01:30 +00:00
2020-05-25 20:28:50 +02:00
//#define UPDATE_RATES_DEBUG 1
// #define DEBUG_TICK 1
// #define RSITEM_DEBUG 1
2007-11-15 03:18:48 +00:00
2015-06-17 08:49:43 +00:00
pqihandler : : pqihandler ( ) : coreMtx ( " pqihandler " )
2007-11-15 03:18:48 +00:00
{
2020-05-25 20:28:50 +02:00
RS_STACK_MUTEX ( coreMtx ) ; /**************** LOCKED MUTEX ****************/
2008-11-22 13:15:07 +00:00
2016-06-11 18:07:57 -04:00
// setup minimal total+individual rates.
rateIndiv_out = 0.01 ;
rateIndiv_in = 0.01 ;
rateMax_out = 0.01 ;
2015-04-19 20:03:46 +00:00
rateMax_in = 0.01 ;
rateTotal_in = 0.0 ;
rateTotal_out = 0.0 ;
2019-04-03 17:29:13 +03:00
traffInSum = 0 ;
traffOutSum = 0 ;
2015-04-19 20:03:46 +00:00
last_m = time ( NULL ) ;
2016-06-11 18:07:57 -04:00
nb_ticks = 0 ;
mLastRateCapUpdate = 0 ;
ticks_per_sec = 5 ; // initial guess
2015-04-19 20:03:46 +00:00
return ;
2007-11-15 03:18:48 +00:00
}
int pqihandler : : tick ( )
{
2008-11-22 13:15:07 +00:00
int moreToTick = 0 ;
2015-12-23 15:49:05 +01:00
{
2020-05-25 20:28:50 +02:00
RS_STACK_MUTEX ( coreMtx ) ; /**************** LOCKED MUTEX ****************/
2008-11-22 13:15:07 +00:00
2011-09-04 20:01:30 +00:00
// tick all interfaces...
2014-03-17 20:56:06 +00:00
std : : map < RsPeerId , SearchModule * > : : iterator it ;
2014-10-24 22:07:26 +00:00
for ( it = mods . begin ( ) ; it ! = mods . end ( ) ; + + it )
2007-11-15 03:18:48 +00:00
{
2011-09-04 20:01:30 +00:00
if ( 0 < ( ( it - > second ) - > pqi ) - > tick ( ) )
{
2008-04-03 12:51:28 +00:00
# ifdef DEBUG_TICK
2011-09-04 20:01:30 +00:00
std : : cerr < < " pqihandler::tick() moreToTick from mod() " < < std : : endl ;
2008-04-03 12:51:28 +00:00
# endif
2011-09-04 20:01:30 +00:00
moreToTick = 1 ;
}
2007-11-15 03:18:48 +00:00
}
2015-04-24 09:29:40 +00:00
# ifdef TO_BE_REMOVED
2011-09-04 20:01:30 +00:00
// get the items, and queue them correctly
if ( 0 < locked_GetItems ( ) )
{
2008-04-03 12:51:28 +00:00
# ifdef DEBUG_TICK
2011-09-04 20:01:30 +00:00
std : : cerr < < " pqihandler::tick() moreToTick from GetItems() " < < std : : endl ;
2008-04-03 12:51:28 +00:00
# endif
2011-09-04 20:01:30 +00:00
moreToTick = 1 ;
}
2015-04-24 09:29:40 +00:00
# endif
2016-06-08 22:44:28 -04:00
}
2014-10-31 21:24:42 +00:00
2018-10-07 01:34:05 +02:00
rstime_t now = time ( NULL ) ;
2017-09-11 20:18:06 +02:00
2016-06-11 18:07:57 -04:00
if ( now > mLastRateCapUpdate + 5 )
2016-06-08 22:44:28 -04:00
{
2020-05-25 20:28:50 +02:00
std : : map < RsPeerId , RsConfigDataRates > rateMap ;
std : : map < RsPeerId , RsConfigDataRates > : : iterator it ;
2017-09-11 20:18:06 +02:00
// every 5 secs, update the max rates for all modules
2020-05-25 20:28:50 +02:00
RS_STACK_MUTEX ( coreMtx ) ; /**************** LOCKED MUTEX ****************/
2016-06-08 22:44:28 -04:00
for ( std : : map < RsPeerId , SearchModule * > : : iterator it = mods . begin ( ) ; it ! = mods . end ( ) ; + + it )
2017-09-11 20:18:06 +02:00
{
// This is rather inelegant, but pqihandler has searchModules that are dynamically allocated, so the max rates
// need to be updated from inside.
uint32_t maxUp = 0 , maxDn = 0 ;
if ( rsPeers - > getPeerMaximumRates ( it - > first , maxUp , maxDn ) )
it - > second - > pqi - > setRateCap ( maxDn , maxUp ) ; // mind the order! Dn first, than Up.
2016-06-08 22:44:28 -04:00
}
2017-09-11 20:18:06 +02:00
mLastRateCapUpdate = now ;
2016-06-08 22:44:28 -04:00
}
2011-09-04 20:01:30 +00:00
2007-11-15 03:18:48 +00:00
UpdateRates ( ) ;
return moreToTick ;
}
2011-09-04 20:01:30 +00:00
bool pqihandler : : queueOutRsItem ( RsItem * item )
{
2020-05-25 20:28:50 +02:00
RS_STACK_MUTEX ( coreMtx ) ; /**************** LOCKED MUTEX ****************/
2012-06-23 12:10:41 +00:00
uint32_t size ;
2015-06-17 09:07:45 +00:00
locked_HandleRsItem ( item , size ) ;
2011-09-04 20:01:30 +00:00
# ifdef DEBUG_QOS
if ( item - > priority_level ( ) = = QOS_PRIORITY_UNKNOWN )
std : : cerr < < " Caught an unprioritized item ! " < < std : : endl ;
print ( ) ;
# endif
return true ;
}
2007-11-15 03:18:48 +00:00
int pqihandler : : status ( )
{
2014-03-17 20:56:06 +00:00
std : : map < RsPeerId , SearchModule * > : : iterator it ;
2020-05-25 20:28:50 +02:00
RS_STACK_MUTEX ( coreMtx ) ; /**************** LOCKED MUTEX ****************/
2007-11-15 03:18:48 +00:00
{ // for output
2012-04-14 00:30:23 +00:00
std : : string out = " pqihandler::status() Active Modules: \n " ;
2007-11-15 03:18:48 +00:00
2012-04-14 00:30:23 +00:00
// display all interfaces...
2014-10-24 22:07:26 +00:00
for ( it = mods . begin ( ) ; it ! = mods . end ( ) ; + + it )
2012-04-14 00:30:23 +00:00
{
2014-03-17 20:56:06 +00:00
rs_sprintf_append ( out , " \t Module [%s] Pointer <%p> " , it - > first . toStdString ( ) . c_str ( ) , ( void * ) ( ( it - > second ) - > pqi ) ) ;
2012-04-14 00:30:23 +00:00
}
2007-11-15 03:18:48 +00:00
2012-04-14 00:30:23 +00:00
pqioutput ( PQL_DEBUG_BASIC , pqihandlerzone , out ) ;
2007-11-15 03:18:48 +00:00
} // end of output.
// status all interfaces...
2014-10-24 22:07:26 +00:00
for ( it = mods . begin ( ) ; it ! = mods . end ( ) ; + + it )
2007-11-15 03:18:48 +00:00
{
( ( it - > second ) - > pqi ) - > status ( ) ;
}
return 1 ;
}
2007-12-12 01:29:14 +00:00
bool pqihandler : : AddSearchModule ( SearchModule * mod )
2007-11-15 03:18:48 +00:00
{
2020-05-25 20:28:50 +02:00
RS_STACK_MUTEX ( coreMtx ) ; /**************** LOCKED MUTEX ****************/
2007-12-12 01:29:14 +00:00
// if peerid used -> error.
2017-07-26 10:33:55 +02:00
//std::map<RsPeerId, SearchModule *>::iterator it;
2007-12-12 01:29:14 +00:00
if ( mod - > peerid ! = mod - > pqi - > PeerId ( ) )
2007-11-15 03:18:48 +00:00
{
2007-12-12 01:29:14 +00:00
// ERROR!
2012-04-14 00:30:23 +00:00
pqioutput ( PQL_ALERT , pqihandlerzone , " ERROR peerid != PeerId! " ) ;
2007-12-12 01:29:14 +00:00
return false ;
2007-11-15 03:18:48 +00:00
}
2007-12-12 01:29:14 +00:00
2014-03-17 20:56:06 +00:00
if ( mod - > peerid . isNull ( ) )
2007-11-15 03:18:48 +00:00
{
2007-12-12 01:29:14 +00:00
// ERROR!
2012-04-14 00:30:23 +00:00
pqioutput ( PQL_ALERT , pqihandlerzone , " ERROR peerid == NULL " ) ;
2007-12-12 01:29:14 +00:00
return false ;
}
2007-11-15 03:18:48 +00:00
2007-12-12 01:29:14 +00:00
if ( mods . find ( mod - > peerid ) ! = mods . end ( ) )
{
// ERROR!
2012-04-14 00:30:23 +00:00
pqioutput ( PQL_ALERT , pqihandlerzone , " ERROR PeerId Module already exists! " ) ;
2007-12-12 01:29:14 +00:00
return false ;
2007-11-15 03:18:48 +00:00
}
// store.
2007-12-12 01:29:14 +00:00
mods [ mod - > peerid ] = mod ;
return true ;
2007-11-15 03:18:48 +00:00
}
2007-12-12 01:29:14 +00:00
bool pqihandler : : RemoveSearchModule ( SearchModule * mod )
2007-11-15 03:18:48 +00:00
{
2020-05-25 20:28:50 +02:00
RS_STACK_MUTEX ( coreMtx ) ; /**************** LOCKED MUTEX ****************/
2014-03-17 20:56:06 +00:00
std : : map < RsPeerId , SearchModule * > : : iterator it ;
2014-10-24 22:07:26 +00:00
for ( it = mods . begin ( ) ; it ! = mods . end ( ) ; + + it )
2007-11-15 03:18:48 +00:00
{
if ( mod = = it - > second )
{
mods . erase ( it ) ;
2007-12-12 01:29:14 +00:00
return true ;
2007-11-15 03:18:48 +00:00
}
}
2007-12-12 01:29:14 +00:00
return false ;
2007-11-15 03:18:48 +00:00
}
// generalised output
2015-06-17 09:07:45 +00:00
int pqihandler : : locked_HandleRsItem ( RsItem * item , uint32_t & computed_size )
2007-11-15 03:18:48 +00:00
{
2011-09-04 20:01:30 +00:00
computed_size = 0 ;
2014-03-17 20:56:06 +00:00
std : : map < RsPeerId , SearchModule * > : : iterator it ;
2015-12-23 15:49:05 +01:00
pqioutput ( PQL_DEBUG_BASIC , pqihandlerzone ,
2007-12-12 01:29:14 +00:00
" pqihandler::HandleRsItem() " ) ;
2007-11-15 03:18:48 +00:00
2015-12-23 15:49:05 +01:00
pqioutput ( PQL_DEBUG_BASIC , pqihandlerzone ,
2007-12-12 01:29:14 +00:00
" pqihandler::HandleRsItem() Sending to One Channel " ) ;
2009-12-13 21:59:26 +00:00
# ifdef DEBUG_TICK
std : : cerr < < " pqihandler::HandleRsItem() Sending to One Channel " < < std : : endl ;
# endif
2007-11-15 03:18:48 +00:00
2007-12-12 01:29:14 +00:00
// find module.
if ( ( it = mods . find ( item - > PeerId ( ) ) ) = = mods . end ( ) )
{
2012-04-14 00:30:23 +00:00
std : : string out = " pqihandler::HandleRsItem() Invalid chan! " ;
pqioutput ( PQL_DEBUG_BASIC , pqihandlerzone , out ) ;
2009-12-13 21:59:26 +00:00
# ifdef DEBUG_TICK
2012-04-14 00:30:23 +00:00
std : : cerr < < out < < std : : endl ;
2009-12-13 21:59:26 +00:00
# endif
2007-11-15 03:18:48 +00:00
2007-12-12 01:29:14 +00:00
delete item ;
return - 1 ;
}
2007-11-15 03:18:48 +00:00
2014-03-17 20:56:06 +00:00
std : : string out = " pqihandler::HandleRsItem() sending to chan: " + it - > first . toStdString ( ) ;
2012-04-14 00:30:23 +00:00
pqioutput ( PQL_DEBUG_BASIC , pqihandlerzone , out ) ;
2009-12-13 21:59:26 +00:00
# ifdef DEBUG_TICK
2012-04-14 00:30:23 +00:00
std : : cerr < < out < < std : : endl ;
2009-12-13 21:59:26 +00:00
# endif
2007-11-15 03:18:48 +00:00
2007-12-12 01:29:14 +00:00
// if yes send on item.
2011-09-04 20:01:30 +00:00
( ( it - > second ) - > pqi ) - > SendItem ( item , computed_size ) ;
2007-12-12 01:29:14 +00:00
return 1 ;
2007-11-15 03:18:48 +00:00
}
2007-12-12 01:29:14 +00:00
int pqihandler : : SendRsRawItem ( RsRawItem * ns )
2007-11-15 03:18:48 +00:00
{
2011-09-04 20:01:30 +00:00
pqioutput ( PQL_DEBUG_BASIC , pqihandlerzone , " pqihandler::SendRsRawItem() " ) ;
2012-06-23 12:10:41 +00:00
// directly send item to streamers
2015-12-23 15:49:05 +01:00
2011-09-04 20:01:30 +00:00
return queueOutRsItem ( ns ) ;
2007-11-15 03:18:48 +00:00
}
2015-07-12 04:04:18 +00:00
int pqihandler : : ExtractTrafficInfo ( std : : list < RSTrafficClue > & out_lst , std : : list < RSTrafficClue > & in_lst )
{
in_lst . clear ( ) ;
out_lst . clear ( ) ;
for ( std : : map < RsPeerId , SearchModule * > : : iterator it = mods . begin ( ) ; it ! = mods . end ( ) ; + + it )
2015-07-17 22:13:31 +02:00
{
std : : list < RSTrafficClue > ilst , olst ;
( it - > second ) - > pqi - > gatherStatistics ( olst , ilst ) ;
for ( std : : list < RSTrafficClue > : : const_iterator it ( ilst . begin ( ) ) ; it ! = ilst . end ( ) ; + + it ) in_lst . push_back ( * it ) ;
for ( std : : list < RSTrafficClue > : : const_iterator it ( olst . begin ( ) ) ; it ! = olst . end ( ) ; + + it ) out_lst . push_back ( * it ) ;
}
2015-07-12 04:04:18 +00:00
return 1 ;
}
2012-06-21 23:23:46 +00:00
// NEW extern fn to extract rates.
2014-03-17 20:56:06 +00:00
int pqihandler : : ExtractRates ( std : : map < RsPeerId , RsBwRates > & ratemap , RsBwRates & total )
2012-06-21 23:23:46 +00:00
{
total . mMaxRateIn = getMaxRate ( true ) ;
total . mMaxRateOut = getMaxRate ( false ) ;
total . mRateIn = 0 ;
total . mRateOut = 0 ;
2012-06-22 01:35:32 +00:00
total . mQueueIn = 0 ;
total . mQueueOut = 0 ;
2012-06-21 23:23:46 +00:00
/* Lock once rates have been retrieved */
2020-05-25 20:28:50 +02:00
RS_STACK_MUTEX ( coreMtx ) ; /**************** LOCKED MUTEX ****************/
2012-06-21 23:23:46 +00:00
2014-03-17 20:56:06 +00:00
std : : map < RsPeerId , SearchModule * > : : iterator it ;
2014-10-24 22:07:26 +00:00
for ( it = mods . begin ( ) ; it ! = mods . end ( ) ; + + it )
2012-06-21 23:23:46 +00:00
{
SearchModule * mod = ( it - > second ) ;
RsBwRates peerRates ;
mod - > pqi - > getRates ( peerRates ) ;
total . mRateIn + = peerRates . mRateIn ;
total . mRateOut + = peerRates . mRateOut ;
2012-06-22 01:35:32 +00:00
total . mQueueIn + = peerRates . mQueueIn ;
total . mQueueOut + = peerRates . mQueueOut ;
2012-06-21 23:23:46 +00:00
ratemap [ it - > first ] = peerRates ;
}
return 1 ;
}
2015-12-23 15:49:05 +01:00
// internal fn to send updates
2007-11-15 03:18:48 +00:00
int pqihandler : : UpdateRates ( )
{
2014-03-17 20:56:06 +00:00
std : : map < RsPeerId , SearchModule * > : : iterator it ;
2015-12-23 15:49:05 +01:00
2007-11-15 03:18:48 +00:00
float avail_in = getMaxRate ( true ) ;
float avail_out = getMaxRate ( false ) ;
float used_bw_in = 0 ;
float used_bw_out = 0 ;
2008-11-22 13:15:07 +00:00
/* Lock once rates have been retrieved */
2020-05-25 20:28:50 +02:00
RS_STACK_MUTEX ( coreMtx ) ; /**************** LOCKED MUTEX ****************/
2008-11-22 13:15:07 +00:00
2015-12-29 23:40:09 -05:00
int num_sm = mods . size ( ) ;
float used_bw_in_table [ num_sm ] ; /* table of in bandwidth currently used by each module */
float used_bw_out_table [ num_sm ] ; /* table of out bandwidth currently used by each module */
2020-05-25 20:28:50 +02:00
// loop through modules to get the used bandwidth
# ifdef UPDATE_RATES_DEBUG
RsDbg ( ) < < " UPDATE_RATES pqihandler::UpdateRates Looping through modules " < < std : : endl ;
2015-12-23 15:49:05 +01:00
# endif
int index = 0 ;
2014-10-24 22:07:26 +00:00
for ( it = mods . begin ( ) ; it ! = mods . end ( ) ; + + it )
2007-11-15 03:18:48 +00:00
{
SearchModule * mod = ( it - > second ) ;
2019-04-03 17:29:13 +03:00
traffInSum + = mod - > pqi - > getTraffic ( true ) ;
traffOutSum + = mod - > pqi - > getTraffic ( false ) ;
2016-04-09 14:48:05 -04:00
2020-05-25 20:28:50 +02:00
float crate_in = mod - > pqi - > getRate ( true ) ;
2009-06-08 17:09:00 +00:00
float crate_out = mod - > pqi - > getRate ( false ) ;
used_bw_in + = crate_in ;
used_bw_out + = crate_out ;
2015-12-23 15:49:05 +01:00
2020-05-25 20:28:50 +02:00
/* fill the table of used bandwidths */
2015-12-23 15:49:05 +01:00
used_bw_in_table [ index ] = crate_in ;
used_bw_out_table [ index ] = crate_out ;
2020-05-25 20:28:50 +02:00
2015-12-23 15:49:05 +01:00
+ + index ;
2007-11-15 03:18:48 +00:00
}
2015-12-23 15:49:05 +01:00
2020-05-25 20:28:50 +02:00
# ifdef UPDATE_RATES_DEBUG
RsDbg ( ) < < " UPDATE_RATES pqihandler::UpdateRates Sorting used_bw_out_table: " < < num_sm < < " entries " < < std : : endl ;
2015-12-23 15:49:05 +01:00
# endif
/* Sort the used bw in/out table in ascending order */
std : : sort ( used_bw_in_table , used_bw_in_table + num_sm ) ;
std : : sort ( used_bw_out_table , used_bw_out_table + num_sm ) ;
2020-05-25 20:28:50 +02:00
# ifdef UPDATE_RATES_DEBUG
RsDbg ( ) < < " UPDATE_RATES pqihandler::UpdateRates used_bw_out " < < used_bw_out < < std : : endl ;
2015-12-23 15:49:05 +01:00
# endif
/* Calculate the optimal out_max value, taking into account avail_out and the out bw requested by modules */
float out_remaining_bw = avail_out ;
float out_max_bw = 0 ;
bool keep_going = true ;
int mod_index = 0 ;
while ( keep_going & & ( mod_index < num_sm ) ) {
float result = ( num_sm - mod_index ) * ( used_bw_out_table [ mod_index ] - out_max_bw ) ;
if ( result > out_remaining_bw ) {
/* There is not enough remaining out bw to satisfy all modules,
distribute the remaining out bw among modules , then exit */
out_max_bw + = out_remaining_bw / ( num_sm - mod_index ) ;
out_remaining_bw = 0 ;
keep_going = false ;
} else {
/* Grant the requested out bandwidth to all modules,
then recalculate the remaining out bandwidth */
out_remaining_bw - = result ;
out_max_bw = used_bw_out_table [ mod_index ] ;
+ + mod_index ;
}
}
2020-05-25 20:28:50 +02:00
# ifdef UPDATE_RATES_DEBUG
RsDbg ( ) < < " UPDATE_RATES pqihandler::UpdateRates mod_index " < < mod_index < < " out_max_bw " < < out_max_bw < < " remaining out bw " < < out_remaining_bw < < std : : endl ;
2015-12-23 15:49:05 +01:00
# endif
2021-01-12 10:08:17 +01:00
/* Allocate only 50 pct the remaining out bw, if any, to make the transition more smooth */
out_max_bw = out_max_bw + 0.5 * out_remaining_bw ;
2015-12-23 15:49:05 +01:00
/* Calculate the optimal in_max value, taking into account avail_in and the in bw requested by modules */
float in_remaining_bw = avail_in ;
float in_max_bw = 0 ;
keep_going = true ;
mod_index = 0 ;
while ( keep_going & & mod_index < num_sm ) {
float result = ( num_sm - mod_index ) * ( used_bw_in_table [ mod_index ] - in_max_bw ) ;
if ( result > in_remaining_bw ) {
/* There is not enough remaining in bw to satisfy all modules,
distribute the remaining in bw among modules , then exit */
in_max_bw + = in_remaining_bw / ( num_sm - mod_index ) ;
in_remaining_bw = 0 ;
keep_going = false ;
} else {
/* Grant the requested in bandwidth to all modules,
then recalculate the remaining in bandwidth */
in_remaining_bw - = result ;
in_max_bw = used_bw_in_table [ mod_index ] ;
+ + mod_index ;
}
}
2020-05-25 20:28:50 +02:00
# ifdef UPDATE_RATES_DEBUG
RsDbg ( ) < < " UPDATE_RATES pqihandler::UpdateRates mod_index " < < mod_index < < " in_max_bw " < < in_max_bw < < " remaining in bw " < < in_remaining_bw < < std : : endl ;
2015-12-23 15:49:05 +01:00
# endif
2021-01-12 10:08:17 +01:00
// allocate only 75 pct of the remaining in bw, to make the transition more smooth
in_max_bw = in_max_bw + 0.75 * in_remaining_bw ;
2015-12-23 15:49:05 +01:00
2021-01-10 15:55:38 +01:00
// store current total in and out used bw
2020-05-25 20:28:50 +02:00
locked_StoreCurrentRates ( used_bw_in , used_bw_out ) ;
2015-12-23 15:49:05 +01:00
2020-05-25 20:28:50 +02:00
# ifdef UPDATE_RATES_DEBUG
RsDbg ( ) < < " UPDATE_RATES pqihandler::UpdateRates setting new out_max " < < out_max_bw < < " in_max " < < in_max_bw < < std : : endl ;
2011-09-04 20:01:30 +00:00
# endif
2007-11-15 03:18:48 +00:00
2021-01-10 15:55:38 +01:00
// retrieve the bandwidth limits provided by peers via BwCtrl
2020-05-25 20:28:50 +02:00
std : : map < RsPeerId , RsConfigDataRates > rateMap ;
rsConfig - > getAllBandwidthRates ( rateMap ) ;
std : : map < RsPeerId , RsConfigDataRates > : : iterator rateMap_it ;
2007-11-15 03:18:48 +00:00
2020-05-25 20:28:50 +02:00
# ifdef UPDATE_RATES_DEBUG
2021-01-10 15:55:38 +01:00
// dump RsConfigurationDataRates
2020-05-25 20:28:50 +02:00
RsDbg ( ) < < " UPDATE_RATES pqihandler::UpdateRates RsConfigDataRates dump " < < std : : endl ;
for ( rateMap_it = rateMap . begin ( ) ; rateMap_it ! = rateMap . end ( ) ; rateMap_it + + )
RsDbg ( ) < < " UPDATE_RATES pqihandler::UpdateRates PeerId " < < rateMap_it - > first . toStdString ( ) < < " mAllowedOut " < < rateMap_it - > second . mAllowedOut < < std : : endl ;
2015-12-23 15:49:05 +01:00
# endif
2007-11-15 03:18:48 +00:00
2021-01-10 15:55:38 +01:00
// update max rates
2015-12-23 15:49:05 +01:00
for ( it = mods . begin ( ) ; it ! = mods . end ( ) ; + + it )
{
SearchModule * mod = ( it - > second ) ;
2021-01-10 15:55:38 +01:00
// for our down bandwidth we use the calculated value without taking into account the max up provided by peers via BwCtrl
// this is harmless as they will control their up bw on their side
2020-05-25 20:28:50 +02:00
mod - > pqi - > setMaxRate ( true , in_max_bw ) ;
2021-01-10 15:55:38 +01:00
// for our up bandwidth we take into account the max down provided by peers via BwCtrl
// because we don't want to clog our outqueues, the TCP buffers, and the peers inbound queues
2021-02-03 09:38:35 +01:00
mod - > pqi - > setMaxRate ( false , out_max_bw ) ;
2020-05-25 20:28:50 +02:00
if ( ( rateMap_it = rateMap . find ( mod - > pqi - > PeerId ( ) ) ) ! = rateMap . end ( ) )
if ( rateMap_it - > second . mAllowedOut > 0 )
2021-01-12 10:08:17 +01:00
if ( out_max_bw > rateMap_it - > second . mAllowedOut )
mod - > pqi - > setMaxRate ( false , rateMap_it - > second . mAllowedOut ) ;
2020-05-25 20:28:50 +02:00
}
2020-05-24 23:40:26 +02:00
2020-05-25 20:28:50 +02:00
# ifdef UPDATE_RATES_DEBUG
// dump maxRates
2014-10-24 22:07:26 +00:00
for ( it = mods . begin ( ) ; it ! = mods . end ( ) ; + + it )
2007-11-15 03:18:48 +00:00
{
2009-06-08 17:09:00 +00:00
SearchModule * mod = ( it - > second ) ;
2020-05-25 20:28:50 +02:00
RsDbg ( ) < < " UPDATE_RATES pqihandler::UpdateRates PeerID " < < ( mod - > pqi - > PeerId ( ) ) . toStdString ( ) < < " new bandwidth limits up " < < mod - > pqi - > getMaxRate ( false ) < < " down " < < mod - > pqi - > getMaxRate ( true ) < < std : : endl ;
2007-11-15 03:18:48 +00:00
}
2020-05-25 20:28:50 +02:00
# endif
2008-06-10 00:47:24 +00:00
2007-11-15 03:18:48 +00:00
return 1 ;
}
2008-06-10 00:47:24 +00:00
void pqihandler : : getCurrentRates ( float & in , float & out )
{
2020-05-25 20:28:50 +02:00
RS_STACK_MUTEX ( coreMtx ) ; /**************** LOCKED MUTEX ****************/
2008-11-22 13:15:07 +00:00
2008-06-10 00:47:24 +00:00
in = rateTotal_in ;
out = rateTotal_out ;
}
2008-11-22 13:15:07 +00:00
void pqihandler : : locked_StoreCurrentRates ( float in , float out )
2008-06-10 00:47:24 +00:00
{
rateTotal_in = in ;
rateTotal_out = out ;
}
2019-04-03 17:29:13 +03:00
void pqihandler : : GetTraffic ( uint64_t & in , uint64_t & out )
{
in = traffInSum ;
out = traffOutSum ;
}