From d3051eff1a121e965b479771487d209b17c9d50b Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 21 Dec 2016 00:34:07 +0100 Subject: [PATCH] added display of usage statistics for GXS identities --- libretroshare/src/gxs/rsgenexchange.h | 2 ++ libretroshare/src/gxs/rsgxsutil.cc | 20 +++++-------- libretroshare/src/pqi/p3servicecontrol.cc | 14 +++++++++ libretroshare/src/pqi/p3servicecontrol.h | 1 + libretroshare/src/retroshare/rsidentity.h | 3 +- .../src/retroshare/rsservicecontrol.h | 1 + libretroshare/src/services/p3idservice.cc | 29 +++++++++++++++++-- retroshare-gui/src/gui/Identity/IdDialog.cpp | 18 ++++++++++++ retroshare-gui/src/gui/Identity/IdDialog.ui | 14 ++++++++- 9 files changed, 85 insertions(+), 17 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index a391d47e0..2fc2ef6f7 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -656,6 +656,8 @@ public: virtual void setSyncPeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) ; uint16_t serviceType() const { return mServType ; } + uint16_t serviceFullType() const { return ((uint32_t)mServType << 8) + (((uint32_t) RS_PKT_VERSION_SERVICE) << 24); } + protected: /** Notifications **/ diff --git a/libretroshare/src/gxs/rsgxsutil.cc b/libretroshare/src/gxs/rsgxsutil.cc index 0b679fd41..7fa83e3b0 100644 --- a/libretroshare/src/gxs/rsgxsutil.cc +++ b/libretroshare/src/gxs/rsgxsutil.cc @@ -139,7 +139,7 @@ bool RsGxsIntegrityCheck::check() GxsMsgReq msgIds; GxsMsgReq grps; - std::set used_gxs_ids ; + std::map used_gxs_ids ; std::set subscribed_groups ; // compute hash and compare to stored value, if it fails then simply add it @@ -172,7 +172,7 @@ bool RsGxsIntegrityCheck::check() #endif if(rsIdentity!=NULL && !rsIdentity->isBanned(grp->metaData->mAuthorId)) - used_gxs_ids.insert(grp->metaData->mAuthorId) ; + used_gxs_ids.insert(std::make_pair(grp->metaData->mAuthorId,grp->grpId)) ; } } } @@ -270,7 +270,7 @@ bool RsGxsIntegrityCheck::check() GXSUTIL_DEBUG() << "TimeStamping message authors' key ID " << msg->metaData->mAuthorId << " in message " << msg->msgId << ", group ID " << msg->grpId<< std::endl; #endif if(rsIdentity!=NULL && !rsIdentity->isBanned(msg->metaData->mAuthorId)) - used_gxs_ids.insert(msg->metaData->mAuthorId) ; + used_gxs_ids.insert(std::make_pair(msg->metaData->mAuthorId,msg->metaData->mGroupId)) ; } delete msg; @@ -297,9 +297,9 @@ bool RsGxsIntegrityCheck::check() std::list connected_friends ; rsPeers->getOnlineList(connected_friends) ; - std::vector gxs_ids ; + std::vector > gxs_ids ; - for(std::set::const_iterator it(used_gxs_ids.begin());it!=used_gxs_ids.end();++it) + for(std::map::const_iterator it(used_gxs_ids.begin());it!=used_gxs_ids.end();++it) { gxs_ids.push_back(*it) ; #ifdef DEBUG_GXSUTIL @@ -321,9 +321,9 @@ bool RsGxsIntegrityCheck::check() GXSUTIL_DEBUG() << " requesting ID " << gxs_ids[n] ; #endif - if(!mGixs->haveKey(gxs_ids[n])) // checks if we have it already in the cache (conservative way to ensure that we atually have it) + if(!mGixs->haveKey(gxs_ids[n].first)) // checks if we have it already in the cache (conservative way to ensure that we atually have it) { - mGixs->requestKey(gxs_ids[n],connected_friends); + mGixs->requestKey(gxs_ids[n].first,connected_friends); ++nb_requested_not_in_cache ; #ifdef DEBUG_GXSUTIL @@ -335,12 +335,8 @@ bool RsGxsIntegrityCheck::check() #ifdef DEBUG_GXSUTIL GXSUTIL_DEBUG() << " ... already in cache" << std::endl; #endif - - // Note: we could time_stamp even in the case where the id is not cached. Anyway, it's not really a problem here, since IDs have a high chance of - // behing eventually stamped. - - mGixs->timeStampKey(gxs_ids[n],"Used in service (Integrity check)") ; } + mGixs->timeStampKey(gxs_ids[n].first,"Author in group " + gxs_ids[n].second.toStdString() + " of service \"" + rsServiceControl->getServiceName(mGenExchangeClient->serviceFullType())) ; gxs_ids[n] = gxs_ids[gxs_ids.size()-1] ; gxs_ids.pop_back() ; diff --git a/libretroshare/src/pqi/p3servicecontrol.cc b/libretroshare/src/pqi/p3servicecontrol.cc index 11dd01520..a397a4e1c 100644 --- a/libretroshare/src/pqi/p3servicecontrol.cc +++ b/libretroshare/src/pqi/p3servicecontrol.cc @@ -362,6 +362,20 @@ void p3ServiceControl::getServiceChanges(std::set &updateSet) mUpdatedSet.clear(); } +std::string p3ServiceControl::getServiceName(uint32_t service_id) +{ + RsStackMutex stack(mCtrlMtx); /***** LOCK STACK MUTEX ****/ + + std::map::const_iterator it = mOwnServices.find(service_id) ; + + if(it == mOwnServices.end()) + { + std::cerr << "(EE) Cannot find own service for ID = " << std::hex << service_id << std::dec << std::endl; + return std::string(); + } + + return it->second.mServiceName; +} bool p3ServiceControl::getOwnServices(RsPeerServiceInfo &info) { diff --git a/libretroshare/src/pqi/p3servicecontrol.h b/libretroshare/src/pqi/p3servicecontrol.h index e2a27ddc3..948481a2b 100644 --- a/libretroshare/src/pqi/p3servicecontrol.h +++ b/libretroshare/src/pqi/p3servicecontrol.h @@ -85,6 +85,7 @@ virtual const RsPeerId& getOwnId(); */ virtual bool getOwnServices(RsPeerServiceInfo &info); +virtual std::string getServiceName(uint32_t service_id) ; // This is what is passed to peers, can be displayed by GUI too. virtual bool getServicesAllowed(const RsPeerId &peerId, RsPeerServiceInfo &info); diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index e7a7abbe8..4a48b747c 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -184,7 +184,7 @@ public: // Cyril: Reputation details. At some point we might want to merge information // between the two into a single global score. Since the old reputation system // is not finished yet, I leave this in place. We should decide what to do with it. - +#warning (cyril) possibly remove this old reputation field. GxsReputation mReputation_oldSystem; // this is the old "mReputation" field, which apparently is not used. RsReputations::ReputationInfo mReputation; @@ -193,6 +193,7 @@ public: // last usage time_t mLastUsageTS ; + std::map mUseCases ; }; diff --git a/libretroshare/src/retroshare/rsservicecontrol.h b/libretroshare/src/retroshare/rsservicecontrol.h index 76c2ee811..a6d8fde7c 100644 --- a/libretroshare/src/retroshare/rsservicecontrol.h +++ b/libretroshare/src/retroshare/rsservicecontrol.h @@ -108,6 +108,7 @@ class RsServiceControl virtual ~RsServiceControl() { return; } virtual bool getOwnServices(RsPeerServiceInfo &info) = 0; +virtual std::string getServiceName(uint32_t service_id) = 0; virtual bool getServicesAllowed(const RsPeerId &peerId, RsPeerServiceInfo &info) = 0; virtual bool getServicesProvided(const RsPeerId &peerId, RsPeerServiceInfo &info) = 0; diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index c4ae86f52..429562a18 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -279,10 +279,24 @@ void p3IdService::timeStampKey(const RsGxsId& gxs_id, const std::string& reason) keyTSInfo& info(mKeysTS[gxs_id]) ; info.TS = now ; - info.usage_map[now] = reason ; + info.usage_map[reason] = now; while(info.usage_map.size() > GXS_MAX_KEY_TS_USAGE_MAP_SIZE) - info.usage_map.erase(info.usage_map.begin()); + { + // This is very costly, but normally the outerloop should never be rolled more than once. + + std::map::iterator best_it ; + time_t best_time = now+1; + + for(std::map::iterator it(info.usage_map.begin());it!=info.usage_map.end();++it) + if(it->second < best_time) + { + best_time = it->second ; + best_it = it; + } + + info.usage_map.erase(best_it) ; + } slowIndicateConfigChanged() ; } @@ -566,7 +580,16 @@ bool p3IdService::getIdDetails(const RsGxsId &id, RsIdentityDetails &details) rsReputations->setOwnOpinion(id,RsReputations::OPINION_POSITIVE) ; details = data.details; - details.mLastUsageTS = locked_getLastUsageTS(id) ; + + std::map::const_iterator it = mKeysTS.find(id) ; + + if(it == mKeysTS.end()) + details.mLastUsageTS = 0 ; + else + { + details.mLastUsageTS = it->second.TS ; + details.mUseCases = it->second.usage_map ; + } // one utf8 symbol can be at most 4 bytes long - would be better to measure real unicode length !!! if(details.mNickname.length() > RSID_MAXIMUM_NICKNAME_SIZE*4) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 20bef5ccf..0ca6be250 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -1849,6 +1849,24 @@ void IdDialog::insertIdDetails(uint32_t token) default: std::cerr << "Unexpected value in own opinion: " << info.mOwnOpinion << std::endl; } + + // now fill in usage cases + + RsIdentityDetails det ; + rsIdentity->getIdDetails(RsGxsId(data.mMeta.mGroupId),det) ; + + QString usage_txt ; + std::map rmap ; + for(std::map::const_iterator it(det.mUseCases.begin());it!=det.mUseCases.end();++it) + rmap.insert(std::make_pair(it->second,it->first)) ; + + for(std::map::const_iterator it(rmap.begin());it!=rmap.end();++it) + usage_txt += QString("")+ getHumanReadableDuration(now - data.mLastUsageTS) + " \t: " + QString::fromStdString(it->second) + "
" ; + + if(usage_txt.isNull()) + usage_txt = tr("[Unused]") ; + + ui->usageStatistics_TB->setText(usage_txt) ; } void IdDialog::modifyReputation() diff --git a/retroshare-gui/src/gui/Identity/IdDialog.ui b/retroshare-gui/src/gui/Identity/IdDialog.ui index bb075b56f..3dceaa373 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.ui +++ b/retroshare-gui/src/gui/Identity/IdDialog.ui @@ -7,7 +7,7 @@ 0 0 1269 - 911 + 1040 @@ -595,6 +595,18 @@ p, li { white-space: pre-wrap; } + + + + Usage statistics + + + + + + + +