Improvements to Comment Handling and GxsChannels.

- Added Vote dummy data into channels.
 - Fixed up RsGxsImage handling to avoid memory issues - need to switch to shared_ptr later.
 - Added "BestScore" calculations into Comments - not sure if the maths is right.
 - Added Hashing interface to Channels.
 - misc bugfixes.



git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6218 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2013-03-13 00:24:57 +00:00
parent 4866c5585b
commit b9f2708927
7 changed files with 246 additions and 28 deletions

View File

@ -104,6 +104,11 @@ virtual void setChannelAutoDownload(uint32_t& token, const RsGxsGroupId& groupId
virtual bool createGroup(uint32_t &token, RsGxsChannelGroup &group) = 0;
virtual bool createPost(uint32_t &token, RsGxsChannelPost &post) = 0;
// File Interface
virtual bool ExtraFileHash(const std::string &path, std::string filename) = 0;
virtual bool ExtraFileRemove(const std::string &hash) = 0;
};

View File

@ -39,7 +39,7 @@ class RsGxsFile
std::string mName;
std::string mHash;
uint64_t mSize;
std::string mPath;
//std::string mPath;
};
class RsGxsImage
@ -47,6 +47,7 @@ class RsGxsImage
public:
RsGxsImage();
~RsGxsImage();
RsGxsImage(const RsGxsImage& a); // TEMP use copy constructor and duplicate memory.
//NB: Must make sure that we always use methods - to be consistent about malloc/free for this data.
static uint8_t *allocate(uint32_t size);
@ -59,6 +60,7 @@ static void release(void *data);
uint8_t *mData;
uint32_t mSize;
};
@ -83,10 +85,10 @@ class RsGxsComment
// below is calculated.
uint32_t mUpVotes;
uint32_t mDownVotes;
double score;
double mScore;
// This is filled in if detailed Comment Data is called.
std::list<RsGxsVote> votes;
std::list<RsGxsVote> mVotes;
};

View File

