From 0b2feb9e458d240e79d0ae02c4385e8ec6bbedfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Wed, 14 Jun 2023 22:12:24 -0400 Subject: [PATCH] perf: make less db calls to load indices pass in postData array to getPostReplies which has the indices already look at the passed in array of posts to find the index of nested replies before calling getPidIndex, most of the time the direct replies are close to the target so they are already in postData array. only load indices if direct reply count is1 --- src/topics/posts.js | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/topics/posts.js b/src/topics/posts.js index fd1dc94889..06b9c28635 100644 --- a/src/topics/posts.js +++ b/src/topics/posts.js @@ -125,7 +125,7 @@ module.exports = function (Topics) { posts.getVoteStatusByPostIDs(pids, uid), getPostUserData('uid', async uids => await posts.getUserInfoForPosts(uids, uid)), getPostUserData('editor', async uids => await user.getUsersFields(uids, ['uid', 'username', 'userslug'])), - getPostReplies(pids, uid), + getPostReplies(postData, uid), Topics.addParentPosts(postData), ]); @@ -314,14 +314,15 @@ module.exports = function (Topics) { return await db.getObjectField(`topic:${tid}`, 'postcount'); }; - async function getPostReplies(pids, callerUid) { + async function getPostReplies(postData, callerUid) { + const pids = postData.map(p => p && p.pid); const keys = pids.map(pid => `pid:${pid}:replies`); - const arrayOfReplyPids = await db.getSortedSetsMembers(keys); + const [arrayOfReplyPids, userSettings] = await Promise.all([ + db.getSortedSetsMembers(keys), + user.getSettings(callerUid), + ]); const uniquePids = _.uniq(_.flatten(arrayOfReplyPids)); - const someTid = await posts.getPostField(pids[0], 'tid'); // the particular tid doesn't matter; used in getPostIndices but does not affect output - const pidIndices = await posts.getPostIndices(pids.map(pid => ({ pid, tid: someTid }))); - const replyIndices = await posts.getPostIndices(uniquePids.map(pid => ({ pid, tid: someTid }))); let replyData = await posts.getPostsFields(uniquePids, ['pid', 'uid', 'timestamp']); const result = await plugins.hooks.fire('filter:topics.getPostReplies', { @@ -338,15 +339,15 @@ module.exports = function (Topics) { const uidMap = _.zipObject(uniqueUids, userData); const pidMap = _.zipObject(replyData.map(r => r.pid), replyData); - const indicesMap = _.zipObject(replyData.map(r => r.pid), replyIndices); + const postDataMap = _.zipObject(pids, postData); - const returnData = arrayOfReplyPids.map((replyPids, idx) => { + const returnData = await Promise.all(arrayOfReplyPids.map(async (replyPids, idx) => { + const currentPid = pids[idx]; replyPids = replyPids.filter(pid => pidMap[pid]); - const currentIndex = pidIndices[idx]; const uidsUsed = {}; const currentData = { hasMore: false, - hasSingleImmediateReply: replyPids.length === 1 && Math.abs(currentIndex - indicesMap[replyPids[0]]) === 1, + hasSingleImmediateReply: false, users: [], text: replyPids.length > 1 ? `[[topic:replies_to_this_post, ${replyPids.length}]]` : '[[topic:one_reply_to_this_post]]', count: replyPids.length, @@ -368,8 +369,22 @@ module.exports = function (Topics) { currentData.hasMore = true; } + if (replyPids.length === 1) { + const currentIndex = postDataMap[currentPid] ? postDataMap[currentPid].index : null; + const replyPid = replyPids[0]; + // only load index of nested reply if we can't find it in the postDataMap + let replyPost = postDataMap[replyPid]; + if (!replyPost) { + const tid = await posts.getPostField(replyPid, 'tid'); + replyPost = { + index: await posts.getPidIndex(replyPid, tid, userSettings.topicPostSort), + }; + } + currentData.hasSingleImmediateReply = Math.abs(currentIndex - replyPost.index) === 1; + } + return currentData; - }); + })); return returnData; }