improved network statistics for GXS net service. Added number of available messages for unsubscribed forums in GUI. Should be done as well for channels.

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7760 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2014-12-16 06:54:15 +00:00
parent d4dad8328f
commit 93f77a0e2c
15 changed files with 186 additions and 113 deletions

View File

@ -327,7 +327,7 @@ RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c)
// local meta // local meta
grpMeta->mSubscribeFlags = c.getInt32(COL_GRP_SUBCR_FLAG); grpMeta->mSubscribeFlags = c.getInt32(COL_GRP_SUBCR_FLAG);
grpMeta->mPop = c.getInt32(COL_GRP_POP); grpMeta->mPop = c.getInt32(COL_GRP_POP);
grpMeta->mMsgCount = c.getInt32(COL_MSG_COUNT); grpMeta->mVisibleMsgCount = c.getInt32(COL_MSG_COUNT);
grpMeta->mLastPost = c.getInt32(COL_GRP_LAST_POST); grpMeta->mLastPost = c.getInt32(COL_GRP_LAST_POST);
grpMeta->mGroupStatus = c.getInt32(COL_GRP_STATUS); grpMeta->mGroupStatus = c.getInt32(COL_GRP_STATUS);
@ -743,7 +743,7 @@ int RsDataService::storeGroup(std::map<RsNxsGrp *, RsGxsGrpMetaData *> &grp)
// local meta data // local meta data
cv.put(KEY_GRP_SUBCR_FLAG, (int32_t)grpMetaPtr->mSubscribeFlags); cv.put(KEY_GRP_SUBCR_FLAG, (int32_t)grpMetaPtr->mSubscribeFlags);
cv.put(KEY_GRP_POP, (int32_t)grpMetaPtr->mPop); cv.put(KEY_GRP_POP, (int32_t)grpMetaPtr->mPop);
cv.put(KEY_MSG_COUNT, (int32_t)grpMetaPtr->mMsgCount); cv.put(KEY_MSG_COUNT, (int32_t)grpMetaPtr->mVisibleMsgCount);
cv.put(KEY_GRP_STATUS, (int32_t)grpMetaPtr->mGroupStatus); cv.put(KEY_GRP_STATUS, (int32_t)grpMetaPtr->mGroupStatus);
cv.put(KEY_GRP_LAST_POST, (int32_t)grpMetaPtr->mLastPost); cv.put(KEY_GRP_LAST_POST, (int32_t)grpMetaPtr->mLastPost);
@ -838,7 +838,7 @@ int RsDataService::updateGroup(std::map<RsNxsGrp *, RsGxsGrpMetaData *> &grp)
// local meta data // local meta data
cv.put(KEY_GRP_SUBCR_FLAG, (int32_t)grpMetaPtr->mSubscribeFlags); cv.put(KEY_GRP_SUBCR_FLAG, (int32_t)grpMetaPtr->mSubscribeFlags);
cv.put(KEY_GRP_POP, (int32_t)grpMetaPtr->mPop); cv.put(KEY_GRP_POP, (int32_t)grpMetaPtr->mPop);
cv.put(KEY_MSG_COUNT, (int32_t)grpMetaPtr->mMsgCount); cv.put(KEY_MSG_COUNT, (int32_t)grpMetaPtr->mVisibleMsgCount);
cv.put(KEY_GRP_STATUS, (int32_t)grpMetaPtr->mGroupStatus); cv.put(KEY_GRP_STATUS, (int32_t)grpMetaPtr->mGroupStatus);
cv.put(KEY_GRP_LAST_POST, (int32_t)grpMetaPtr->mLastPost); cv.put(KEY_GRP_LAST_POST, (int32_t)grpMetaPtr->mLastPost);

View File