@ -171,7 +171,8 @@ bool RsGxsChannelGroupItem::toChannelGroup(RsGxsChannelGroup &group, bool moveIm
if (moveImage)
{
group.mImage.take((uint8_t *) mImage.binData.bin_data, mImage.binData.bin_len);
mImage.TlvShallowClear();
// mImage doesn't have a ShallowClear at the moment!
mImage.binData.TlvShallowClear();
}
else
{
@ -376,7 +377,8 @@ bool RsGxsChannelPostItem::toChannelPost(RsGxsChannelPost &post, bool moveImage)
if (moveImage)
{
post.mThumbnail.take((uint8_t *) mThumbnail.binData.bin_data, mThumbnail.binData.bin_len);
mThumbnail.TlvShallowClear();
// mThumbnail doesn't have a ShallowClear at the moment!
mThumbnail.binData.TlvShallowClear();
}
else
{
@ -392,7 +394,6 @@ bool RsGxsChannelPostItem::toChannelPost(RsGxsChannelPost &post, bool moveImage)
fi.mName = RsDirUtil::getTopDir(fit->name);
fi.mSize = fit->filesize;
fi.mHash = fit->hash;
fi.mPath = fit->path;
post.mFiles.push_back(fi);
post.mCount++;

View File

@ -27,6 +27,7 @@
#include "serialiser/rsgxschannelitems.h"
#include <retroshare/rsidentity.h>
#include <retroshare/rsfiles.h>
#include "retroshare/rsgxsflags.h"
@ -44,6 +45,8 @@
RsGxsChannels *rsGxsChannels = NULL;
#define GXSCHANNEL_STOREPERIOD (3600 * 24 * 30)
#define GXSCHANNELS_SUBSCRIBED_META 1
#define GXSCHANNELS_UNPROCESSED_SPECIFIC 2
#define GXSCHANNELS_UNPROCESSED_GENERIC 3
@ -708,6 +711,29 @@ bool p3GxsChannels::createPost(uint32_t &token, RsGxsChannelPost &msg)
return true;
}
/********************************************************************************************/
/********************************************************************************************/
bool p3GxsChannels::ExtraFileHash(const std::string &path, std::string filename)
{
/* extract filename */
filename = RsDirUtil::getTopDir(path);
TransferRequestFlags flags = RS_FILE_REQ_ANONYMOUS_ROUTING;
if(!rsFiles->ExtraFileHash(path, GXSCHANNEL_STOREPERIOD, flags))
return false;
return true;
}
bool p3GxsChannels::ExtraFileRemove(const std::string &hash)
{
TransferRequestFlags tflags = RS_FILE_REQ_ANONYMOUS_ROUTING | RS_FILE_REQ_EXTRA;
return rsFiles->ExtraFileRemove(hash, tflags);
}
/********************************************************************************************/
/********************************************************************************************/
@ -715,8 +741,10 @@ bool p3GxsChannels::createPost(uint32_t &token, RsGxsChannelPost &msg)
/* so we need the same tick idea as wiki for generating dummy channels
*/
#define MAX_GEN_GROUPS 5
#define MAX_GEN_MESSAGES 100
#define MAX_GEN_GROUPS 3
#define MAX_GEN_POSTS 8
#define MAX_GEN_COMMENTS 50
#define MAX_GEN_VOTES 500
std::string p3GxsChannels::genRandomId()
{
@ -732,7 +760,7 @@ std::string p3GxsChannels::genRandomId()
bool p3GxsChannels::generateDummyData()
{
mGenCount = 0;
mGenRefs.resize(MAX_GEN_MESSAGES);
mGenRefs.resize(MAX_GEN_VOTES);
std::string groupName;
rs_sprintf(groupName, "TestChannel_%d", mGenCount);
@ -755,7 +783,7 @@ void p3GxsChannels::dummy_tick()
if (mGenActive)
{
std::cerr << "p3GxsChannels::dummyTick() AboutActive";
std::cerr << "p3GxsChannels::dummyTick() Gen Active";
std::cerr << std::endl;
uint32_t status = RsGenExchange::getTokenService()->requestStatus(mGenToken);
@ -792,7 +820,7 @@ void p3GxsChannels::dummy_tick()
ChannelDummyRef ref(groupId, emptyId, emptyId);
mGenRefs[mGenCount] = ref;
}
else if (mGenCount < MAX_GEN_MESSAGES)
else if (mGenCount < MAX_GEN_POSTS)
{
/* get the msg Id, and generate next snapshot */
RsGxsGrpMsgIdPair msgId;
@ -804,7 +832,47 @@ void p3GxsChannels::dummy_tick()
return;
}
std::cerr << "p3GxsChannels::dummy_tick() Acknowledged <GroupId: " << msgId.first << ", MsgId: " << msgId.second << ">";
std::cerr << "p3GxsChannels::dummy_tick() Acknowledged Post <GroupId: " << msgId.first << ", MsgId: " << msgId.second << ">";
std::cerr << std::endl;
/* store results for later selection */
ChannelDummyRef ref(msgId.first, mGenThreadId, msgId.second);
mGenRefs[mGenCount] = ref;
}
else if (mGenCount < MAX_GEN_COMMENTS)
{
/* get the msg Id, and generate next snapshot */
RsGxsGrpMsgIdPair msgId;
if (!acknowledgeTokenMsg(mGenToken, msgId))
{
std::cerr << " ERROR ";
std::cerr << std::endl;
mGenActive = false;
return;
}
std::cerr << "p3GxsChannels::dummy_tick() Acknowledged Comment <GroupId: " << msgId.first << ", MsgId: " << msgId.second << ">";
std::cerr << std::endl;
/* store results for later selection */
ChannelDummyRef ref(msgId.first, mGenThreadId, msgId.second);
mGenRefs[mGenCount] = ref;
}
else if (mGenCount < MAX_GEN_VOTES)
{
/* get the msg Id, and generate next snapshot */
RsGxsGrpMsgIdPair msgId;
if (!acknowledgeTokenMsg(mGenToken, msgId))
{
std::cerr << " ERROR ";
std::cerr << std::endl;
mGenActive = false;
return;
}
std::cerr << "p3GxsChannels::dummy_tick() Acknowledged Vote <GroupId: " << msgId.first << ", MsgId: " << msgId.second << ">";
std::cerr << std::endl;
/* store results for later selection */
@ -835,10 +903,10 @@ void p3GxsChannels::dummy_tick()
/* create a new group */
generateGroup(mGenToken, groupName);
}
else
else if (mGenCount < MAX_GEN_POSTS)
{
/* create a new message */
uint32_t idx = (uint32_t) (mGenCount * RSRandom::random_f32());
/* create a new post */
uint32_t idx = (uint32_t) (MAX_GEN_GROUPS * RSRandom::random_f32());
ChannelDummyRef &ref = mGenRefs[idx];
RsGxsGroupId grpId = ref.mGroupId;
@ -849,21 +917,59 @@ void p3GxsChannels::dummy_tick()
mGenThreadId = parentId;
}
std::cerr << "p3GxsChannels::dummy_tick() Generating Msg ... ";
std::cerr << "p3GxsChannels::dummy_tick() Generating Post ... ";
std::cerr << " GroupId: " << grpId;
std::cerr << " ThreadId: " << mGenThreadId;
std::cerr << " ParentId: " << parentId;
std::cerr << std::endl;
if (parentId.empty())
{
generatePost(mGenToken, grpId);
}
else
{
generateComment(mGenToken, grpId, parentId, mGenThreadId);
}
generatePost(mGenToken, grpId);
}
else if (mGenCount < MAX_GEN_COMMENTS)
{
/* create a new post */
uint32_t idx = (uint32_t) ((mGenCount - MAX_GEN_GROUPS) * RSRandom::random_f32());
ChannelDummyRef &ref = mGenRefs[idx + MAX_GEN_GROUPS];
RsGxsGroupId grpId = ref.mGroupId;
RsGxsMessageId parentId = ref.mMsgId;
mGenThreadId = ref.mThreadId;
if (mGenThreadId.empty())
{
mGenThreadId = parentId;
}
std::cerr << "p3GxsChannels::dummy_tick() Generating Comment ... ";
std::cerr << " GroupId: " << grpId;
std::cerr << " ThreadId: " << mGenThreadId;
std::cerr << " ParentId: " << parentId;
std::cerr << std::endl;
generateComment(mGenToken, grpId, parentId, mGenThreadId);
}
else
{
/* create a new post */
uint32_t idx = (uint32_t) ((MAX_GEN_COMMENTS - MAX_GEN_POSTS) * RSRandom::random_f32());
ChannelDummyRef &ref = mGenRefs[idx + MAX_GEN_POSTS];
RsGxsGroupId grpId = ref.mGroupId;
RsGxsMessageId parentId = ref.mMsgId;
mGenThreadId = ref.mThreadId;
if (mGenThreadId.empty())
{
mGenThreadId = parentId;
}
std::cerr << "p3GxsChannels::dummy_tick() Generating Vote ... ";
std::cerr << " GroupId: " << grpId;
std::cerr << " ThreadId: " << mGenThreadId;
std::cerr << " ParentId: " << parentId;
std::cerr << std::endl;
generateVote(mGenToken, grpId, parentId, mGenThreadId);
}
}
}
@ -920,13 +1026,13 @@ bool p3GxsChannels::generateComment(uint32_t &token, const RsGxsGroupId &grpId,
if (it != ownIds.end())
{
std::cerr << "p3GxsChannels::generateMessage() Author: " << *it;
std::cerr << "p3GxsChannels::generateComment() Author: " << *it;
std::cerr << std::endl;
msg.mMeta.mAuthorId = *it;
}
else
{
std::cerr << "p3GxsChannels::generateMessage() No Author!";
std::cerr << "p3GxsChannels::generateComment() No Author!";
std::cerr << std::endl;
}
@ -936,6 +1042,53 @@ bool p3GxsChannels::generateComment(uint32_t &token, const RsGxsGroupId &grpId,
}
bool p3GxsChannels::generateVote(uint32_t &token, const RsGxsGroupId &grpId, const RsGxsMessageId &parentId, const RsGxsMessageId &threadId)
{
RsGxsVote vote;
vote.mMeta.mGroupId = grpId;
vote.mMeta.mThreadId = threadId;
vote.mMeta.mParentId = parentId;
vote.mMeta.mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_UNREAD;
/* chose a random Id to sign with */
std::list<RsGxsId> ownIds;
std::list<RsGxsId>::iterator it;
rsIdentity->getOwnIds(ownIds);
uint32_t idx = (uint32_t) (ownIds.size() * RSRandom::random_f32());
uint32_t i = 0;
for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++);
if (it != ownIds.end())
{
std::cerr << "p3GxsChannels::generateVote() Author: " << *it;
std::cerr << std::endl;
vote.mMeta.mAuthorId = *it;
}
else
{
std::cerr << "p3GxsChannels::generateVote() No Author!";
std::cerr << std::endl;
}
if (0.7 > RSRandom::random_f32())
{
// 70 % postive votes
vote.mVoteType = GXS_VOTE_UP;
}
else
{
vote.mVoteType = GXS_VOTE_DOWN;
}
createVote(token, vote);
return true;
}
bool p3GxsChannels::generateGroup(uint32_t &token, std::string groupName)
{
/* generate a new channel */

View File

@ -125,6 +125,10 @@ virtual void subscribeToGroup(const RsGxsGroupId &groupId, bool subscribe);
virtual void setMessageProcessedStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool processed);
virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read);
// File Interface
virtual bool ExtraFileHash(const std::string &path, std::string filename);
virtual bool ExtraFileRemove(const std::string &hash);
protected:
// Overloaded from GxsTokenQueue for Request callbacks.
@ -168,6 +172,9 @@ void dummy_tick();
bool generatePost(uint32_t &token, const RsGxsGroupId &grpId);
bool generateComment(uint32_t &token, const RsGxsGroupId &grpId,
const RsGxsMessageId &parentId, const RsGxsMessageId &threadId);
bool generateVote(uint32_t &token, const RsGxsGroupId &grpId,
const RsGxsMessageId &parentId, const RsGxsMessageId &threadId);
bool generateGroup(uint32_t &token, std::string groupName);
class ChannelDummyRef

