mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-01 19:46:01 +01:00
late night optimizations
-isMemberOfSets returns true/false instead of 1/0 -when loading the posts of a topic only get the userdata for each user once, before this commit if a topic had 10 posts from 2 different users we were getting the user data for each user 5 times (drunk) -getVoteStatusByPostIDs and getFavouritesByPostIDs no longer make pids.length calls to the db, they use isMemberOfSets now -getUserInfoForPost renamed to getUserInfoForPosts and doesnt make uids.length calls to db, uses getMultipleUserFields instead
This commit is contained in:
@@ -78,7 +78,7 @@ module.exports = function(db, module) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
result = sets.map(function(set) {
|
result = sets.map(function(set) {
|
||||||
return result.indexOf(set) !== -1 ? 1 : 0;
|
return result.indexOf(set) !== -1;
|
||||||
});
|
});
|
||||||
|
|
||||||
callback(null, result);
|
callback(null, result);
|
||||||
|
|||||||
@@ -40,11 +40,20 @@ module.exports = function(redisClient, module) {
|
|||||||
module.isMemberOfSets = function(sets, value, callback) {
|
module.isMemberOfSets = function(sets, value, callback) {
|
||||||
var multi = redisClient.multi();
|
var multi = redisClient.multi();
|
||||||
|
|
||||||
for (var i = 0, ii = sets.length; i < ii; i++) {
|
for (var i = 0; i < sets.length; ++i) {
|
||||||
multi.sismember(sets[i], value);
|
multi.sismember(sets[i], value);
|
||||||
}
|
}
|
||||||
|
|
||||||
multi.exec(callback);
|
multi.exec(function(err, results) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i=0; i<results.length; ++i) {
|
||||||
|
results[i] = results[i] === 1;
|
||||||
|
}
|
||||||
|
callback(null, results);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.getSetMembers = function(key, callback) {
|
module.getSetMembers = function(key, callback) {
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ var async = require('async'),
|
|||||||
if (meta.config['reputation:disabled'] === false) {
|
if (meta.config['reputation:disabled'] === false) {
|
||||||
return callback(false);
|
return callback(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleVote('upvote', pid, uid, callback);
|
toggleVote('upvote', pid, uid, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -155,8 +155,21 @@ var async = require('async'),
|
|||||||
};
|
};
|
||||||
|
|
||||||
Favourites.getVoteStatusByPostIDs = function(pids, uid, callback) {
|
Favourites.getVoteStatusByPostIDs = function(pids, uid, callback) {
|
||||||
async.map(pids, function(pid, next) {
|
var upvoteSets = [],
|
||||||
Favourites.hasVoted(pid, uid, next);
|
downvoteSets = [];
|
||||||
|
|
||||||
|
for (var i=0; i<pids.length; ++i) {
|
||||||
|
upvoteSets.push('pid:' + pids[i] + ':upvote');
|
||||||
|
downvoteSets.push('pid:' + pids[i] + ':downvote');
|
||||||
|
}
|
||||||
|
|
||||||
|
async.parallel({
|
||||||
|
upvotes: function(next) {
|
||||||
|
db.isMemberOfSets(upvoteSets, uid, next);
|
||||||
|
},
|
||||||
|
downvotes: function(next) {
|
||||||
|
db.isMemberOfSets(downvoteSets, uid, next);
|
||||||
|
}
|
||||||
}, callback);
|
}, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -225,9 +238,12 @@ var async = require('async'),
|
|||||||
};
|
};
|
||||||
|
|
||||||
Favourites.getFavouritesByPostIDs = function(pids, uid, callback) {
|
Favourites.getFavouritesByPostIDs = function(pids, uid, callback) {
|
||||||
async.map(pids, function(pid, next) {
|
var sets = [];
|
||||||
Favourites.hasFavourited(pid, uid, next);
|
for (var i=0; i<pids.length; ++i) {
|
||||||
}, callback);
|
sets.push('pid:' + pids[i] + ':users_favourited');
|
||||||
|
}
|
||||||
|
|
||||||
|
db.isMemberOfSets(sets, uid, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
Favourites.getFavouritedUidsByPids = function(pids, callback) {
|
Favourites.getFavouritedUidsByPids = function(pids, callback) {
|
||||||
|
|||||||
@@ -350,7 +350,7 @@
|
|||||||
|
|
||||||
db.isMemberOfSets(groupSets, uid, function(err, isMembers) {
|
db.isMemberOfSets(groupSets, uid, function(err, isMembers) {
|
||||||
for(var i=isMembers.length - 1; i>=0; --i) {
|
for(var i=isMembers.length - 1; i>=0; --i) {
|
||||||
if (parseInt(isMembers[i], 10) !== 1) {
|
if (!isMembers[i]) {
|
||||||
groupData.splice(i, 1);
|
groupData.splice(i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
65
src/posts.js
65
src/posts.js
@@ -188,43 +188,46 @@ var async = require('async'),
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
Posts.getUserInfoForPost = function(post, callback) {
|
Posts.getUserInfoForPosts = function(uids, callback) {
|
||||||
user.getUserFields(post.uid, ['username', 'userslug', 'reputation', 'postcount', 'picture', 'signature', 'banned'], function(err, userData) {
|
user.getMultipleUserFields(uids, ['uid', 'username', 'userslug', 'reputation', 'postcount', 'picture', 'signature', 'banned'], function(err, userData) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
var userInfo = {
|
async.map(userData, function(userData, next) {
|
||||||
username: userData.username || '[[global:guest]]',
|
var userInfo = {
|
||||||
userslug: userData.userslug || '',
|
uid: userData.uid,
|
||||||
reputation: userData.reputation || 0,
|
username: userData.username || '[[global:guest]]',
|
||||||
postcount: userData.postcount || 0,
|
userslug: userData.userslug || '',
|
||||||
banned: parseInt(userData.banned, 10) === 1,
|
reputation: userData.reputation || 0,
|
||||||
picture: userData.picture || user.createGravatarURLFromEmail('')
|
postcount: userData.postcount || 0,
|
||||||
};
|
banned: parseInt(userData.banned, 10) === 1,
|
||||||
|
picture: userData.picture || user.createGravatarURLFromEmail('')
|
||||||
|
};
|
||||||
|
|
||||||
async.parallel({
|
async.parallel({
|
||||||
signature: function(next) {
|
signature: function(next) {
|
||||||
if (parseInt(meta.config.disableSignatures, 10) === 1) {
|
if (parseInt(meta.config.disableSignatures, 10) === 1) {
|
||||||
return next();
|
return next();
|
||||||
|
}
|
||||||
|
postTools.parseSignature(userData.signature, next);
|
||||||
|
},
|
||||||
|
customProfileInfo: function(next) {
|
||||||
|
plugins.fireHook('filter:posts.custom_profile_info', {profile: [], uid: userData.uid}, next);
|
||||||
|
},
|
||||||
|
groups: function(next) {
|
||||||
|
groups.getUserGroups(userData.uid, next);
|
||||||
}
|
}
|
||||||
postTools.parseSignature(userData.signature, next);
|
}, function(err, results) {
|
||||||
},
|
if (err) {
|
||||||
customProfileInfo: function(next) {
|
return next(err);
|
||||||
plugins.fireHook('filter:posts.custom_profile_info', {profile: [], uid: post.uid, pid: post.pid}, next);
|
}
|
||||||
},
|
userInfo.signature = results.signature;
|
||||||
groups: function(next) {
|
userInfo.custom_profile_info = results.custom_profile_info;
|
||||||
groups.getUserGroups(post.uid, next);
|
userInfo.groups = results.groups;
|
||||||
}
|
next(null, userInfo);
|
||||||
}, function(err, results) {
|
});
|
||||||
if (err) {
|
}, callback);
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
userInfo.signature = results.signature;
|
|
||||||
userInfo.custom_profile_info = results.custom_profile_info;
|
|
||||||
userInfo.groups = results.groups;
|
|
||||||
callback(null, userInfo);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -270,6 +270,9 @@ var async = require('async'),
|
|||||||
}
|
}
|
||||||
|
|
||||||
async.parallel({
|
async.parallel({
|
||||||
|
mainPost: function(next) {
|
||||||
|
Topics.getMainPost(tid, uid, next);
|
||||||
|
},
|
||||||
posts: function(next) {
|
posts: function(next) {
|
||||||
Topics.getTopicPosts(tid, set, start, end, uid, reverse, next);
|
Topics.getTopicPosts(tid, set, start, end, uid, reverse, next);
|
||||||
},
|
},
|
||||||
@@ -284,26 +287,6 @@ var async = require('async'),
|
|||||||
},
|
},
|
||||||
tags: function(next) {
|
tags: function(next) {
|
||||||
Topics.getTopicTagsObjects(tid, next);
|
Topics.getTopicTagsObjects(tid, next);
|
||||||
},
|
|
||||||
mainPost: function(next) {
|
|
||||||
Topics.getTopicField(tid, 'mainPid', function(err, mainPid) {
|
|
||||||
if (err) {
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
if (!parseInt(mainPid, 10)) {
|
|
||||||
return next(null, []);
|
|
||||||
}
|
|
||||||
posts.getPostsByPids([mainPid], function(err, postData) {
|
|
||||||
if (err) {
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
if (!Array.isArray(postData) || !postData[0]) {
|
|
||||||
return next(null, []);
|
|
||||||
}
|
|
||||||
postData[0].index = 0;
|
|
||||||
Topics.addPostData(postData, uid, next);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}, function(err, results) {
|
}, function(err, results) {
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -325,6 +308,27 @@ var async = require('async'),
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Topics.getMainPost = function(tid, uid, callback) {
|
||||||
|
Topics.getTopicField(tid, 'mainPid', function(err, mainPid) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
if (!parseInt(mainPid, 10)) {
|
||||||
|
return callback(null, []);
|
||||||
|
}
|
||||||
|
posts.getPostsByPids([mainPid], function(err, postData) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
if (!Array.isArray(postData) || !postData[0]) {
|
||||||
|
return callback(null, []);
|
||||||
|
}
|
||||||
|
postData[0].index = 0;
|
||||||
|
Topics.addPostData(postData, uid, callback);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Topics.getTeasers = function(tids, callback) {
|
Topics.getTeasers = function(tids, callback) {
|
||||||
|
|
||||||
if(!Array.isArray(tids)) {
|
if(!Array.isArray(tids)) {
|
||||||
|
|||||||
@@ -224,10 +224,10 @@ module.exports = function(Topics) {
|
|||||||
},
|
},
|
||||||
function(result, next) {
|
function(result, next) {
|
||||||
Topics.pushUnreadCount();
|
Topics.pushUnreadCount();
|
||||||
posts.getUserInfoForPost(postData, next);
|
posts.getUserInfoForPosts([postData.uid], next);
|
||||||
},
|
},
|
||||||
function(userInfo, next) {
|
function(userInfo, next) {
|
||||||
postData.user = userInfo;
|
postData.user = userInfo[0];
|
||||||
Topics.getTopicFields(tid, ['tid', 'title', 'slug'], next);
|
Topics.getTopicFields(tid, ['tid', 'title', 'slug'], next);
|
||||||
},
|
},
|
||||||
function(topicData, next) {
|
function(topicData, next) {
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ module.exports = function(Topics) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Topics.addPostData = function(postData, uid, callback) {
|
Topics.addPostData = function(postData, uid, callback) {
|
||||||
|
var st = process.hrtime();
|
||||||
var pids = postData.map(function(post) {
|
var pids = postData.map(function(post) {
|
||||||
return post.pid;
|
return post.pid;
|
||||||
});
|
});
|
||||||
@@ -54,27 +55,43 @@ module.exports = function(Topics) {
|
|||||||
favourites.getVoteStatusByPostIDs(pids, uid, next);
|
favourites.getVoteStatusByPostIDs(pids, uid, next);
|
||||||
},
|
},
|
||||||
userData: function(next) {
|
userData: function(next) {
|
||||||
async.each(postData, function(post, next) {
|
var uids = [];
|
||||||
async.parallel({
|
for(var i=0; i<postData.length; ++i) {
|
||||||
editor: function(next) {
|
if (uids.indexOf(postData[i].uid) === -1) {
|
||||||
if (!post.editor) {
|
uids.push(postData[i].uid);
|
||||||
return next();
|
}
|
||||||
}
|
}
|
||||||
user.getUserFields(post.editor, ['username', 'userslug'], next);
|
|
||||||
},
|
|
||||||
user: function(next) {
|
|
||||||
posts.getUserInfoForPost(post, next);
|
|
||||||
}
|
|
||||||
}, function(err, results) {
|
|
||||||
if (err) {
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
post.user = results.user;
|
posts.getUserInfoForPosts(uids, function(err, users) {
|
||||||
post.editor = results.editor;
|
if (err) {
|
||||||
next();
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
var userData = {};
|
||||||
|
users.forEach(function(user) {
|
||||||
|
userData[user.uid] = user;
|
||||||
});
|
});
|
||||||
}, next);
|
next(null, userData);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
editors: function(next) {
|
||||||
|
var editors = [];
|
||||||
|
for(var i=0; i<postData.length; ++i) {
|
||||||
|
if (postData[i].editor && editors.indexOf(postData[i].editor) === -1) {
|
||||||
|
editors.push(postData[i].editor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
user.getMultipleUserFields(editors, ['uid', 'username', 'userslug'], function(err, editors) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
var editorData = {};
|
||||||
|
editors.forEach(function(editor) {
|
||||||
|
editorData[editor.uid] = editor;
|
||||||
|
})
|
||||||
|
next(null, editorData);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
privileges: function(next) {
|
privileges: function(next) {
|
||||||
async.map(pids, function (pid, next) {
|
async.map(pids, function (pid, next) {
|
||||||
@@ -88,9 +105,11 @@ module.exports = function(Topics) {
|
|||||||
|
|
||||||
for (var i = 0; i < postData.length; ++i) {
|
for (var i = 0; i < postData.length; ++i) {
|
||||||
postData[i].deleted = parseInt(postData[i].deleted, 10) === 1;
|
postData[i].deleted = parseInt(postData[i].deleted, 10) === 1;
|
||||||
|
postData[i].user = results.userData[postData[i].uid];
|
||||||
|
postData[i].editor = postData[i].editor ? results.editors[postData[i].editor] : null;
|
||||||
postData[i].favourited = results.favourites[i];
|
postData[i].favourited = results.favourites[i];
|
||||||
postData[i].upvoted = results.voteData[i].upvoted;
|
postData[i].upvoted = results.voteData.upvotes[i];
|
||||||
postData[i].downvoted = results.voteData[i].downvoted;
|
postData[i].downvoted = results.voteData.downvotes[i];
|
||||||
postData[i].votes = postData[i].votes || 0;
|
postData[i].votes = postData[i].votes || 0;
|
||||||
postData[i].display_moderator_tools = results.privileges[i].editable;
|
postData[i].display_moderator_tools = results.privileges[i].editable;
|
||||||
postData[i].display_move_tools = results.privileges[i].move && postData[i].index !== 0;
|
postData[i].display_move_tools = results.privileges[i].move && postData[i].index !== 0;
|
||||||
@@ -100,7 +119,7 @@ module.exports = function(Topics) {
|
|||||||
postData[i].content = '[[topic:post_is_deleted]]';
|
postData[i].content = '[[topic:post_is_deleted]]';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
process.profile('derp', st);
|
||||||
callback(null, postData);
|
callback(null, postData);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ module.exports = function(Topics) {
|
|||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
var newtids = tids.filter(function(tid, index, self) {
|
var newtids = tids.filter(function(tid, index, self) {
|
||||||
return parseInt(read[index], 10) === 0;
|
return !read[index];
|
||||||
});
|
});
|
||||||
|
|
||||||
async.filter(newtids, function(tid, next) {
|
async.filter(newtids, function(tid, next) {
|
||||||
|
|||||||
Reference in New Issue
Block a user