@ -75,6 +75,23 @@ public:
}; };
/*!
* This is used to query network statistics for a given group. This is useful to e.g. show group
* popularity, or number of visible messages for unsubscribed group.
*/
class RsGroupNetworkStats
{
public:
RsGroupNetworkStats()
{
mMaxVisibleCount = 0 ;
}
uint32_t mSuppliers ;
uint32_t mMaxVisibleCount ;
};
typedef std::map<RsGxsGroupId, std::vector<RsNxsMsg*> > NxsMsgDataResult; typedef std::map<RsGxsGroupId, std::vector<RsNxsMsg*> > NxsMsgDataResult;
typedef std::map<RsGxsGrpMsgIdPair, std::vector<RsNxsMsg*> > NxsMsgRelatedDataResult; typedef std::map<RsGxsGrpMsgIdPair, std::vector<RsNxsMsg*> > NxsMsgRelatedDataResult;
typedef std::map<RsGxsGroupId, std::vector<RsNxsMsg*> > GxsMsgResult; // <grpId, msgs> typedef std::map<RsGxsGroupId, std::vector<RsNxsMsg*> > GxsMsgResult; // <grpId, msgs>

View File

@ -1146,11 +1146,18 @@ bool RsGenExchange::getGroupMeta(const uint32_t &token, std::list<RsGroupMetaDat
{ {
RsGxsGrpMetaData& gMeta = *(*lit); RsGxsGrpMetaData& gMeta = *(*lit);
m = gMeta; m = gMeta;
RsGroupNetworkStats sts ;
if(mNetService != NULL) if(mNetService != NULL && mNetService->getGroupNetworkStats((*lit)->mGroupId,sts))
m.mPop = mNetService->getGroupPopularity((*lit)->mGroupId) ; {
m.mPop = sts.mSuppliers ;
m.mVisibleMsgCount = sts.mMaxVisibleCount ;
}
else else
{
m.mPop= 0 ; m.mPop= 0 ;
m.mVisibleMsgCount = 0 ;
}
groupInfo.push_back(m); groupInfo.push_back(m);
delete (*lit); delete (*lit);
@ -1251,10 +1258,18 @@ bool RsGenExchange::getGroupData(const uint32_t &token, std::vector<RsGxsGrpItem
{ {
gItem->meta = *((*lit)->metaData); gItem->meta = *((*lit)->metaData);
if(mNetService != NULL) RsGroupNetworkStats sts ;
gItem->meta.mPop = mNetService->getGroupPopularity(gItem->meta.mGroupId) ;
if(mNetService != NULL && mNetService->getGroupNetworkStats(gItem->meta.mGroupId,sts))
{
gItem->meta.mPop = sts.mSuppliers ;
gItem->meta.mVisibleMsgCount = sts.mMaxVisibleCount;
}
else else
gItem->meta.mPop= 0 ; {
gItem->meta.mPop = 0 ;
gItem->meta.mVisibleMsgCount = 0 ;
}
grpItem.push_back(gItem); grpItem.push_back(gItem);
} }
else else

View File

@ -77,7 +77,7 @@ void RsGxsGrpMetaData::clear(){
mSubscribeFlags = 0; mSubscribeFlags = 0;
mPop = 0; mPop = 0;
mMsgCount = 0; mVisibleMsgCount = 0;
mGroupStatus = 0; mGroupStatus = 0;
mLastPost = 0; mLastPost = 0;
mReputationCutOff = 0; mReputationCutOff = 0;
@ -289,7 +289,7 @@ void RsGxsGrpMetaData::operator =(const RsGroupMetaData& rMeta)
this->mGroupId = rMeta.mGroupId; this->mGroupId = rMeta.mGroupId;
this->mGroupStatus = rMeta.mGroupStatus ; this->mGroupStatus = rMeta.mGroupStatus ;
this->mLastPost = rMeta.mLastPost; this->mLastPost = rMeta.mLastPost;
this->mMsgCount = rMeta.mMsgCount ; this->mVisibleMsgCount = rMeta.mVisibleMsgCount ;
this->mPop = rMeta.mPop; this->mPop = rMeta.mPop;
this->mPublishTs = rMeta.mPublishTs; this->mPublishTs = rMeta.mPublishTs;
this->mSubscribeFlags = rMeta.mSubscribeFlags; this->mSubscribeFlags = rMeta.mSubscribeFlags;

View File

@ -71,9 +71,9 @@ public:
uint32_t mSubscribeFlags; uint32_t mSubscribeFlags;
uint32_t mPop; // HOW DO WE DO THIS NOW. uint32_t mPop; // Number of friends who subscribed
uint32_t mMsgCount; // ??? uint32_t mVisibleMsgCount; // Max number of messages reported by a single friend (used for unsubscribed groups)
uint32_t mLastPost; // ??? uint32_t mLastPost; // Time stamp of last post (not yet filled)
uint32_t mReputationCutOff; uint32_t mReputationCutOff;
uint32_t mGrpSize; uint32_t mGrpSize;

View File

@ -37,7 +37,6 @@
/*** /***
* #define NXS_NET_DEBUG 1 * #define NXS_NET_DEBUG 1
***/ ***/
// #define NXS_NET_DEBUG 1
#define GIXS_CUT_OFF 0 #define GIXS_CUT_OFF 0
@ -278,11 +277,11 @@ void RsGxsNetService::syncWithPeers()
{ {
RsGxsGrpMetaData* meta = mit->second; RsGxsGrpMetaData* meta = mit->second;
if(meta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED ) // if(meta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED )
{ // {
toRequest.insert(std::make_pair(mit->first, meta)); toRequest.insert(std::make_pair(mit->first, meta));
}else // }else
delete meta; // delete meta;
} }
grpMeta.clear(); grpMeta.clear();
@ -1434,16 +1433,19 @@ void RsGxsNetService::processTransactions()
} }
} }
int RsGxsNetService::getGroupPopularity(const RsGxsGroupId& gid) bool RsGxsNetService::getGroupNetworkStats(const RsGxsGroupId& gid,RsGroupNetworkStats& stats)
{ {
RS_STACK_MUTEX(mNxsMutex) ; RS_STACK_MUTEX(mNxsMutex) ;
std::map<RsGxsGroupId,std::set<RsPeerId> >::const_iterator it = mGroupSuppliers.find(gid) ; std::map<RsGxsGroupId,RsGroupNetworkStatsRecord>::const_iterator it = mGroupNetworkStats.find(gid) ;
if(it == mGroupSuppliers.end()) if(it == mGroupNetworkStats.end())
return 0 ; return false ;
else
return it->second.size(); stats.mSuppliers = it->second.suppliers.size();
stats.mMaxVisibleCount = it->second.max_visible_count ;
return true ;
} }
void RsGxsNetService::processCompletedTransactions() void RsGxsNetService::processCompletedTransactions()
@ -1820,6 +1822,15 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
RsNxsSyncMsgItem* item = msgItemL.front(); RsNxsSyncMsgItem* item = msgItemL.front();
const RsGxsGroupId& grpId = item->grpId; const RsGxsGroupId& grpId = item->grpId;
// store the count for the peer who sent the message list
uint32_t mcount = msgItemL.size() ;
RsPeerId pid = msgItemL.front()->PeerId() ;
RsGroupNetworkStatsRecord& gnsr = mGroupNetworkStats[grpId];
gnsr.suppliers.insert(pid) ;
gnsr.max_visible_count = std::max(gnsr.max_visible_count, mcount) ;
#ifdef NXS_NET_DEBUG #ifdef NXS_NET_DEBUG
std::cerr << " grpId = " << grpId << std::endl; std::cerr << " grpId = " << grpId << std::endl;
std::cerr << " retrieving grp mesta data..." << std::endl; std::cerr << " retrieving grp mesta data..." << std::endl;
@ -1829,6 +1840,9 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
mDataStore->retrieveGxsGrpMetaData(grpMetaMap); mDataStore->retrieveGxsGrpMetaData(grpMetaMap);
RsGxsGrpMetaData* grpMeta = grpMetaMap[grpId]; RsGxsGrpMetaData* grpMeta = grpMetaMap[grpId];
if(! (grpMeta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED ))
return ;
int cutoff = 0; int cutoff = 0;
if(grpMeta != NULL) if(grpMeta != NULL)
cutoff = grpMeta->mReputationCutOff; cutoff = grpMeta->mReputationCutOff;
@ -2864,7 +2878,7 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsg* item)
// We do that early, so as to get info about who sends data about which group, // We do that early, so as to get info about who sends data about which group,
// even when the group doesn't need update. // even when the group doesn't need update.
mGroupSuppliers[item->grpId].insert(item->PeerId()) ; mGroupNetworkStats[item->grpId].suppliers.insert(item->PeerId()) ;
if(!locked_CanReceiveUpdate(item)) if(!locked_CanReceiveUpdate(item))
return; return;

