From 78fa734017fa7804c83f57320d2026391f679212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bar=C4=B1=C5=9F=20Soner=20U=C5=9Fakl=C4=B1?= Date: Sun, 9 Dec 2018 16:03:41 -0500 Subject: [PATCH] feat: cache category tag whitelist --- src/categories/delete.js | 1 + src/categories/index.js | 28 ++++++++++++++++++++++++++-- src/categories/update.js | 4 ++++ src/topics/tags.js | 13 +++++++------ 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/categories/delete.js b/src/categories/delete.js index 9b5f208049..69f5a24045 100644 --- a/src/categories/delete.js +++ b/src/categories/delete.js @@ -104,6 +104,7 @@ module.exports = function (Categories) { 'cid:0:children', 'cid:' + results.parentCid + ':children', 'cid:' + cid + ':children', + 'cid:' + cid + ':tag:whitelist', ]); next(); }); diff --git a/src/categories/index.js b/src/categories/index.js index 37c7c97d3d..3a325b33f1 100644 --- a/src/categories/index.js +++ b/src/categories/index.js @@ -178,8 +178,32 @@ Categories.getCategories = function (cids, uid, callback) { }; Categories.getTagWhitelist = function (cids, callback) { - const keys = cids.map(cid => 'cid:' + cid + ':tag:whitelist'); - db.getSortedSetsMembers(keys, callback); + const cachedData = {}; + + const nonCachedCids = cids.filter((cid) => { + const data = cache.get('cid:' + cid + ':tag:whitelist'); + const isInCache = data !== undefined; + if (isInCache) { + cachedData[cid] = data; + } + return !isInCache; + }); + + if (!nonCachedCids.length) { + return setImmediate(callback, null, _.clone(cids.map(cid => cachedData[cid]))); + } + + const keys = nonCachedCids.map(cid => 'cid:' + cid + ':tag:whitelist'); + db.getSortedSetsMembers(keys, function (err, data) { + if (err) { + return callback(err); + } + nonCachedCids.forEach((cid, index) => { + cachedData[cid] = data[index]; + cache.set('cid:' + cid + ':tag:whitelist', data[index]); + }); + callback(null, _.clone(cids.map(cid => cachedData[cid]))); + }); }; function calculateTopicPostCount(category) { diff --git a/src/categories/update.js b/src/categories/update.js index b876cd22d6..a1ca3cc01f 100644 --- a/src/categories/update.js +++ b/src/categories/update.js @@ -137,6 +137,10 @@ module.exports = function (Categories) { var scores = tags.map((tag, index) => index); db.sortedSetAdd('cid:' + cid + ':tag:whitelist', scores, tags, next); }, + function (next) { + cache.del('cid:' + cid + ':tag:whitelist'); + next(); + }, ], callback); } diff --git a/src/topics/tags.js b/src/topics/tags.js index 5f78c39b97..4acc8810b5 100644 --- a/src/topics/tags.js +++ b/src/topics/tags.js @@ -7,6 +7,7 @@ var validator = require('validator'); var _ = require('lodash'); var db = require('../database'); var meta = require('../meta'); +var categories = require('../categories'); var plugins = require('../plugins'); var utils = require('../utils'); var batch = require('../batch'); @@ -59,13 +60,13 @@ module.exports = function (Topics) { Topics.getTopicField(tid, 'cid', next); }, function (cid, next) { - db.getSortedSetRange('cid:' + cid + ':tag:whitelist', 0, -1, next); + categories.getTagWhitelist([cid], next); }, function (tagWhitelist, next) { - if (!tagWhitelist.length) { + if (!Array.isArray(tagWhitelist[0]) || !tagWhitelist[0].length) { return next(null, tags); } - var whitelistSet = new Set(tagWhitelist); + const whitelistSet = new Set(tagWhitelist[0]); tags = tags.filter(tag => whitelistSet.has(tag)); next(null, tags); }, @@ -398,14 +399,14 @@ module.exports = function (Topics) { async.waterfall([ function (next) { if (parseInt(cid, 10)) { - db.getSortedSetRange('cid:' + cid + ':tag:whitelist', 0, -1, next); + categories.getTagWhitelist([cid], next); } else { setImmediate(next, null, []); } }, function (tagWhitelist, next) { - if (tagWhitelist.length) { - setImmediate(next, null, tagWhitelist); + if (Array.isArray(tagWhitelist[0]) && tagWhitelist[0].length) { + setImmediate(next, null, tagWhitelist[0]); } else { db.getSortedSetRevRange('tags:topic:count', 0, -1, next); }