2012-12-02 14:40:17 -05:00
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <math.h>
|
2012-12-05 17:45:44 -05:00
|
|
|
#include <sstream>
|
2012-12-02 14:40:17 -05:00
|
|
|
|
2012-10-05 14:12:52 -04:00
|
|
|
#include "p3posted.h"
|
2012-12-02 14:40:17 -05:00
|
|
|
#include "gxs/rsgxsflags.h"
|
2012-10-21 15:45:35 -04:00
|
|
|
#include "serialiser/rsposteditems.h"
|
|
|
|
|
2012-12-05 17:45:44 -05:00
|
|
|
#define NUM_TOPICS_TO_GENERATE 7
|
|
|
|
#define NUM_POSTS_TO_GENERATE 8
|
|
|
|
#define NUM_VOTES_TO_GENERATE 23
|
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
const uint32_t RsPosted::FLAG_MSGTYPE_COMMENT = 0x0001;
|
|
|
|
const uint32_t RsPosted::FLAG_MSGTYPE_POST = 0x0002;
|
|
|
|
const uint32_t RsPosted::FLAG_MSGTYPE_VOTE = 0x0004;
|
2012-12-02 14:40:17 -05:00
|
|
|
const uint32_t RsPosted::FLAG_MSGTYPE_MASK = 0x000f;
|
|
|
|
|
|
|
|
#define POSTED_MAX_SERVICE_STRING 50
|
2012-10-21 15:45:35 -04:00
|
|
|
|
|
|
|
RsPosted *rsPosted = NULL;
|
2012-10-05 14:12:52 -04:00
|
|
|
|
2012-11-25 16:50:45 -05:00
|
|
|
RsPostedComment::RsPostedComment(const RsGxsPostedCommentItem & item)
|
|
|
|
{
|
|
|
|
mComment = item.mComment.mComment;
|
|
|
|
mMeta = item.meta;
|
|
|
|
}
|
|
|
|
|
2012-12-02 14:40:17 -05:00
|
|
|
RsPostedVote::RsPostedVote(const RsGxsPostedVoteItem& item)
|
|
|
|
{
|
|
|
|
mDirection = item.mVote.mDirection;
|
|
|
|
mMeta = item.meta;
|
|
|
|
}
|
|
|
|
|
2012-10-05 14:12:52 -04:00
|
|
|
p3Posted::p3Posted(RsGeneralDataService *gds, RsNetworkExchangeService *nes)
|
2012-12-02 14:40:17 -05:00
|
|
|
: RsGenExchange(gds, nes, new RsGxsPostedSerialiser(), RS_SERVICE_GXSV1_TYPE_POSTED), RsPosted(this), mPostedMutex("Posted"),
|
2012-12-05 17:45:44 -05:00
|
|
|
mTokenService(NULL), mGeneratingTopics(true), mGeneratingPosts(false)
|
2012-10-05 14:12:52 -04:00
|
|
|
{
|
2012-12-02 14:40:17 -05:00
|
|
|
mTokenService = RsGenExchange::getTokenService();
|
2012-10-05 14:12:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void p3Posted::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|
|
|
{
|
2012-10-17 17:20:57 -04:00
|
|
|
receiveChanges(changes);
|
2012-10-05 14:12:52 -04:00
|
|
|
}
|
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
void p3Posted::service_tick()
|
2012-10-05 14:12:52 -04:00
|
|
|
{
|
2012-12-05 17:45:44 -05:00
|
|
|
generateTopics();
|
|
|
|
|
|
|
|
//generatePosts();
|
|
|
|
}
|
|
|
|
|
|
|
|
void p3Posted::generatePosts()
|
|
|
|
{
|
|
|
|
if(mGeneratingPosts)
|
|
|
|
{
|
|
|
|
// request topics then chose at random which one to use to generate a post about
|
|
|
|
uint32_t token;
|
|
|
|
RsTokReqOptions opts;
|
|
|
|
opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS;
|
|
|
|
mTokenService->requestGroupInfo(token, 0, opts);
|
|
|
|
double timeDelta = 2.; // slow tick
|
|
|
|
while(mTokenService->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
|
|
|
{
|
|
|
|
#ifndef WINDOWS_SYS
|
|
|
|
usleep((int) (timeDelta * 1000000));
|
|
|
|
#else
|
|
|
|
Sleep((int) (timeDelta * 1000));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
std::list<RsGxsGroupId> grpIds;
|
|
|
|
RsGenExchange::getGroupList(token, grpIds);
|
|
|
|
|
|
|
|
|
|
|
|
// for each group generate NUM_POSTS_TO_GENERATE posts
|
|
|
|
std::list<RsGxsGroupId>::iterator lit = grpIds.begin();
|
|
|
|
|
|
|
|
for(; lit != grpIds.end(); lit++)
|
|
|
|
{
|
|
|
|
RsGxsGroupId& grpId = *lit;
|
|
|
|
|
|
|
|
std::vector<uint32_t> tokens;
|
|
|
|
|
|
|
|
for(int i=0; i < NUM_POSTS_TO_GENERATE; i++)
|
|
|
|
{
|
|
|
|
std::ostringstream ostrm;
|
|
|
|
ostrm << i;
|
|
|
|
std::string link = "link" + ostrm.str();
|
|
|
|
|
|
|
|
RsPostedPost post;
|
|
|
|
post.mLink = link;
|
|
|
|
post.mNotes = link;
|
|
|
|
post.mMeta.mMsgName = link;
|
|
|
|
post.mMeta.mGroupId = grpId;
|
|
|
|
|
|
|
|
submitPost(token, post);
|
|
|
|
tokens.push_back(token);
|
|
|
|
}
|
|
|
|
|
|
|
|
while(!tokens.empty())
|
|
|
|
{
|
|
|
|
std::vector<uint32_t>::iterator vit = tokens.begin();
|
|
|
|
|
|
|
|
for(; vit != tokens.end(); )
|
|
|
|
{
|
|
|
|
if(mTokenService->requestStatus(*vit) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
|
|
|
vit = tokens.erase(vit);
|
|
|
|
else
|
|
|
|
vit++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// stop generating posts after acknowledging all the ones you created
|
|
|
|
mGeneratingPosts = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void p3Posted::generateTopics()
|
|
|
|
{
|
|
|
|
if(mGeneratingTopics)
|
|
|
|
{
|
|
|
|
std::vector<uint32_t> tokens;
|
|
|
|
|
|
|
|
for(int i=0; i < NUM_TOPICS_TO_GENERATE; i++)
|
|
|
|
{
|
|
|
|
std::ostringstream strm;
|
|
|
|
strm << i;
|
|
|
|
std::string topicName = "Topic " + strm.str();
|
|
|
|
|
|
|
|
RsPostedGroup topic;
|
|
|
|
topic.mMeta.mGroupName = topicName;
|
|
|
|
|
|
|
|
uint32_t token;
|
|
|
|
submitGroup(token, topic);
|
|
|
|
tokens.push_back(token);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
while(!tokens.empty())
|
|
|
|
{
|
|
|
|
std::vector<uint32_t>::iterator vit = tokens.begin();
|
|
|
|
|
|
|
|
for(; vit != tokens.end(); )
|
|
|
|
{
|
|
|
|
if(mTokenService->requestStatus(*vit) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
|
|
|
vit = tokens.erase(vit);
|
|
|
|
else
|
|
|
|
vit++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mGeneratingTopics = false;
|
|
|
|
mGeneratingPosts = true;
|
|
|
|
}
|
2012-10-05 14:12:52 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
bool p3Posted::getGroup(const uint32_t &token, std::vector<RsPostedGroup> &groups)
|
2012-10-05 14:12:52 -04:00
|
|
|
{
|
2012-10-21 15:45:35 -04:00
|
|
|
std::vector<RsGxsGrpItem*> grpData;
|
|
|
|
bool ok = RsGenExchange::getGroupData(token, grpData);
|
2012-10-05 14:12:52 -04:00
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
if(ok)
|
|
|
|
{
|
|
|
|
std::vector<RsGxsGrpItem*>::iterator vit = grpData.begin();
|
2012-10-05 14:12:52 -04:00
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
for(; vit != grpData.end(); vit++)
|
|
|
|
{
|
|
|
|
RsGxsPostedGroupItem* item = dynamic_cast<RsGxsPostedGroupItem*>(*vit);
|
|
|
|
RsPostedGroup grp = item->mGroup;
|
|
|
|
item->mGroup.mMeta = item->meta;
|
|
|
|
grp.mMeta = item->mGroup.mMeta;
|
|
|
|
delete item;
|
|
|
|
groups.push_back(grp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ok;
|
2012-10-05 14:12:52 -04:00
|
|
|
}
|
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
bool p3Posted::getPost(const uint32_t &token, PostedPostResult &posts)
|
2012-10-05 14:12:52 -04:00
|
|
|
{
|
2012-10-21 15:45:35 -04:00
|
|
|
GxsMsgDataMap msgData;
|
|
|
|
bool ok = RsGenExchange::getMsgData(token, msgData);
|
2012-10-05 14:12:52 -04:00
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
if(ok)
|
|
|
|
{
|
|
|
|
GxsMsgDataMap::iterator mit = msgData.begin();
|
2012-10-05 14:12:52 -04:00
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
for(; mit != msgData.end(); mit++)
|
|
|
|
{
|
|
|
|
RsGxsGroupId grpId = mit->first;
|
|
|
|
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
|
|
|
|
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
|
2012-10-05 14:12:52 -04:00
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
for(; vit != msgItems.end(); vit++)
|
|
|
|
{
|
|
|
|
RsGxsPostedPostItem* item = dynamic_cast<RsGxsPostedPostItem*>(*vit);
|
2012-10-05 14:12:52 -04:00
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
if(item)
|
|
|
|
{
|
|
|
|
RsPostedPost post = item->mPost;
|
|
|
|
post.mMeta = item->meta;
|
|
|
|
posts[grpId].push_back(post);
|
|
|
|
delete item;
|
|
|
|
}else
|
|
|
|
{
|
|
|
|
std::cerr << "Not a post Item, deleting!" << std::endl;
|
|
|
|
delete *vit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-10-05 14:12:52 -04:00
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
return ok;
|
2012-10-05 14:12:52 -04:00
|
|
|
}
|
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
bool p3Posted::getComment(const uint32_t &token, PostedCommentResult &comments)
|
2012-10-05 14:12:52 -04:00
|
|
|
{
|
2012-10-21 15:45:35 -04:00
|
|
|
GxsMsgDataMap msgData;
|
|
|
|
bool ok = RsGenExchange::getMsgData(token, msgData);
|
2012-10-05 14:12:52 -04:00
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
if(ok)
|
|
|
|
{
|
|
|
|
GxsMsgDataMap::iterator mit = msgData.begin();
|
2012-10-05 14:12:52 -04:00
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
for(; mit != msgData.end(); mit++)
|
|
|
|
{
|
|
|
|
RsGxsGroupId grpId = mit->first;
|
|
|
|
std::vector<RsGxsMsgItem*>& msgItems = mit->second;
|
|
|
|
std::vector<RsGxsMsgItem*>::iterator vit = msgItems.begin();
|
2012-10-05 14:12:52 -04:00
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
for(; vit != msgItems.end(); vit++)
|
|
|
|
{
|
|
|
|
RsGxsPostedCommentItem* item = dynamic_cast<RsGxsPostedCommentItem*>(*vit);
|
2012-10-05 14:12:52 -04:00
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
if(item)
|
|
|
|
{
|
|
|
|
RsPostedComment comment = item->mComment;
|
|
|
|
comment.mMeta = item->meta;
|
|
|
|
comments[grpId].push_back(comment);
|
|
|
|
delete item;
|
|
|
|
}else
|
|
|
|
{
|
|
|
|
std::cerr << "Not a comment Item, deleting!" << std::endl;
|
|
|
|
delete *vit;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-10-05 14:12:52 -04:00
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
return ok;
|
2012-10-05 14:12:52 -04:00
|
|
|
}
|
|
|
|
|
2012-11-25 16:50:45 -05:00
|
|
|
bool p3Posted::getRelatedComment(const uint32_t& token, PostedRelatedCommentResult &comments)
|
|
|
|
{
|
|
|
|
return RsGenExchange::getMsgRelatedDataT<RsGxsPostedCommentItem, RsPostedComment>(token, comments);
|
|
|
|
}
|
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
bool p3Posted::submitGroup(uint32_t &token, RsPostedGroup &group)
|
2012-10-05 14:12:52 -04:00
|
|
|
{
|
2012-10-21 15:45:35 -04:00
|
|
|
RsGxsPostedGroupItem* grpItem = new RsGxsPostedGroupItem();
|
|
|
|
grpItem->mGroup = group;
|
|
|
|
grpItem->meta = group.mMeta;
|
|
|
|
RsGenExchange::publishGroup(token, grpItem);
|
|
|
|
return true;
|
2012-10-05 14:12:52 -04:00
|
|
|
}
|
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
bool p3Posted::submitPost(uint32_t &token, RsPostedPost &post)
|
2012-10-05 14:12:52 -04:00
|
|
|
{
|
2012-10-21 15:45:35 -04:00
|
|
|
RsGxsPostedPostItem* postItem = new RsGxsPostedPostItem();
|
|
|
|
postItem->mPost = post;
|
|
|
|
postItem->meta = post.mMeta;
|
|
|
|
postItem->meta.mMsgFlags |= FLAG_MSGTYPE_POST;
|
2012-10-05 14:12:52 -04:00
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
RsGenExchange::publishMsg(token, postItem);
|
|
|
|
return true;
|
2012-10-05 14:12:52 -04:00
|
|
|
}
|
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
bool p3Posted::submitVote(uint32_t &token, RsPostedVote &vote)
|
2012-10-05 14:12:52 -04:00
|
|
|
{
|
2012-10-21 15:45:35 -04:00
|
|
|
RsGxsPostedVoteItem* voteItem = new RsGxsPostedVoteItem();
|
|
|
|
voteItem->mVote = vote;
|
|
|
|
voteItem->meta = vote.mMeta;
|
2012-12-02 14:40:17 -05:00
|
|
|
voteItem->meta.mMsgFlags |= FLAG_MSGTYPE_VOTE;
|
2012-10-05 14:12:52 -04:00
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
RsGenExchange::publishMsg(token, voteItem);
|
|
|
|
return true;
|
2012-10-05 14:12:52 -04:00
|
|
|
}
|
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
bool p3Posted::submitComment(uint32_t &token, RsPostedComment &comment)
|
2012-10-05 14:12:52 -04:00
|
|
|
{
|
2012-10-21 15:45:35 -04:00
|
|
|
RsGxsPostedCommentItem* commentItem = new RsGxsPostedCommentItem();
|
|
|
|
commentItem->mComment = comment;
|
|
|
|
commentItem->meta = comment.mMeta;
|
|
|
|
commentItem->meta.mMsgFlags |= FLAG_MSGTYPE_COMMENT;
|
2012-10-05 14:12:52 -04:00
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
RsGenExchange::publishMsg(token, commentItem);
|
|
|
|
return true;
|
2012-10-05 14:12:52 -04:00
|
|
|
}
|
|
|
|
|
2012-10-21 15:45:35 -04:00
|
|
|
// Special Ranking Request.
|
2012-11-30 13:54:25 -05:00
|
|
|
bool p3Posted::requestCommentRankings(uint32_t &token, const RankType &rType, const RsGxsGrpMsgIdPair &msgId)
|
|
|
|
{
|
|
|
|
token = RsGenExchange::generatePublicToken();
|
|
|
|
|
|
|
|
RsStackMutex stack(mPostedMutex);
|
|
|
|
|
|
|
|
GxsPostedCommentRanking* gpc = new GxsPostedCommentRanking();
|
|
|
|
gpc->msgId = msgId;
|
|
|
|
gpc->rType = rType;
|
|
|
|
gpc->pubToken = token;
|
|
|
|
|
|
|
|
mPendingCommentRanks.insert(std::make_pair(token, gpc));
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool p3Posted::requestMessageRankings(uint32_t &token, const RankType &rType, const RsGxsGroupId &groupId)
|
|
|
|
{
|
|
|
|
token = RsGenExchange::generatePublicToken();
|
|
|
|
|
|
|
|
RsStackMutex stack(mPostedMutex);
|
|
|
|
GxsPostedPostRanking* gp = new GxsPostedPostRanking();
|
|
|
|
gp->grpId = groupId;
|
|
|
|
gp->rType = rType;
|
|
|
|
gp->pubToken = token;
|
|
|
|
|
|
|
|
mPendingPostRanks.insert(std::make_pair(token, gp));
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool p3Posted::getRanking(const uint32_t &token, PostedRanking &ranking)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void p3Posted::processRankings()
|
|
|
|
{
|
|
|
|
processMessageRanks();
|
|
|
|
|
|
|
|
processCommentRanks();
|
|
|
|
}
|
|
|
|
|
|
|
|
void p3Posted::processMessageRanks()
|
|
|
|
{
|
|
|
|
|
|
|
|
RsStackMutex stack(mPostedMutex);
|
|
|
|
std::map<uint32_t, GxsPostedPostRanking*>::iterator mit =mPendingPostRanks.begin();
|
|
|
|
|
2012-12-02 14:40:17 -05:00
|
|
|
// go through all pending posts
|
2012-11-30 13:54:25 -05:00
|
|
|
for(; mit !=mPendingPostRanks.begin(); mit++)
|
|
|
|
{
|
|
|
|
uint32_t token;
|
|
|
|
std::list<RsGxsGroupId> grpL;
|
|
|
|
grpL.push_back(mit->second->grpId);
|
|
|
|
RsTokReqOptions opts;
|
|
|
|
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
|
|
|
opts.mOptions = RS_TOKREQOPT_MSG_LATEST | RS_TOKREQOPT_MSG_THREAD;
|
|
|
|
RsGenExchange::getTokenService()->requestMsgInfo(token, GXS_REQUEST_TYPE_GROUP_DATA, opts, grpL);
|
|
|
|
GxsPostedPostRanking* gp = mit->second;
|
|
|
|
gp->reqToken = token;
|
|
|
|
|
|
|
|
while(true)
|
|
|
|
{
|
2012-12-02 14:40:17 -05:00
|
|
|
uint32_t status = mTokenService->requestStatus(token);
|
2012-11-30 13:54:25 -05:00
|
|
|
|
|
|
|
if(RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE
|
|
|
|
== status)
|
|
|
|
{
|
|
|
|
completePostedPostCalc(gp);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if(RsTokenService::GXS_REQUEST_V2_STATUS_FAILED
|
|
|
|
== status)
|
|
|
|
{
|
|
|
|
discardCalc(token);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mPendingPostRanks.clear();
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void p3Posted::discardCalc(const uint32_t &token)
|
|
|
|
{
|
2012-12-02 14:40:17 -05:00
|
|
|
mTokenService->cancelRequest(token);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PostedTopScoreComp(const PostedScore& i, const PostedScore& j)
|
|
|
|
{
|
|
|
|
if((i.upVotes + (-i.downVotes)) == (j.upVotes + (-j.downVotes))){
|
|
|
|
return i.date < j.date;
|
|
|
|
}else
|
|
|
|
return (i.upVotes + (-i.downVotes)) < (j.upVotes + (-j.downVotes));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PostedNewScoreComp(const PostedScore& i, const PostedScore& j)
|
|
|
|
{
|
|
|
|
return i.date < j.date;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PostedBestScoreComp(const PostedScore& i, const PostedScore& j)
|
|
|
|
{
|
|
|
|
|
|
|
|
// n = ups + downs if n == 0: return 0 z = 1.0
|
|
|
|
// #1.0 = 85%, 1.6 = 95% phat = float(ups)
|
|
|
|
// / n return sqrt(phat+z*z/(2*n)-z*((phat*(1-phat)+z*z/(4*n))/n))/(1+z*z/n)
|
|
|
|
// def confidence(ups, downs): if ups + downs == 0: return 0 else:
|
|
|
|
// return _confidence(ups, downs)
|
|
|
|
// very expensive!!
|
|
|
|
|
|
|
|
static float z = 1.0;
|
|
|
|
float phat;
|
|
|
|
|
|
|
|
float i_score;
|
|
|
|
int n = i.upVotes + (-i.downVotes);
|
|
|
|
if(n==0)
|
|
|
|
i_score = 0.;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
phat = float(i.upVotes);
|
|
|
|
i_score = sqrt(phat+z*z/(2*n)-z*((phat*(1-phat)+z*z/(4*n))/n))/(1+z*z/n);
|
|
|
|
}
|
|
|
|
|
|
|
|
float j_score;
|
|
|
|
n = j.upVotes + (-j.downVotes);
|
|
|
|
if(n==0)
|
|
|
|
j_score = 0.;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
phat = float(j.upVotes);
|
|
|
|
j_score = sqrt(phat+z*z/(2*n)-z*((phat*(1-phat)+z*z/(4*n))/n))/(1+z*z/n);
|
|
|
|
}
|
2012-11-30 13:54:25 -05:00
|
|
|
|
2012-12-02 14:40:17 -05:00
|
|
|
if(j_score == i_score)
|
|
|
|
return i.date < j.date;
|
|
|
|
else
|
|
|
|
return i_score < j_score;
|
2012-11-30 13:54:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void p3Posted::completePostedPostCalc(GxsPostedPostRanking *gpp)
|
|
|
|
{
|
|
|
|
GxsMsgMetaMap msgMetas;
|
|
|
|
|
2012-12-02 14:40:17 -05:00
|
|
|
if(getMsgMeta(gpp->reqToken, msgMetas))
|
|
|
|
{
|
|
|
|
std::vector<RsMsgMetaData> msgMetaV = msgMetas[gpp->grpId];
|
|
|
|
switch(gpp->rType)
|
|
|
|
{
|
|
|
|
case NewRankType:
|
|
|
|
calcPostedPostRank(msgMetaV, gpp->rankingResult, PostedNewScoreComp);
|
|
|
|
break;
|
|
|
|
case TopRankType:
|
|
|
|
calcPostedPostRank(msgMetaV, gpp->rankingResult, PostedTopScoreComp);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
std::cerr << "Unknown ranking tpye: " << gpp->rType << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void p3Posted::calcPostedPostRank(const std::vector<RsMsgMetaData > msgMeta, PostedRanking &ranking,
|
|
|
|
bool comp(const PostedScore &, const PostedScore &)) const
|
|
|
|
{
|
|
|
|
|
|
|
|
std::vector<RsMsgMetaData>::const_iterator cit = msgMeta.begin();
|
|
|
|
std::vector<PostedScore> scores;
|
|
|
|
|
|
|
|
for(; cit != msgMeta.begin(); )
|
|
|
|
{
|
|
|
|
const RsMsgMetaData& m = *cit;
|
|
|
|
uint32_t upVotes, downVotes, nComments;
|
|
|
|
retrieveScores(m.mServiceString, upVotes, downVotes, nComments);
|
|
|
|
|
|
|
|
PostedScore c;
|
|
|
|
c.upVotes = upVotes;
|
|
|
|
c.downVotes = downVotes;
|
|
|
|
c.date = m.mPublishTs;
|
|
|
|
scores.push_back(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::sort(scores.begin(), scores.end(), comp);
|
|
|
|
|
|
|
|
std::vector<PostedScore>::iterator vit = scores.begin();
|
|
|
|
|
|
|
|
int i = 1;
|
|
|
|
for(; vit != scores.end(); vit)
|
|
|
|
{
|
|
|
|
const PostedScore& p = *vit;
|
|
|
|
ranking.insert(std::make_pair(p.msgId, i++));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void p3Posted::calcPostedCommentsRank(const std::map<RsGxsMessageId, std::vector<RsGxsMessageId> > &msgBranches,
|
|
|
|
std::map<RsGxsMessageId, RsMsgMetaData >& msgMetas, PostedRanking &ranking, bool comp(const PostedScore &, const PostedScore &)) const
|
|
|
|
{
|
2012-11-30 13:54:25 -05:00
|
|
|
|
2012-12-02 14:40:17 -05:00
|
|
|
std::map<RsGxsMessageId, std::vector<RsGxsMessageId> >::const_iterator cit = msgBranches.begin();
|
|
|
|
|
|
|
|
for(; cit != msgBranches.end(); cit++)
|
2012-11-30 13:54:25 -05:00
|
|
|
{
|
2012-12-02 14:40:17 -05:00
|
|
|
const std::vector<RsGxsMessageId>& branch = cit->second;
|
|
|
|
std::vector<PostedScore> scores;
|
|
|
|
|
|
|
|
std::vector<RsGxsMessageId>::const_iterator vit = branch.begin();
|
|
|
|
|
|
|
|
for(; vit != branch.end(); vit++)
|
|
|
|
{
|
|
|
|
|
|
|
|
std::map<RsGxsMessageId, RsMsgMetaData >::iterator mit =
|
|
|
|
msgMetas.find(*vit);
|
|
|
|
|
|
|
|
if(mit != msgMetas.end())
|
|
|
|
{
|
|
|
|
uint32_t upVotes, downVotes, nComments;
|
2012-11-30 13:54:25 -05:00
|
|
|
|
2012-12-02 14:40:17 -05:00
|
|
|
const RsMsgMetaData& m = mit->second;
|
|
|
|
retrieveScores(m.mServiceString, upVotes, downVotes, nComments);
|
|
|
|
|
|
|
|
PostedScore c;
|
|
|
|
c.upVotes = upVotes;
|
|
|
|
c.downVotes = downVotes;
|
|
|
|
c.date = m.mPublishTs;
|
|
|
|
scores.push_back(c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::sort(scores.begin(), scores.end(), comp);
|
|
|
|
|
|
|
|
std::vector<PostedScore>::iterator cvit = scores.begin();
|
|
|
|
|
|
|
|
int i = 1;
|
|
|
|
for(; cvit != scores.end(); cvit)
|
|
|
|
{
|
|
|
|
const PostedScore& p = *cvit;
|
|
|
|
ranking.insert(std::make_pair(p.msgId, i++));
|
|
|
|
}
|
2012-11-30 13:54:25 -05:00
|
|
|
}
|
|
|
|
|
2012-12-02 14:40:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void p3Posted::completePostedCommentRanking(GxsPostedCommentRanking *gpc)
|
|
|
|
{
|
|
|
|
GxsMsgRelatedMetaMap msgMetas;
|
|
|
|
|
|
|
|
if(getMsgRelatedMeta(gpc->reqToken, msgMetas))
|
|
|
|
{
|
|
|
|
|
|
|
|
// create map of msgs
|
|
|
|
std::vector<RsMsgMetaData>& msgV = msgMetas[gpc->msgId];
|
|
|
|
std::map<RsGxsMessageId, std::vector<RsGxsMessageId> > msgBranches;
|
|
|
|
std::map<RsGxsMessageId, RsMsgMetaData> remappedMsgMeta;
|
|
|
|
|
|
|
|
std::vector<RsMsgMetaData>::iterator vit = msgV.begin();
|
|
|
|
|
|
|
|
for(; vit != msgV.end(); vit++)
|
|
|
|
{
|
|
|
|
const RsMsgMetaData& m = *vit;
|
|
|
|
|
|
|
|
if(!m.mParentId.empty())
|
|
|
|
{
|
|
|
|
msgBranches[m.mParentId].push_back(m.mMsgId);
|
|
|
|
}
|
|
|
|
|
|
|
|
remappedMsgMeta.insert(std::make_pair(m.mMsgId, m));
|
|
|
|
}
|
2012-11-30 13:54:25 -05:00
|
|
|
|
2012-12-02 14:40:17 -05:00
|
|
|
switch(gpc->rType)
|
|
|
|
{
|
|
|
|
case BestRankType:
|
|
|
|
calcPostedCommentsRank(msgBranches, remappedMsgMeta, gpc->result, PostedBestScoreComp);
|
|
|
|
break;
|
|
|
|
case TopRankType:
|
|
|
|
calcPostedCommentsRank(msgBranches, remappedMsgMeta, gpc->result, PostedTopScoreComp);
|
|
|
|
break;
|
|
|
|
case NewRankType:
|
|
|
|
calcPostedCommentsRank(msgBranches, remappedMsgMeta, gpc->result, PostedNewScoreComp);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
std::cerr << "Unknown Rank type" << gpc->rType << std::endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2012-11-30 13:54:25 -05:00
|
|
|
}
|
|
|
|
|
2012-12-02 14:40:17 -05:00
|
|
|
bool p3Posted::retrieveScores(const std::string &serviceString, uint32_t &upVotes, uint32_t downVotes, uint32_t nComments) const
|
2012-11-30 13:54:25 -05:00
|
|
|
{
|
2012-12-02 14:40:17 -05:00
|
|
|
if (3 == sscanf(serviceString.c_str(), "%d %d %d", &upVotes, &downVotes, &nComments))
|
2012-11-30 13:54:25 -05:00
|
|
|
{
|
2012-12-02 14:40:17 -05:00
|
|
|
return true;
|
2012-11-30 13:54:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-12-02 14:40:17 -05:00
|
|
|
bool p3Posted::storeScores(std::string &serviceString, uint32_t &upVotes, uint32_t downVotes, uint32_t nComments) const
|
|
|
|
{
|
|
|
|
char line[POSTED_MAX_SERVICE_STRING];
|
|
|
|
|
|
|
|
bool ok = snprintf(line, POSTED_MAX_SERVICE_STRING, "%d %d %d", upVotes, downVotes, nComments) > -1;
|
|
|
|
|
|
|
|
serviceString = line;
|
|
|
|
return ok;
|
|
|
|
}
|
2012-11-30 13:54:25 -05:00
|
|
|
void p3Posted::processCommentRanks()
|
2012-10-05 14:12:52 -04:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
2012-12-02 14:40:17 -05:00
|
|
|
|
|
|
|
|
|
|
|
void p3Posted::updateVotes()
|
|
|
|
{
|
|
|
|
if(!mUpdateTokenQueued)
|
|
|
|
{
|
|
|
|
mUpdateTokenQueued = true;
|
|
|
|
|
|
|
|
switch(mUpdatePhase)
|
|
|
|
{
|
|
|
|
// case UPDATE_PHASE_GRP_REQUEST:
|
|
|
|
// {
|
|
|
|
// updateRequestGroups(mUpda);
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
// case UPDATE_PHASE_GRP_MSG_REQUEST:
|
|
|
|
// {
|
|
|
|
// updateRequestMessages(mVoteUpdataToken);
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
// case UPDATE_VOTE_COMMENT_REQUEST:
|
|
|
|
// {
|
|
|
|
// updateRequestVotesComments(mVoteUpdataToken);
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
// case UPDATE_COMPLETE_UPDATE:
|
|
|
|
// {
|
|
|
|
// updateCompleteUpdate();
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
// default:
|
|
|
|
// break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// first get all msgs for groups for which you are subscribed to.
|
|
|
|
// then request comments for them
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool p3Posted::updateRequestGroups(uint32_t &token)
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
RsTokReqOptions opts;
|
|
|
|
opts.mReqType = GXS_REQUEST_TYPE_GROUP_IDS;
|
|
|
|
opts.mSubscribeMask = GXS_SERV::GROUP_SUBSCRIBE_MASK;
|
|
|
|
opts.mSubscribeFilter = GXS_SERV::GROUP_SUBSCRIBE_ADMIN |
|
|
|
|
GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED;
|
|
|
|
mTokenService->requestGroupInfo(token, 0, opts);
|
|
|
|
|
|
|
|
mUpdatePhase = UPDATE_PHASE_GRP_MSG_REQUEST;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool p3Posted::updateRequestMessages(uint32_t &token)
|
|
|
|
{
|
|
|
|
|
|
|
|
uint32_t status = mTokenService->requestStatus(token);
|
|
|
|
|
|
|
|
if(status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
|
|
|
{
|
|
|
|
std::list<RsGxsGroupId> grpIds;
|
|
|
|
RsGenExchange::getGroupList(token, grpIds);
|
|
|
|
RsTokReqOptions opts;
|
|
|
|
opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS;
|
|
|
|
opts.mOptions = RS_TOKREQOPT_MSG_LATEST | RS_TOKREQOPT_MSG_THREAD;
|
|
|
|
mTokenService->requestMsgInfo(token, 0, opts, grpIds);
|
|
|
|
mUpdatePhase = UPDATE_VOTE_COMMENT_REQUEST;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if(status == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED)
|
|
|
|
{
|
|
|
|
mTokenService->cancelRequest(token);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool p3Posted::updateRequestVotesComments(uint32_t &token)
|
|
|
|
{
|
|
|
|
|
|
|
|
uint32_t status = mTokenService->requestStatus(token);
|
|
|
|
|
|
|
|
if(status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
|
|
|
|
{
|
|
|
|
|
|
|
|
GxsMsgIdResult result;
|
|
|
|
RsGenExchange::getMsgList(token, result);
|
|
|
|
|
|
|
|
std::vector<RsGxsGrpMsgIdPair> msgIds;
|
|
|
|
|
|
|
|
GxsMsgIdResult::iterator mit = result.begin();
|
|
|
|
|
|
|
|
for(; mit != result.end(); mit++)
|
|
|
|
{
|
|
|
|
std::vector<RsGxsMessageId>& msgIdV = mit->second;
|
|
|
|
std::vector<RsGxsMessageId>::const_iterator cit = msgIdV.begin();
|
|
|
|
|
|
|
|
for(; cit != msgIdV.end(); cit++)
|
|
|
|
msgIds.push_back(std::make_pair(mit->first, *cit));
|
|
|
|
}
|
|
|
|
|
|
|
|
// only need ids for comments
|
|
|
|
RsTokReqOptions opts;
|
|
|
|
opts.mReqType = GXS_REQUEST_TYPE_MSG_IDS;
|
|
|
|
opts.mOptions = RS_TOKREQOPT_MSG_LATEST | RS_TOKREQOPT_MSG_PARENT;
|
|
|
|
opts.mMsgFlagMask = RsPosted::FLAG_MSGTYPE_MASK;
|
|
|
|
opts.mMsgFlagFilter = RsPosted::FLAG_MSGTYPE_COMMENT;
|
|
|
|
mTokenService->requestMsgRelatedInfo(mCommentToken, 0, opts, msgIds);
|
|
|
|
|
|
|
|
// need actual data from votes
|
|
|
|
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
|
|
|
opts.mOptions = RS_TOKREQOPT_MSG_LATEST | RS_TOKREQOPT_MSG_PARENT;
|
|
|
|
opts.mMsgFlagMask = RsPosted::FLAG_MSGTYPE_MASK;
|
|
|
|
opts.mMsgFlagFilter = RsPosted::FLAG_MSGTYPE_VOTE;
|
|
|
|
mTokenService->requestMsgRelatedInfo(mVoteToken, 0, opts, msgIds);
|
|
|
|
|
|
|
|
mUpdatePhase = UPDATE_COMPLETE_UPDATE;
|
|
|
|
mMsgsPendingUpdate = msgIds;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else if(status == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED)
|
|
|
|
{
|
|
|
|
mTokenService->cancelRequest(token);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool p3Posted::updateCompleteUpdate()
|
|
|
|
{
|
|
|
|
uint32_t commentStatus = mTokenService->requestStatus(mCommentToken);
|
|
|
|
uint32_t voteStatus = mTokenService->requestStatus(mVoteToken);
|
|
|
|
|
|
|
|
bool ready = commentStatus == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE;
|
|
|
|
ready &= voteStatus == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE;
|
|
|
|
|
|
|
|
bool failed = commentStatus == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED;
|
|
|
|
failed &= voteStatus == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED;
|
|
|
|
|
|
|
|
if(ready)
|
|
|
|
{
|
|
|
|
std::map<RsGxsGrpMsgIdPair, std::vector<RsGxsMessageId> > msgCommentIds;
|
|
|
|
std::map<RsGxsGrpMsgIdPair, std::vector<RsPostedVote> > votes;
|
|
|
|
getMsgRelatedDataT<RsGxsPostedVoteItem, RsPostedVote>(mVoteToken, votes);
|
|
|
|
std::vector<RsGxsGrpMsgIdPair>::iterator vit = mMsgsPendingUpdate.begin();
|
|
|
|
|
|
|
|
for(; vit != mMsgsPendingUpdate.end();vit++)
|
|
|
|
{
|
|
|
|
updateMsg(*vit, votes[*vit], msgCommentIds[*vit]);
|
|
|
|
}
|
|
|
|
mUpdatePhase = 0;
|
|
|
|
}
|
|
|
|
else if(failed)
|
|
|
|
{
|
|
|
|
mTokenService->cancelRequest(mCommentToken);
|
|
|
|
mTokenService->cancelRequest(mVoteToken);
|
|
|
|
return false;
|
|
|
|
}else
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool p3Posted::updateMsg(const RsGxsGrpMsgIdPair& msgId, const std::vector<RsPostedVote> &msgVotes,
|
|
|
|
const std::vector<RsGxsMessageId>& msgCommentIds)
|
|
|
|
{
|
|
|
|
|
|
|
|
uint32_t nComments = msgCommentIds.size();
|
|
|
|
uint32_t nUp = 0, nDown = 0;
|
|
|
|
|
|
|
|
std::vector<RsPostedVote>::const_iterator cit = msgVotes.begin();
|
|
|
|
|
|
|
|
for(; cit != msgVotes.end(); cit++)
|
|
|
|
{
|
|
|
|
const RsPostedVote& v = *cit;
|
|
|
|
|
|
|
|
if(v.mDirection == 0)
|
|
|
|
{
|
|
|
|
nDown++;
|
|
|
|
}else
|
|
|
|
{
|
|
|
|
nUp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
std::string servStr;
|
|
|
|
storeScores(servStr, nUp, nDown, nComments);
|
|
|
|
uint32_t token;
|
|
|
|
setMsgServiceString(token, msgId, servStr);
|
|
|
|
}
|
|
|
|
|