View File

@ -48,6 +48,15 @@ typedef std::map<RsPeerId, TransactionIdMap > TransactionsPeerMap;
class PgpAuxUtils; class PgpAuxUtils;
class RsGroupNetworkStatsRecord
{
public:
RsGroupNetworkStatsRecord() { max_visible_count= 0 ; }
std::set<RsPeerId> suppliers ;
uint32_t max_visible_count ;
};
/*! /*!
* This class implements the RsNetWorkExchangeService * This class implements the RsNetWorkExchangeService
* using transactions to handle synchrnisation of Nxs items between * using transactions to handle synchrnisation of Nxs items between
@ -128,7 +137,11 @@ public:
virtual int sharePublishKey(const RsGxsGroupId& grpId,const std::list<RsPeerId>& peers) ; virtual int sharePublishKey(const RsGxsGroupId& grpId,const std::list<RsPeerId>& peers) ;
virtual int getGroupPopularity(const RsGxsGroupId& id) ; /*!
* Returns statistics for the group networking activity: popularity (number of friends subscribers) and max_visible_msg_count,
* that is the max nnumber of messages reported by a friend.
*/
virtual bool getGroupNetworkStats(const RsGxsGroupId& id,RsGroupNetworkStats& stats) ;
/* p3Config methods */ /* p3Config methods */
public: public:
@ -477,7 +490,7 @@ private:
ServerMsgMap mServerMsgUpdateMap; ServerMsgMap mServerMsgUpdateMap;
ClientGrpMap mClientGrpUpdateMap; ClientGrpMap mClientGrpUpdateMap;
std::map<RsGxsGroupId,std::set<RsPeerId> > mGroupSuppliers ; std::map<RsGxsGroupId,RsGroupNetworkStatsRecord> mGroupNetworkStats ;
RsGxsServerGrpUpdateItem* mGrpServerUpdateItem; RsGxsServerGrpUpdateItem* mGrpServerUpdateItem;
RsServiceInfo mServiceInfo; RsServiceInfo mServiceInfo;

