added a cache for comments in comment tree widget to make loading synchronous when necessary

This commit is contained in:
csoler 2020-09-18 23:12:48 +02:00
parent a142694896
commit c7bc7e814b
5 changed files with 49 additions and 10 deletions

View File

@ -68,7 +68,7 @@ BoardPostDisplayWidget::BoardPostDisplayWidget(const RsPostedPost& post, Display
std::set<RsGxsMessageId> post_versions ;
post_versions.insert(post.mMeta.mMsgId) ;
ui->commentsWidget->commentLoad(post.mMeta.mGroupId, post_versions,mPost.mMeta.mMsgId);
ui->commentsWidget->commentLoad(post.mMeta.mGroupId, post_versions,mPost.mMeta.mMsgId,true);
}
}

View File

@ -84,7 +84,7 @@ GxsCommentDialog::~GxsCommentDialog()
delete(ui);
}
void GxsCommentDialog::commentLoad(const RsGxsGroupId &grpId, const std::set<RsGxsMessageId>& msg_versions,const RsGxsMessageId& most_recent_msgId)
void GxsCommentDialog::commentLoad(const RsGxsGroupId &grpId, const std::set<RsGxsMessageId>& msg_versions,const RsGxsMessageId& most_recent_msgId,bool use_cache)
{
std::cerr << "GxsCommentDialog::commentLoad(" << grpId << ", most recent msg version: " << most_recent_msgId << ")";
std::cerr << std::endl;
@ -93,7 +93,8 @@ void GxsCommentDialog::commentLoad(const RsGxsGroupId &grpId, const std::set<RsG
mMostRecentMsgId = most_recent_msgId;
mMsgVersions = msg_versions;
ui->treeWidget->requestComments(mGrpId,msg_versions,most_recent_msgId);
ui->treeWidget->setUseCache(use_cache);
ui->treeWidget->requestComments(mGrpId,msg_versions,most_recent_msgId);
}
void GxsCommentDialog::notifyCommentsLoaded(int n)

View File

@ -38,7 +38,7 @@ public:
void setTokenService(RsTokenService *token_service, RsGxsCommentService *comment_service);
void setCommentHeader(QWidget *header);
void commentLoad(const RsGxsGroupId &grpId, const std::set<RsGxsMessageId> &msg_versions, const RsGxsMessageId &most_recent_msgId);
void commentLoad(const RsGxsGroupId &grpId, const std::set<RsGxsMessageId> &msg_versions, const RsGxsMessageId &most_recent_msgId, bool use_cache=false);
RsGxsGroupId groupId() { return mGrpId; }
RsGxsMessageId messageId() { return mMostRecentMsgId; }

View File

@ -64,6 +64,9 @@
#define IMAGE_VOTEUP ":/images/vote_up.png"
#define IMAGE_VOTEDOWN ":/images/vote_down.png"
std::map<RsGxsMessageId, std::vector<RsGxsComment> > GxsCommentTreeWidget::mCommentsCache;
QMutex GxsCommentTreeWidget::mCacheMutex;
// This class allows to draw the item using an appropriate size
class MultiLinesCommentDelegate: public QStyledItemDelegate
@ -148,6 +151,8 @@ GxsCommentTreeWidget::GxsCommentTreeWidget(QWidget *parent)
commentsRole = new RSTreeWidgetItemCompareRole;
commentsRole->setRole(PCITEM_COLUMN_DATE, ROLE_SORT);
mUseCache = false;
// QFont font = QFont("ARIAL", 10);
// font.setBold(true);
@ -362,6 +367,19 @@ void GxsCommentTreeWidget::requestComments(const RsGxsGroupId& group, const std:
mMsgVersions = message_versions ;
mLatestMsgId = most_recent_message;
if(mUseCache)
{
QMutexLocker lock(&mCacheMutex);
auto it = mCommentsCache.find(most_recent_message);
if(it != mCommentsCache.end())
{
std::cerr << "Got " << it->second.size() << " comments from cache." << std::endl;
insertComments(it->second);
completeItems();
}
}
service_requestComments(group,message_versions);
}
@ -581,11 +599,28 @@ void GxsCommentTreeWidget::service_loadThread(const uint32_t &token)
std::vector<RsGxsComment> comments;
mCommentService->getRelatedComments(token, comments);
std::vector<RsGxsComment>::iterator vit;
// This is inconsistent since we cannot know here that all comments are for the same thread. However they are only
// requested in requestComments() where a single MsgId is used.
for(vit = comments.begin(); vit != comments.end(); ++vit)
if(mUseCache)
{
QMutexLocker lock(&mCacheMutex);
if(!comments.empty())
{
std::cerr << "Updating cache with " << comments.size() << " for thread " << comments[0].mMeta.mThreadId << std::endl;
mCommentsCache[comments[0].mMeta.mThreadId] = comments;
}
}
insertComments(comments);
}
void GxsCommentTreeWidget::insertComments(const std::vector<RsGxsComment>& comments)
{
for(auto vit = comments.begin(); vit != comments.end(); ++vit)
{
RsGxsComment &comment = *vit;
const RsGxsComment &comment = *vit;
/* convert to a QTreeWidgetItem */
std::cerr << "GxsCommentTreeWidget::service_loadThread() Got Comment: " << comment.mMeta.mMsgId;
std::cerr << std::endl;
@ -636,8 +671,6 @@ void GxsCommentTreeWidget::service_loadThread(const uint32_t &token)
addItem(comment.mMeta.mMsgId, comment.mMeta.mParentId, item);
}
return;
}
QTreeWidgetItem *GxsCommentTreeWidget::service_createMissingItem(const RsGxsMessageId& parent)

View File

@ -22,6 +22,7 @@
#define _GXS_COMMENT_TREE_WIDGET_H
#include <QTreeWidget>
#include <QMutex>
#include "util/TokenQueue.h"
#include <retroshare/rsgxscommon.h>
@ -45,6 +46,7 @@ public:
void loadRequest(const TokenQueue *queue, const TokenRequest &req);
void setVoteId(const RsGxsId &voterId);
void setUseCache(bool b) { mUseCache = b ;}
protected:
/* to be overloaded */
@ -60,8 +62,8 @@ protected:
void loadThread(const uint32_t &token);
void insertComments(const std::vector<RsGxsComment>& comments);
void addItem(RsGxsMessageId itemId, RsGxsMessageId parentId, QTreeWidgetItem *item);
public slots:
void customPopUpMenu(const QPoint& point);
void setCurrentCommentMsgId(QTreeWidgetItem* current, QTreeWidgetItem* previous);
@ -108,6 +110,9 @@ protected:
RsTokenService *mRsTokenService;
RsGxsCommentService *mCommentService;
bool mUseCache;
static std::map<RsGxsMessageId, std::vector<RsGxsComment> > mCommentsCache;
static QMutex mCacheMutex;
};