View File

@ -29,32 +29,48 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
RsGxsComment::RsGxsComment()
{
mUpVotes = 0;
mDownVotes = 0;
score = 0;
mScore = 0;
}
/********************************************************************************/
RsGxsImage::RsGxsImage()
{
std::cerr << "RsGxsImage(" << this << ")";
std::cerr << std::endl;
mData = NULL;
mSize = 0;
}
RsGxsImage::RsGxsImage(const RsGxsImage& a)
{
std::cerr << "RsGxsImage(" << this << ") = RsGxsImage(" << (void *) &a << ")";
std::cerr << std::endl;
mData = NULL;
mSize = 0;
copy(a.mData, a.mSize);
}
RsGxsImage::~RsGxsImage()
{
std::cerr << "~RsGxsImage(" << this << ")";
std::cerr << std::endl;
clear();
}
void RsGxsImage::take(uint8_t *data, uint32_t size)
{
std::cerr << "RsGxsImage(" << this << ")::take(" << (void *) data << "," << size << ")";
std::cerr << std::endl;
// Copies Pointer.
clear();
mData = data;
@ -64,16 +80,23 @@ void RsGxsImage::take(uint8_t *data, uint32_t size)
// NB Must make sure that we always use malloc/free for this data.
uint8_t *RsGxsImage::allocate(uint32_t size)
{
return (uint8_t *) malloc(size);
uint8_t *val = (uint8_t *) malloc(size);
std::cerr << "RsGxsImage()::allocate(" << (void *) val << ")";
std::cerr << std::endl;
return val;
}
void RsGxsImage::release(void *data)
{
std::cerr << "RsGxsImage()::release(" << (void *) data << ")";
std::cerr << std::endl;
free(data);
}
void RsGxsImage::copy(uint8_t *data, uint32_t size)
{
std::cerr << "RsGxsImage(" << this << ")::copy(" << (void *) data << "," << size << ")";
std::cerr << std::endl;
// Allocates and Copies.
clear();
if (data && size)
@ -190,6 +213,7 @@ bool p3GxsCommentService::getGxsCommentData(const uint32_t &token, std::vector<R
cit->mDownVotes++;
}
}
cit->mScore = calculateBestScore(cit->mUpVotes, cit->mDownVotes);
}
std::cerr << "p3GxsCommentService::getGxsCommentData() Found " << comments.size() << " Comments";
@ -272,6 +296,7 @@ bool p3GxsCommentService::getGxsRelatedComments(const uint32_t &token, std::vect
cit->mDownVotes++;
}
}
cit->mScore = calculateBestScore(cit->mUpVotes, cit->mDownVotes);
}
std::cerr << "p3GxsCommentService::getGxsRelatedComments() Found " << comments.size() << " Comments";
@ -289,6 +314,28 @@ bool p3GxsCommentService::getGxsRelatedComments(const uint32_t &token, std::vect
return ok;
}
double p3GxsCommentService::calculateBestScore(int upVotes, int downVotes)
{
static float z = 1.0;
float score;
int n = upVotes - downVotes;
if(n==0)
{
score = 0.0;
}
else
{
float phat = upVotes;
score = sqrt(phat+z*z/(2*n)-z*((phat*(1-phat)+z*z/(4*n))/n))/(1+z*z/n);
}
return score;
}
/********************************************************************************************/
bool p3GxsCommentService::createGxsComment(uint32_t &token, RsGxsComment &msg)

View File

@ -47,6 +47,9 @@ class p3GxsCommentService
bool createGxsComment(uint32_t &token, RsGxsComment &msg);
bool createGxsVote(uint32_t &token, RsGxsVote &msg);
static double calculateBestScore(int upVotes, int downVotes);
#if 0
void setGxsMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, bool read);
#endif