View File

@ -111,6 +111,12 @@ public:
*/ */
virtual int requestGrp(const std::list<RsGxsGroupId>& grpId, const RsPeerId& peerId) = 0; virtual int requestGrp(const std::list<RsGxsGroupId>& grpId, const RsPeerId& peerId) = 0;
/*!
* returns some stats about this group related to the network visibility.
* For now, only one statistics:
* max_known_messages: max number of messages reported by a friend. This is used to display unsubscribed group content.
*/
virtual bool getGroupNetworkStats(const RsGxsGroupId& grpId,RsGroupNetworkStats& stats)=0;
/*! /*!
* Request for this group is sent through to peers on your network * Request for this group is sent through to peers on your network
@ -118,12 +124,6 @@ public:
*/ */
virtual int sharePublishKey(const RsGxsGroupId& grpId,const std::list<RsPeerId>& peers)=0 ; virtual int sharePublishKey(const RsGxsGroupId& grpId,const std::list<RsPeerId>& peers)=0 ;
/*!
* Request the number of peers who sent info about this group, as an indicator
* of group popularity.
*/
virtual int getGroupPopularity(const RsGxsGroupId& id) = 0 ;
}; };
#endif // RSGNP_H #endif // RSGNP_H

View File

@ -44,7 +44,7 @@ public:
mSubscribeFlags = 0; mSubscribeFlags = 0;
mPop = 0; mPop = 0;
mMsgCount = 0; mVisibleMsgCount = 0;
mLastPost = 0; mLastPost = 0;
mGroupStatus = 0; mGroupStatus = 0;
@ -76,9 +76,9 @@ public:
uint32_t mSubscribeFlags; uint32_t mSubscribeFlags;
uint32_t mPop; // HOW DO WE DO THIS NOW. uint32_t mPop; // Popularity = number of friend subscribers
uint32_t mMsgCount; // ??? uint32_t mVisibleMsgCount; // Max messages reported by friends
time_t mLastPost; // ??? time_t mLastPost; // Timestamp for last message. Not used yet.
uint32_t mGroupStatus; uint32_t mGroupStatus;
std::string mServiceString; // Service Specific Free-Form extra storage. std::string mServiceString; // Service Specific Free-Form extra storage.
@ -148,7 +148,8 @@ public:
public: public:
/// number of message /// number of message
RsGxsGroupId mGrpId; RsGxsGroupId mGrpId;
uint32_t mNumMsgs;
uint32_t mNumMsgs; // from the database
uint32_t mTotalSizeOfMsgs; uint32_t mTotalSizeOfMsgs;
uint32_t mNumThreadMsgsNew; uint32_t mNumThreadMsgsNew;
uint32_t mNumThreadMsgsUnread; uint32_t mNumThreadMsgsUnread;

