55import lombok .extern .slf4j .Slf4j ;
66import redis .clients .jedis .Jedis ;
77import redis .clients .jedis .Pipeline ;
8+ import redis .clients .jedis .Response ;
89import redis .clients .jedis .Tuple ;
910
1011import java .util .*;
@@ -159,9 +160,9 @@ public RankElement getRankByMemberWithNoRegions(String member) {
159160 private List <RankElement > getRankElementListWithNoRegions (long begin , long end , boolean isAsc ) {
160161 Set <Tuple > tuples ;
161162 if (isAsc ) {
162- tuples = jedis .zrevrangeWithScores (RANK , begin , end );
163- } else {
164163 tuples = jedis .zrangeWithScores (RANK , begin , end );
164+ } else {
165+ tuples = jedis .zrevrangeWithScores (RANK , begin , end );
165166 }
166167
167168 if (CollectionUtil .isEmpty (tuples )) {
@@ -214,16 +215,32 @@ private void saveRankWithNoRegions(final String member, final double score) {
214215 */
215216 public RankRegionElement getRankByMemberWithRegions (String member ) {
216217 long totalRank = TOTAL_RANK_LENGTH ;
218+
219+ // pipeline 合并查询
220+ List <Response <Long >> responseList = new LinkedList <>();
221+ Pipeline pipeline = jedis .pipelined ();
217222 for (RankRegion region : REGIONS ) {
218- // 计算排行榜分区的 Redis Key
219- Long rank = jedis .zrevrank (region .getRegionKey (), member );
223+ responseList .add (pipeline .zrevrank (region .getRegionKey (), member ));
224+ }
225+ pipeline .syncAndReturnAll ();
220226
221- if (rank != null ) {
227+ if (CollectionUtil .isEmpty (responseList )) {
228+ log .error ("【排行榜】getRankByMemberWithRegions pipeline 结果为空!" );
229+ return null ;
230+ }
231+
232+ // 处理 pipeline 查询结果
233+ for (int i = 0 ; i < responseList .size (); i ++) {
234+ Response <Long > response = responseList .get (i );
235+ if (response != null && response .get () != null ) {
236+ Long rank = response .get ();
237+ RankRegion region = REGIONS .get (i );
222238 totalRank = getTotalRank (region .getRegionNo (), rank );
223239 return new RankRegionElement (region .getRegionNo (), region .getRegionKey (), member , null , rank ,
224240 totalRank );
225241 }
226242 }
243+
227244 int lastRegionNo = getLastRegionNo ();
228245 return new RankRegionElement (lastRegionNo , getRankRedisKey (lastRegionNo ), member , null , null , totalRank );
229246 }
@@ -242,9 +259,11 @@ public List<RankRegionElement> getRankElementListWithRegions(long begin, long en
242259 return null ;
243260 }
244261
245- List <RankRegionElement > finalList = new LinkedList <>();
262+ List <Response <Set <Tuple >>> responseList = new LinkedList <>();
263+ Pipeline pipeline = jedis .pipelined ();
246264 for (RankRegion region : REGIONS ) {
247265
266+ // 计算当前分区的起始、结束位置
248267 long regionBegin = region .getRegionNo ();
249268 long regionEnd = region .getRegionNo () + region .getMaxSize () - 1 ;
250269
@@ -256,53 +275,67 @@ public List<RankRegionElement> getRankElementListWithRegions(long begin, long en
256275 continue ;
257276 }
258277
259- long first = Math .max (regionBegin , begin );
260- long last = Math .min (regionEnd , end );
261- RankRegionElement firstElement = getRegionRank (first );
262- RankRegionElement lastElement = getRegionRank (last );
263- List <RankRegionElement > list = getRankElementListInRegion (region , firstElement .getRank (),
264- lastElement .getRank (), isAsc );
265- if (CollectionUtil .isNotEmpty (list )) {
266- finalList .addAll (list );
278+ // 计算查询区间
279+ RankRegionElement firstElement = getRegionRank (Math .max (regionBegin , begin ));
280+ RankRegionElement lastElement = getRegionRank (Math .min (regionEnd , end ));
281+ if (firstElement == null || lastElement == null ) {
282+ log .error ("【排行榜】查询区间错误!" );
283+ break ;
284+ }
285+ long first = firstElement .getRank ();
286+ long last = lastElement .getRank ();
287+
288+ if (isAsc ) {
289+ // 从低到高排名
290+ responseList .add (pipeline .zrangeWithScores (region .getRegionKey (), first , last ));
291+ } else {
292+ // 从高到低排名
293+ responseList .add (pipeline .zrevrangeWithScores (region .getRegionKey (), first , last ));
267294 }
268295 }
269- return finalList ;
296+ pipeline .syncAndReturnAll ();
297+
298+ return parseZsetTuples (responseList );
270299 }
271300
272301 /**
273- * 获取指定分区中指定排名范围的信息
274- *
275- * @param region 指定榜单分区
276- * @param begin 起始排名
277- * @param end 结束排名
278- * @param isAsc true:从低到高 / false:从高到低
279- * @return 匹配排名的信息
302+ * 解析 pipeline 返回的 zset 响应结果,转化为 List<RankRegionElement>
280303 */
281- private List <RankRegionElement > getRankElementListInRegion (RankRegion region , long begin , long end , boolean isAsc ) {
282- Set <Tuple > tuples ;
283- if (isAsc ) {
284- // 从低到高排名
285- tuples = jedis .zrangeWithScores (region .getRegionKey (), begin , end );
286- } else {
287- // 从高到低排名
288- tuples = jedis .zrevrangeWithScores (region .getRegionKey (), begin , end );
289- }
304+ private List <RankRegionElement > parseZsetTuples (List <Response <Set <Tuple >>> responseList ) {
290305
291- if (CollectionUtil .isEmpty (tuples )) {
292- return null ;
306+ List <RankRegionElement > finalList = new LinkedList <>();
307+ if (CollectionUtil .isEmpty (responseList )) {
308+ return finalList ;
293309 }
294310
295- long regionRank = 0 ;
296- List <RankRegionElement > list = new ArrayList <>();
297- for (Tuple tuple : tuples ) {
298- long totalRank = getTotalRank (region .getRegionNo (), regionRank );
299- RankRegionElement rankElementVo = new RankRegionElement (region .getRegionNo (), region .getRegionKey (),
300- tuple .getElement (), tuple .getScore (), regionRank ,
301- totalRank );
302- list .add (rankElementVo );
303- regionRank ++;
311+ for (int i = 0 ; i < responseList .size (); i ++) {
312+
313+ Response <Set <Tuple >> response = responseList .get (i );
314+ if (response == null || response .get () == null ) {
315+ continue ;
316+ }
317+
318+ Set <Tuple > tuples = response .get ();
319+ if (CollectionUtil .isEmpty (tuples )) {
320+ continue ;
321+ }
322+
323+ long regionRank = 0 ;
324+ RankRegion region = REGIONS .get (i );
325+ List <RankRegionElement > list = new ArrayList <>();
326+ for (Tuple tuple : tuples ) {
327+ long totalRank = getTotalRank (region .getRegionNo (), regionRank );
328+ RankRegionElement rankElementVo = new RankRegionElement (region .getRegionNo (), region .getRegionKey (),
329+ tuple .getElement (), tuple .getScore (),
330+ regionRank , totalRank );
331+ list .add (rankElementVo );
332+ regionRank ++;
333+ }
334+ if (CollectionUtil .isNotEmpty (list )) {
335+ finalList .addAll (list );
336+ }
304337 }
305- return list ;
338+ return finalList ;
306339 }
307340
308341 /**
0 commit comments