5
5
import lombok .extern .slf4j .Slf4j ;
6
6
import redis .clients .jedis .Jedis ;
7
7
import redis .clients .jedis .Pipeline ;
8
+ import redis .clients .jedis .Response ;
8
9
import redis .clients .jedis .Tuple ;
9
10
10
11
import java .util .*;
@@ -159,9 +160,9 @@ public RankElement getRankByMemberWithNoRegions(String member) {
159
160
private List <RankElement > getRankElementListWithNoRegions (long begin , long end , boolean isAsc ) {
160
161
Set <Tuple > tuples ;
161
162
if (isAsc ) {
162
- tuples = jedis .zrevrangeWithScores (RANK , begin , end );
163
- } else {
164
163
tuples = jedis .zrangeWithScores (RANK , begin , end );
164
+ } else {
165
+ tuples = jedis .zrevrangeWithScores (RANK , begin , end );
165
166
}
166
167
167
168
if (CollectionUtil .isEmpty (tuples )) {
@@ -214,16 +215,32 @@ private void saveRankWithNoRegions(final String member, final double score) {
214
215
*/
215
216
public RankRegionElement getRankByMemberWithRegions (String member ) {
216
217
long totalRank = TOTAL_RANK_LENGTH ;
218
+
219
+ // pipeline 合并查询
220
+ List <Response <Long >> responseList = new LinkedList <>();
221
+ Pipeline pipeline = jedis .pipelined ();
217
222
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 ();
220
226
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 );
222
238
totalRank = getTotalRank (region .getRegionNo (), rank );
223
239
return new RankRegionElement (region .getRegionNo (), region .getRegionKey (), member , null , rank ,
224
240
totalRank );
225
241
}
226
242
}
243
+
227
244
int lastRegionNo = getLastRegionNo ();
228
245
return new RankRegionElement (lastRegionNo , getRankRedisKey (lastRegionNo ), member , null , null , totalRank );
229
246
}
@@ -242,9 +259,11 @@ public List<RankRegionElement> getRankElementListWithRegions(long begin, long en
242
259
return null ;
243
260
}
244
261
245
- List <RankRegionElement > finalList = new LinkedList <>();
262
+ List <Response <Set <Tuple >>> responseList = new LinkedList <>();
263
+ Pipeline pipeline = jedis .pipelined ();
246
264
for (RankRegion region : REGIONS ) {
247
265
266
+ // 计算当前分区的起始、结束位置
248
267
long regionBegin = region .getRegionNo ();
249
268
long regionEnd = region .getRegionNo () + region .getMaxSize () - 1 ;
250
269
@@ -256,53 +275,67 @@ public List<RankRegionElement> getRankElementListWithRegions(long begin, long en
256
275
continue ;
257
276
}
258
277
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 ));
267
294
}
268
295
}
269
- return finalList ;
296
+ pipeline .syncAndReturnAll ();
297
+
298
+ return parseZsetTuples (responseList );
270
299
}
271
300
272
301
/**
273
- * 获取指定分区中指定排名范围的信息
274
- *
275
- * @param region 指定榜单分区
276
- * @param begin 起始排名
277
- * @param end 结束排名
278
- * @param isAsc true:从低到高 / false:从高到低
279
- * @return 匹配排名的信息
302
+ * 解析 pipeline 返回的 zset 响应结果,转化为 List<RankRegionElement>
280
303
*/
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 ) {
290
305
291
- if (CollectionUtil .isEmpty (tuples )) {
292
- return null ;
306
+ List <RankRegionElement > finalList = new LinkedList <>();
307
+ if (CollectionUtil .isEmpty (responseList )) {
308
+ return finalList ;
293
309
}
294
310
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
+ }
304
337
}
305
- return list ;
338
+ return finalList ;
306
339
}
307
340
308
341
/**
0 commit comments