View File

@ -35,7 +35,7 @@
this->mGroupId = rGxsMeta.mGroupId; this->mGroupId = rGxsMeta.mGroupId;
this->mGroupStatus = rGxsMeta.mGroupStatus; this->mGroupStatus = rGxsMeta.mGroupStatus;
this->mLastPost = rGxsMeta.mLastPost; this->mLastPost = rGxsMeta.mLastPost;
this->mMsgCount = rGxsMeta.mMsgCount; this->mVisibleMsgCount = rGxsMeta.mVisibleMsgCount;
this->mPop = rGxsMeta.mPop; this->mPop = rGxsMeta.mPop;
this->mPublishTs = rGxsMeta.mPublishTs; this->mPublishTs = rGxsMeta.mPublishTs;
this->mSubscribeFlags = rGxsMeta.mSubscribeFlags; this->mSubscribeFlags = rGxsMeta.mSubscribeFlags;

View File

@ -45,7 +45,6 @@
/**** /****
* #define GXSCHANNEL_DEBUG 1 * #define GXSCHANNEL_DEBUG 1
****/ ****/
#define GXSCHANNEL_DEBUG 1
RsGxsChannels *rsGxsChannels = NULL; RsGxsChannels *rsGxsChannels = NULL;

View File

@ -22,6 +22,7 @@
#include <QMenu> #include <QMenu>
#include <QToolButton> #include <QToolButton>
#include "retroshare/rsgxsflags.h"
#include "GroupTreeWidget.h" #include "GroupTreeWidget.h"
#include "ui_GroupTreeWidget.h" #include "ui_GroupTreeWidget.h"
@ -354,6 +355,7 @@ void GroupTreeWidget::fillGroupItems(QTreeWidgetItem *categoryItem, const QList<
/* Set popularity */ /* Set popularity */
QString tooltip = PopularityDefs::tooltip(itemInfo.popularity); QString tooltip = PopularityDefs::tooltip(itemInfo.popularity);
item->setIcon(COLUMN_POPULARITY, PopularityDefs::icon(itemInfo.popularity)); item->setIcon(COLUMN_POPULARITY, PopularityDefs::icon(itemInfo.popularity));
item->setData(COLUMN_DATA, ROLE_POPULARITY, -itemInfo.popularity); // negative for correct sorting item->setData(COLUMN_DATA, ROLE_POPULARITY, -itemInfo.popularity); // negative for correct sorting
@ -361,6 +363,9 @@ void GroupTreeWidget::fillGroupItems(QTreeWidgetItem *categoryItem, const QList<
if (itemInfo.privatekey) { if (itemInfo.privatekey) {
tooltip += "\n" + tr("Private Key Available"); tooltip += "\n" + tr("Private Key Available");
} }
if(!IS_GROUP_SUBSCRIBED(itemInfo.subscribeFlags))
tooltip += "\n" + QString::number(itemInfo.max_visible_posts) + " messages available" ;
item->setToolTip(COLUMN_NAME, tooltip); item->setToolTip(COLUMN_NAME, tooltip);
item->setToolTip(COLUMN_POPULARITY, tooltip); item->setToolTip(COLUMN_POPULARITY, tooltip);

View File

@ -49,6 +49,7 @@ public:
popularity = 0; popularity = 0;
privatekey = false; privatekey = false;
subscribeFlags = 0; subscribeFlags = 0;
max_visible_posts =0;
} }
public: public:
@ -59,7 +60,8 @@ public:
QDateTime lastpost; QDateTime lastpost;
QIcon icon; QIcon icon;
bool privatekey; bool privatekey;
int subscribeFlags; quint32 subscribeFlags;
quint32 max_visible_posts ;
}; };
class GroupTreeWidget : public QWidget class GroupTreeWidget : public QWidget

