From eb57e01f450d32df5cf92930792d9ab7d484898d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E8=BE=89?= <1101635162@qq.com> Date: Sat, 21 Dec 2024 20:50:29 +0800 Subject: [PATCH] =?UTF-8?q?:art:=20follow=20count=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../symphony/cache/FollowingCountCache.java | 19 ++++++++++ .../symphony/service/FollowQueryService.java | 35 +++++++++++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/b3log/symphony/cache/FollowingCountCache.java diff --git a/src/main/java/org/b3log/symphony/cache/FollowingCountCache.java b/src/main/java/org/b3log/symphony/cache/FollowingCountCache.java new file mode 100644 index 00000000..13aca7c9 --- /dev/null +++ b/src/main/java/org/b3log/symphony/cache/FollowingCountCache.java @@ -0,0 +1,19 @@ +package org.b3log.symphony.cache; + +import org.b3log.latke.ioc.Singleton; +import org.json.JSONObject; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +@Singleton +public class FollowingCountCache { + + public static final Map COUNT_CACHE = Collections.synchronizedMap(new LinkedHashMap<>() { + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > 2000; + } + }); +} diff --git a/src/main/java/org/b3log/symphony/service/FollowQueryService.java b/src/main/java/org/b3log/symphony/service/FollowQueryService.java index 6646ebd8..ca3ca4c8 100644 --- a/src/main/java/org/b3log/symphony/service/FollowQueryService.java +++ b/src/main/java/org/b3log/symphony/service/FollowQueryService.java @@ -29,6 +29,7 @@ import org.b3log.latke.repository.*; import org.b3log.latke.service.annotation.Service; import org.b3log.latke.util.Stopwatchs; +import org.b3log.symphony.cache.FollowingCountCache; import org.b3log.symphony.model.Follow; import org.b3log.symphony.repository.ArticleRepository; import org.b3log.symphony.repository.FollowRepository; @@ -395,9 +396,23 @@ public long getFollowingCount(final String followerId, final int followingType) final List filters = new ArrayList<>(); filters.add(new PropertyFilter(Follow.FOLLOWER_ID, FilterOperator.EQUAL, followerId)); filters.add(new PropertyFilter(Follow.FOLLOWING_TYPE, FilterOperator.EQUAL, followingType)); + JSONObject cacheJSON = new JSONObject(); + cacheJSON.put(Follow.FOLLOWER_ID, followerId); + cacheJSON.put(Follow.FOLLOWING_TYPE, followingType); + JSONObject result = FollowingCountCache.COUNT_CACHE.get(cacheJSON.toString()); + if (result != null) { + if (result.optLong("time") > System.currentTimeMillis() - FIVE_MINUTES_IN_MILLIS) { + return result.optLong("count"); + } + } final Query query = new Query().setFilter(new CompositeFilter(CompositeFilterOperator.AND, filters)); try { - return followRepository.count(query); + long count = followRepository.count(query); + JSONObject json = new JSONObject(); + json.put("count", count); + json.put("time", System.currentTimeMillis()); + FollowingCountCache.COUNT_CACHE.put(cacheJSON.toString(), json); + return count; } catch (final RepositoryException e) { LOGGER.log(Level.ERROR, "Counts following count failed", e); return 0; @@ -407,6 +422,8 @@ public long getFollowingCount(final String followerId, final int followingType) } } + private static final long FIVE_MINUTES_IN_MILLIS = 1000 * 60 * 5; + /** * Gets the follower count of a following specified by the given following id and following type. * @@ -418,9 +435,23 @@ public long getFollowerCount(final String followingId, final int followingType) final List filters = new ArrayList<>(); filters.add(new PropertyFilter(Follow.FOLLOWING_ID, FilterOperator.EQUAL, followingId)); filters.add(new PropertyFilter(Follow.FOLLOWING_TYPE, FilterOperator.EQUAL, followingType)); + JSONObject cacheJSON = new JSONObject(); + cacheJSON.put(Follow.FOLLOWING_ID, followingId); + cacheJSON.put(Follow.FOLLOWING_TYPE, followingType); + JSONObject result = FollowingCountCache.COUNT_CACHE.get(cacheJSON.toString()); + if (result != null) { + if (result.optLong("time") > System.currentTimeMillis() - FIVE_MINUTES_IN_MILLIS) { + return result.optLong("count"); + } + } final Query query = new Query().setFilter(new CompositeFilter(CompositeFilterOperator.AND, filters)); try { - return followRepository.count(query); + long count = followRepository.count(query); + JSONObject json = new JSONObject(); + json.put("count", count); + json.put("time", System.currentTimeMillis()); + FollowingCountCache.COUNT_CACHE.put(cacheJSON.toString(), json); + return count; } catch (final RepositoryException e) { LOGGER.log(Level.ERROR, "Counts follower count failed", e); return 0;