From f0a49a427ebe44d4e4d2b31437634379c0f782ce Mon Sep 17 00:00:00 2001 From: csoler Date: Sat, 30 Jan 2016 20:27:56 -0500 Subject: [PATCH] changed global router routing strategy. Should be more effective now. --- libretroshare/src/grouter/grouteritems.cc | 51 ++- libretroshare/src/grouter/grouteritems.h | 2 +- libretroshare/src/grouter/groutermatrix.cc | 6 +- libretroshare/src/grouter/groutermatrix.h | 2 +- libretroshare/src/grouter/groutertypes.h | 4 + libretroshare/src/grouter/p3grouter.cc | 333 ++++++++++++------ libretroshare/src/grouter/p3grouter.h | 5 +- libretroshare/src/retroshare/rsgrouter.h | 1 + .../gui/statistics/GlobalRouterStatistics.cpp | 32 +- .../gui/statistics/GlobalRouterStatistics.ui | 7 +- 10 files changed, 308 insertions(+), 135 deletions(-) diff --git a/libretroshare/src/grouter/grouteritems.cc b/libretroshare/src/grouter/grouteritems.cc index cab25c43e..a964aabc4 100644 --- a/libretroshare/src/grouter/grouteritems.cc +++ b/libretroshare/src/grouter/grouteritems.cc @@ -142,25 +142,44 @@ RsGRouterGenericDataItem *RsGRouterSerialiser::deserialise_RsGRouterGenericDataI ok &= getRawUInt32(data, pktsize, &offset, &item->service_id); ok &= getRawUInt32(data, pktsize, &offset, &item->data_size); - if(item->data_size > rssize || offset > rssize - item->data_size) // better than if(item->data_size + offset > rssize) + if(item->data_size > 0) // This happens when the item data has been deleted from the cache { - std::cerr << __PRETTY_FUNCTION__ << ": Cannot read beyond item size. Serialisation error!" << std::endl; - delete item; - return NULL ; - } + if(item->data_size > rssize || offset > rssize - item->data_size) // better than if(item->data_size + offset > rssize) + { + std::cerr << __PRETTY_FUNCTION__ << ": Cannot read beyond item size. Serialisation error!" << std::endl; + delete item; + return NULL ; + } - if( NULL == (item->data_bytes = (uint8_t*)rs_malloc(item->data_size))) - { - delete item; - return NULL ; - } + if( NULL == (item->data_bytes = (uint8_t*)rs_malloc(item->data_size))) + { + delete item; + return NULL ; + } - memcpy(item->data_bytes,&((uint8_t*)data)[offset],item->data_size) ; - offset += item->data_size ; + memcpy(item->data_bytes,&((uint8_t*)data)[offset],item->data_size) ; + offset += item->data_size ; + } + else + item->data_bytes = NULL ; ok &= item->signature.GetTlv(data, pktsize, &offset) ; - ok &= getRawUInt32(data, pktsize, &offset, &item->randomized_distance); + ok &= getRawUInt32(data, pktsize, &offset, &item->duplication_factor); + + // make sure the duplication factor is not altered by friends. In the worst case, the item will duplicate a bit more. + + if(item->duplication_factor < 1) + { + item->duplication_factor = 1 ; + std::cerr << "(II) correcting GRouter item duplication factor from 0 to 1, to ensure backward compat." << std::endl; + } + if(item->duplication_factor > GROUTER_MAX_DUPLICATION_FACTOR) + { + std::cerr << "(WW) correcting GRouter item duplication factor of " << item->duplication_factor << ". This is very unexpected." << std::endl; + item->duplication_factor = GROUTER_MAX_DUPLICATION_FACTOR ; + } + ok &= getRawUInt32(data, pktsize, &offset, &item->flags); if (offset != rssize || !ok) @@ -382,7 +401,7 @@ uint32_t RsGRouterGenericDataItem::serial_size() const s += 4 ; // service id s += data_size ; // data s += signature.TlvSize() ; // signature - s += 4 ; // randomized distance + s += 4 ; // duplication_factor s += 4 ; // flags return s ; @@ -483,7 +502,7 @@ bool RsGRouterGenericDataItem::serialise(void *data,uint32_t& size) const ok &= signature.SetTlv(data, tlvsize, &offset) ; - ok &= setRawUInt32(data, tlvsize, &offset, randomized_distance) ; + ok &= setRawUInt32(data, tlvsize, &offset, duplication_factor) ; ok &= setRawUInt32(data, tlvsize, &offset, flags) ; if (offset != tlvsize) @@ -796,7 +815,7 @@ std::ostream& RsGRouterGenericDataItem::print(std::ostream& o, uint16_t) o << " Data size: " << data_size << std::endl ; o << " Data hash: " << RsDirUtil::sha1sum(data_bytes,data_size) << std::endl ; o << " signature key: " << signature.keyId << std::endl; - o << " randomized dist:" << randomized_distance << std::endl; + o << " duplication fac:" << duplication_factor << std::endl; o << " flags: " << flags << std::endl; return o ; diff --git a/libretroshare/src/grouter/grouteritems.h b/libretroshare/src/grouter/grouteritems.h index ad87d1051..63952fc23 100644 --- a/libretroshare/src/grouter/grouteritems.h +++ b/libretroshare/src/grouter/grouteritems.h @@ -133,7 +133,7 @@ class RsGRouterGenericDataItem: public RsGRouterAbstractMsgItem, public RsGRoute uint32_t data_size ; uint8_t *data_bytes; - uint32_t randomized_distance ; // number of hops (tunnel wise. Does not preclude of the real distance) + uint32_t duplication_factor ; // number of duplicates allowed. Should be capped at each de-serialise operation! // utility methods for signing data virtual uint32_t signed_data_size() const ; diff --git a/libretroshare/src/grouter/groutermatrix.cc b/libretroshare/src/grouter/groutermatrix.cc index a6bb063cf..31bed1375 100644 --- a/libretroshare/src/grouter/groutermatrix.cc +++ b/libretroshare/src/grouter/groutermatrix.cc @@ -203,7 +203,7 @@ void GRouterMatrix::debugDump() const std::cerr << " " << it->first << ": from " << it->second.friend_id << " " << now - it->second.time_stamp << " secs ago." << std::endl; } -bool GRouterMatrix::computeRoutingProbabilities(const GRouterKeyId& key_id, const std::vector& friends, std::vector& probas) const +bool GRouterMatrix::computeRoutingProbabilities(const GRouterKeyId& key_id, const std::vector& friends, std::vector& probas, float& maximum) const { // Routing probabilities are computed according to routing clues // @@ -239,6 +239,7 @@ bool GRouterMatrix::computeRoutingProbabilities(const GRouterKeyId& key_id, cons return false ; } const std::vector& w(it2->second) ; + maximum = 0.0f ; for(uint32_t i=0;i& friends, std::vector& probas) const ; + bool computeRoutingProbabilities(const GRouterKeyId& id, const std::vector& friends, std::vector& probas, float &maximum) const ; // Update routing probabilities for each key, accounting for all received events, but without // activity information diff --git a/libretroshare/src/grouter/groutertypes.h b/libretroshare/src/grouter/groutertypes.h index 3c4897b0a..4341b5d65 100644 --- a/libretroshare/src/grouter/groutertypes.h +++ b/libretroshare/src/grouter/groutertypes.h @@ -44,6 +44,8 @@ static const uint32_t RS_GROUTER_MAX_KEEP_TRACKING_CLUES = 86400*10 ; // m static const float RS_GROUTER_BASE_WEIGHT_ROUTED_MSG = 1.0f ; // base contribution of routed message clue to routing matrix static const float RS_GROUTER_BASE_WEIGHT_GXS_PACKET = 0.1f ; // base contribution of GXS message to routing matrix +static const float RS_GROUTER_PROBABILITY_THRESHOLD_FOR_RANDOM_ROUTING = 0.01f ; // routing probability under which the routage is performed randomly +static const float RS_GROUTER_PROBABILITY_THRESHOLD_BEST_PEERS_SELECT = 0.5f ; // min ratio of forward proba with respect to best peer. static const uint32_t MAX_TUNNEL_WAIT_TIME = 60 ; // wait for 60 seconds at most for a tunnel response. static const uint32_t MAX_TUNNEL_UNMANAGED_TIME = 600 ; // min time before retry tunnels for that msg. @@ -54,6 +56,8 @@ static const uint32_t MAX_GROUTER_DATA_SIZE = 2*1024*1024 ; // 2M static const uint32_t MAX_TRANSACTION_ACK_WAITING_TIME = 60 ; // wait for at most 60 secs for a ACK. If not restart the transaction. static const uint32_t DIRECT_FRIEND_TRY_DELAY = 20 ; // wait for 20 secs if no friends available, then try tunnels. static const uint32_t MAX_INACTIVE_DATA_PIPE_DELAY = 300 ; // clean inactive data pipes for more than 5 mins +static const uint32_t GROUTER_MAX_DUPLICATION_FACTOR = 10 ; // max number of duplicates for a given message to keep in the network +static const uint32_t GROUTER_MAX_BRANCHING_FACTOR = 3 ; // max number of branches, for locally forwarding items static const time_t RS_GROUTER_DEBUG_OUTPUT_PERIOD = 10 ; // Output everything static const time_t RS_GROUTER_AUTOWASH_PERIOD = 10 ; // Autowash every minute. Not a costly operation. diff --git a/libretroshare/src/grouter/p3grouter.cc b/libretroshare/src/grouter/p3grouter.cc index e11358970..74902837b 100644 --- a/libretroshare/src/grouter/p3grouter.cc +++ b/libretroshare/src/grouter/p3grouter.cc @@ -190,6 +190,7 @@ #include "services/p3idservice.h" #include "turtle/p3turtle.h" #include "gxs/rsgixs.h" +#include "retroshare/rspeers.h" #include "p3grouter.h" #include "grouteritems.h" @@ -197,7 +198,7 @@ #include "grouterclientservice.h" /**********************/ -//#define GROUTER_DEBUG +#define GROUTER_DEBUG /**********************/ const std::string p3GRouter::SERVICE_INFO_APP_NAME = "Global Router" ; @@ -855,6 +856,34 @@ void p3GRouter::handleTunnels() } } +void p3GRouter::locked_sendToPeers(RsGRouterGenericDataItem *data_item,const std::map& peers_and_duplication_factors) +{ + // slice the data appropriately and send. + + uint32_t saved_duplication_factor = data_item->duplication_factor ; // this little trick avoids copying the item for each peer before slicing it up + + for(std::map::const_iterator itpid(peers_and_duplication_factors.begin());itpid!=peers_and_duplication_factors.end();++itpid) + { + std::list chunks ; + data_item->duplication_factor = itpid->second; + + sliceDataItem(data_item,chunks) ; + + for(std::list::const_iterator it2(chunks.begin());it2!=chunks.end();++it2) + locked_sendTransactionData(itpid->first,*(*it2) ) ; + +#ifdef GROUTER_DEBUG + std::cerr << " sending " << chunks.size() << " slices to peer " << itpid->first << " with duplication factor = " << itpid->second << std::endl; +#endif + // delete temporary items + + for(std::list::const_iterator cit=chunks.begin();cit!=chunks.end();++cit) + delete *cit; + } + + data_item->duplication_factor = saved_duplication_factor ; +} + void p3GRouter::routePendingObjects() { // Go throught he list of pending messages. For those with a peer ready, send the message to that peer. @@ -885,56 +914,59 @@ void p3GRouter::routePendingObjects() { // Look for tunnels and friends where to send the data. Send to both. - std::list peers ; - - if(it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_TUNNELS) - locked_collectAvailableTunnels(it->second.tunnel_hash,peers); - - // For now, disable friends. We'll first check that the good old tunnel system works as before. + std::map peers_and_duplication_factors ; +// if(it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_TUNNELS) +// locked_collectAvailableTunnels(it->second.tunnel_hash,it->second.data_item->duplication_factor,peers_and_duplication_factors); +// +// if(!peers_and_duplication_factors.empty()) +// { +//#ifdef GROUTER_DEBUG +// std::cerr << " tunnels available! sending!" << std::endl; +//#endif +// locked_sendToPeers(it->second.data_item,peers_and_duplication_factors) ; +// +// // change item state in waiting list +// +// it->second.data_status = RS_GROUTER_DATA_STATUS_ONGOING ; +// it->second.data_transaction_TS = now ; +// +// pending_messages_changed = true ; +// continue ; // no need to seek for friend asynced routes since tunnels directly go to the final destination! +// } + if(it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_FRIENDS) - locked_collectAvailableFriends(it->second.data_item->destination_key,peers, it->second.incoming_routes.ids, it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_IS_ORIGIN); + locked_collectAvailableFriends(it->second.data_item->destination_key,it->second.incoming_routes.ids,it->second.data_item->duplication_factor,peers_and_duplication_factors); - if(peers.empty()) - { -#ifdef GROUTER_DEBUG - std::cerr << " no direct friends available" << std::endl; -#endif +// if(!peers_and_duplication_factors.empty()) +// { +//#ifdef GROUTER_DEBUG +// std::cerr << " friends available! sending!" << std::endl; +//#endif +// locked_sendToPeers(it->second.data_item,peers_and_duplication_factors) ; +// +// // change item state in waiting list +// +// it->second.data_status = RS_GROUTER_DATA_STATUS_ONGOING ; +// it->second.data_transaction_TS = now ; +// +// pending_messages_changed = true ; +// } +// else +// { +//#ifdef GROUTER_DEBUG +// std::cerr << " no direct friends available" << std::endl; +//#endif +// +// if(it->second.received_time_TS + DIRECT_FRIEND_TRY_DELAY < now && !(it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_TUNNELS)) +// { +//#ifdef GROUTER_DEBUG +// std::cerr << " enabling tunnels for this message." << std::endl; +//#endif +// it->second.routing_flags |= GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_TUNNELS ; +// } +// } - if(it->second.received_time_TS + DIRECT_FRIEND_TRY_DELAY < now && !(it->second.routing_flags & GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_TUNNELS)) - { -#ifdef GROUTER_DEBUG - std::cerr << " enabling tunnels for this message." << std::endl; -#endif - it->second.routing_flags |= GRouterRoutingInfo::ROUTING_FLAGS_ALLOW_TUNNELS ; - } - continue ; - } - - // slice the data appropriately and send. - - std::list chunks ; - sliceDataItem(it->second.data_item,chunks) ; - -#ifdef GROUTER_DEBUG - if(!peers.empty()) - std::cerr << " sending to peers:" << std::endl; -#endif - for(std::list::const_iterator itpid(peers.begin());itpid!=peers.end();++itpid) - for(std::list::const_iterator it2(chunks.begin());it2!=chunks.end();++it2) - locked_sendTransactionData(*itpid,*(*it2) ) ; - - // delete temporary items - - for(std::list::const_iterator cit=chunks.begin();cit!=chunks.end();++cit) - delete *cit; - - // change item state in waiting list - - it->second.data_status = RS_GROUTER_DATA_STATUS_ONGOING ; - it->second.data_transaction_TS = now ; - - pending_messages_changed = true ; } else if(it->second.data_status == RS_GROUTER_DATA_STATUS_ONGOING && now > MAX_TRANSACTION_ACK_WAITING_TIME + it->second.data_transaction_TS) { @@ -1014,70 +1046,161 @@ void p3GRouter::routePendingObjects() IndicateConfigChanged() ; } -void p3GRouter::locked_collectAvailableFriends(const GRouterKeyId& gxs_id,std::list& friend_peers,const std::set& incoming_routes,bool is_origin) +void p3GRouter::locked_collectAvailableFriends(const GRouterKeyId& gxs_id,const std::set& incoming_routes,uint32_t duplication_factor, std::map& friend_peers_and_duplication_factors) { - // The strategy is the following: + // Old strategy was the following: // if origin // send to multiple neighbors : best and random // else // send to a single "best" neighbor (determined by threshold over routing probability), - - std::set ids ; - mServiceControl->getPeersConnected(getServiceInfo().mServiceType,ids) ; - - std::vector probas; - std::vector tmp_peers; - - // remove previous peers - - for(std::set::const_iterator it(ids.begin());it!=ids.end();++it) - if(incoming_routes.find(*it) == incoming_routes.end()) - tmp_peers.push_back(*it) ; - - if(tmp_peers.empty()) - return ; - - _routing_matrix.computeRoutingProbabilities(gxs_id, tmp_peers, probas) ; + + // New strategy is: + // + // Characteristics of the distribution to look at: + // * who's online, who's not + // * all values quite equal + // * single value well above others + // * largest value is small + // Algorithm: + // + // 0 - encode duplicate factor in routed item and allow at most N duplicates + // - when forwarding to N peers, split the duplication factor into N bins, each being proportional to the forwarding probability. + // Example for N=3 and D=10: + // + // p Calculation Final bin + // + // +-0.21--> 0.21*10=2.1 --> 2 0.1 below + // | + // 10 ----+-0.45--> 0.45*10=4.5 --> 4.6-> 5 0.4 above + // | + // +-0.34--> 0.34*10=3.4 --> 3.0-> 3 0 + // + // + // 1 - get routing probabilities p_i for all peers as well as the maximum proba p before normalization. + // + // Set N = min(3,item->duplication_factor) // max number of friends to route to + // + // if p < threshold // That means the routage info is too old => Fallback to random routing. + // Select N random online friends and forward to them. + // else + // Let p_i be the probabilities of all peers + // Select all online peers for which p_i >= 0.5*p. + // if !empty + // Update duplication factors according to probabilities and number of peers + // Route to these peers + // else + // Keep the item + // #ifdef GROUTER_DEBUG std::cerr << "locked_getAvailableFriends()" << std::endl; - std::cerr << " getting connected friends, computing routing probabilities" << std::endl; + std::cerr << " looking for friends for item to ID " << gxs_id << " duplication factor = " << duplication_factor << std::endl; + std::cerr << " retrieving online friends and all friends lists." << std::endl; +#endif + std::set online_ids ; + std::list all_ids ; + + rsPeers->getFriendList(all_ids) ; + mServiceControl->getPeersConnected(getServiceInfo().mServiceType,online_ids) ; + + std::vector tmp_peers; + + for(std::list::const_iterator it(all_ids.begin());it!=all_ids.end();++it) + tmp_peers.push_back(*it) ; + + std::vector probas; + float maximum = 1.0; + float max_probability = 0.0; + + _routing_matrix.computeRoutingProbabilities(gxs_id, tmp_peers, probas, maximum) ; + +#ifdef GROUTER_DEBUG + std::cerr << " initial routing probabilities (maximum=" << maximum << ")" << std::endl; + for(uint32_t i=0;i using uniform random routing." << std::endl; +#endif + } + else + { + for(uint32_t i=0;i giving up." << std::endl; +#endif + return ; + } + + // now select the N best peers +#ifdef GROUTER_DEBUG + std::cerr << " Remaining peers and routing probabilities:" << std::endl; for(uint32_t i=0;i mac_count=" << max_count << ", proba threshold=" << probability_threshold << std::endl; -#endif + float probability_threshold = RS_GROUTER_PROBABILITY_THRESHOLD_FOR_RANDOM_ROUTING ; std::vector > mypairs ; for(uint32_t i=0;i >::const_reverse_iterator it = mypairs.rbegin();it!=mypairs.rend() && n= probability_threshold ) + for(int i=mypairs.size()-1;i>=0 && nfirst << std::dec ; grouter_debug() << " data hash: " << it->second.item_hash ; - grouter_debug() << " client id: " << std::hex << it->second.client_id << std::dec; + grouter_debug() << " client: " << std::hex << it->second.client_id << std::dec; grouter_debug() << " Flags: " << std::hex << it->second.routing_flags << std::dec; - grouter_debug() << " Destination: " << it->second.data_item->destination_key ; - grouter_debug() << " Received: " << now - it->second.received_time_TS << " secs ago."; - grouter_debug() << " Last sent: " << now - it->second.last_sent_TS << " secs ago."; - grouter_debug() << " Transaction TS: " << now - it->second.data_transaction_TS << " secs ago."; - grouter_debug() << " Data Status: " << statusString[it->second.data_status] << std::endl; - grouter_debug() << " Tunl Status: " << statusString[it->second.tunnel_status] << std::endl; - grouter_debug() << " Receipt ok: " << (it->second.receipt_item != NULL) << std::endl; + grouter_debug() << " Dest: " << it->second.data_item->destination_key ; + grouter_debug() << " Recd: " << now - it->second.received_time_TS << " secs ago."; + grouter_debug() << " Sent: " << now - it->second.last_sent_TS << " secs ago."; + grouter_debug() << " Trans. TS: " << now - it->second.data_transaction_TS << " secs ago." ; + grouter_debug() << " Data Status: " << statusString[it->second.data_status] ; + grouter_debug() << " Tunl Status: " << statusString[it->second.tunnel_status] ; + grouter_debug() << " Receipt ok: " << (it->second.receipt_item != NULL) ; + grouter_debug() << " Dup: " << it->second.data_item->duplication_factor << std::endl; } grouter_debug() << " Tunnels: " << std::endl; @@ -2251,8 +2378,8 @@ void p3GRouter::debugDump() grouter_debug() << " Routing matrix: " << std::endl; - if(_debug_enabled) - _routing_matrix.debugDump() ; + // if(_debug_enabled) + // _routing_matrix.debugDump() ; } diff --git a/libretroshare/src/grouter/p3grouter.h b/libretroshare/src/grouter/p3grouter.h index 45072425f..82b64881e 100644 --- a/libretroshare/src/grouter/p3grouter.h +++ b/libretroshare/src/grouter/p3grouter.h @@ -272,8 +272,9 @@ private: //bool locked_getGxsIdAndClientId(const TurtleFileHash &sum,RsGxsId& gxs_id,GRouterServiceId& client_id); bool locked_sendTransactionData(const RsPeerId& pid,const RsGRouterTransactionItem& item); - void locked_collectAvailableFriends(const GRouterKeyId &gxs_id,std::list& friend_peers, const std::set& incoming_routes,bool is_origin); - void locked_collectAvailableTunnels(const TurtleFileHash& hash,std::list& tunnel_peers); + void locked_collectAvailableFriends(const GRouterKeyId &gxs_id, const std::set& incoming_routes,uint32_t duplication_factor, std::map &friend_peers_and_duplication_factors); + void locked_collectAvailableTunnels(const TurtleFileHash& hash, uint32_t total_duplication, std::map &tunnel_peers_and_duplication_factors); + void locked_sendToPeers(RsGRouterGenericDataItem *data_item, const std::map &peers_and_duplication_factors); //===================================================// // p3Config methods // diff --git a/libretroshare/src/retroshare/rsgrouter.h b/libretroshare/src/retroshare/rsgrouter.h index acd3aee10..f0bec2677 100644 --- a/libretroshare/src/retroshare/rsgrouter.h +++ b/libretroshare/src/retroshare/rsgrouter.h @@ -50,6 +50,7 @@ public: time_t last_tunnel_attempt_time; time_t last_sent_time; bool receipt_available ; + uint32_t duplication_factor ; uint32_t data_status ; uint32_t tunnel_status ; uint32_t data_size ; diff --git a/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp b/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp index 60a6519ba..1ec95b2f3 100644 --- a/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp +++ b/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.cpp @@ -43,15 +43,16 @@ #include "util/QtVersion.h" #include "util/misc.h" -#define COL_ID 0 -#define COL_NICKNAME 1 -#define COL_DESTINATION 2 -#define COL_DATASTATUS 3 -#define COL_TUNNELSTATUS 4 -#define COL_DATASIZE 5 -#define COL_DATAHASH 6 -#define COL_RECEIVED 7 -#define COL_SEND 8 +#define COL_ID 0 +#define COL_NICKNAME 1 +#define COL_DESTINATION 2 +#define COL_DATASTATUS 3 +#define COL_TUNNELSTATUS 4 +#define COL_DATASIZE 5 +#define COL_DATAHASH 6 +#define COL_RECEIVED 7 +#define COL_SEND 8 +#define COL_DUPLICATION_FACTOR 9 static const int PARTIAL_VIEW_SIZE = 5 ; static const int MAX_TUNNEL_REQUESTS_DISPLAY = 10 ; @@ -187,6 +188,7 @@ void GlobalRouterStatistics::updateContent() item -> setData(COL_DATAHASH, Qt::DisplayRole, QString::fromStdString(cache_infos[i].item_hash.toStdString())); item -> setData(COL_RECEIVED, Qt::DisplayRole, QString::number(now - cache_infos[i].routing_time)); item -> setData(COL_SEND, Qt::DisplayRole, QString::number(now - cache_infos[i].last_sent_time)); + item -> setData(COL_DUPLICATION_FACTOR, Qt::DisplayRole, QString::number(cache_infos[i].duplication_factor)); } } @@ -333,6 +335,9 @@ void GlobalRouterStatisticsWidget::updateContent() mMinWheelZoneX = ox+2*cellx ; mMinWheelZoneY = oy ; + RsGxsId current_id ; + float current_width=0 ; + for(std::map >::const_iterator it(matrix_info.per_friend_probabilities.begin());it!=matrix_info.per_friend_probabilities.end();++it,++n) if(n >= mCurrentN-PARTIAL_VIEW_SIZE/2 && n <= mCurrentN+PARTIAL_VIEW_SIZE/2) { @@ -355,12 +360,19 @@ void GlobalRouterStatisticsWidget::updateContent() { current_probs = it->second ; current_oy = oy ; + current_id = it->first ; + current_width = ox+matrix_info.friend_ids.size()*cellx+fm_monospace.width(ids); } oy += celly ; //} } + + RsIdentityDetails iddetails ; + if(rsIdentity->getIdDetails(current_id,iddetails)) + painter.drawText(current_width+cellx, current_oy+celly, QString::fromUtf8(iddetails.mNickname.c_str())) ; + mMaxWheelZoneY = oy+celly ; painter.setPen(QColor::fromRgb(0,0,0)) ; @@ -382,7 +394,7 @@ void GlobalRouterStatisticsWidget::updateContent() painter.drawLine(x1,y1,x1,y2); painter.drawLine(x1,y2,x1 + total_length - i*cellx,y2) ; - painter.drawText(cellx+ x1 + total_length - i*cellx,y2+(0.35)*celly, QString::fromUtf8(peer_ssl_details.name.c_str()) + " ("+QString::number(current_probs[i])+")"); + painter.drawText(cellx+ x1 + total_length - i*cellx,y2+(0.35)*celly, QString::fromUtf8(peer_ssl_details.name.c_str()) + " - " + QString::fromUtf8(peer_ssl_details.location.c_str()) + " ("+QString::number(current_probs[i])+")"); } oy += celly * (2+matrix_info.friend_ids.size()); diff --git a/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.ui b/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.ui index 38890fa2f..b8499a5bb 100644 --- a/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.ui +++ b/retroshare-gui/src/gui/statistics/GlobalRouterStatistics.ui @@ -35,7 +35,7 @@ 0 0 593 - 159 + 156 @@ -101,6 +101,11 @@ Send + + + Branching factor + +