View File

@ -61,7 +61,6 @@
* these will need to be addressed in the future. * these will need to be addressed in the future.
* -> Child TS (for sorting) is not handled by GXS, this will probably have to be done in the GUI. * -> Child TS (for sorting) is not handled by GXS, this will probably have to be done in the GUI.
* -> Need to handle IDs properly. * -> Need to handle IDs properly.
* -> Popularity not handled in GXS yet.
* -> Much more to do. * -> Much more to do.
*/ */
@ -655,6 +654,7 @@ void GxsGroupFrameDialog::groupInfoToGroupItemInfo(const RsGroupMetaData &groupI
groupItemInfo.lastpost = QDateTime::fromTime_t(groupInfo.mLastPost); groupItemInfo.lastpost = QDateTime::fromTime_t(groupInfo.mLastPost);
groupItemInfo.subscribeFlags = groupInfo.mSubscribeFlags; groupItemInfo.subscribeFlags = groupInfo.mSubscribeFlags;
groupItemInfo.privatekey = IS_GROUP_PUBLISHER(groupInfo.mSubscribeFlags) ; groupItemInfo.privatekey = IS_GROUP_PUBLISHER(groupInfo.mSubscribeFlags) ;
groupItemInfo.max_visible_posts = groupInfo.mVisibleMsgCount ;
#if TOGXS #if TOGXS
if (groupInfo.mGroupFlags & RS_DISTRIB_AUTHEN_REQ) { if (groupInfo.mGroupFlags & RS_DISTRIB_AUTHEN_REQ) {

View File

@ -692,7 +692,14 @@ void GxsForumThreadWidget::insertGroupData(const RsGxsForumGroup &group)
mSubscribeFlags = group.mMeta.mSubscribeFlags; mSubscribeFlags = group.mMeta.mSubscribeFlags;
ui->forumName->setText(QString::fromUtf8(group.mMeta.mGroupName.c_str())); ui->forumName->setText(QString::fromUtf8(group.mMeta.mGroupName.c_str()));
mForumDescription = QString::fromUtf8(group.mDescription.c_str());
mForumDescription = QString();
mForumDescription += QString("<b>Forum name: \t</b>")+QString::fromStdString( group.mMeta.mGroupName)+"<br/>" ;
mForumDescription += QString("<b>Subscribers: \t</b>")+QString::number( group.mMeta.mPop)+"<br/>" ;
mForumDescription += QString("<b>Posts: \t</b>")+QString::number(group.mMeta.mVisibleMsgCount)+"<br/>" ;
mForumDescription += QString("<b>Description: </b>")+"<br/><br/>" ;
mForumDescription += QString::fromUtf8(group.mDescription.c_str());
ui->subscribeToolButton->setSubscribed(IS_GROUP_SUBSCRIBED(mSubscribeFlags)); ui->subscribeToolButton->setSubscribed(IS_GROUP_SUBSCRIBED(mSubscribeFlags));
mStateHelper->setWidgetEnabled(ui->newthreadButton, (IS_GROUP_SUBSCRIBED(mSubscribeFlags))); mStateHelper->setWidgetEnabled(ui->newthreadButton, (IS_GROUP_SUBSCRIBED(mSubscribeFlags)));