Skip to content
This repository was archived by the owner on Apr 8, 2026. It is now read-only.

Commit dd3ba73

Browse files
committed
Use withscores to optmize leaders call where rank can be inferred.
1 parent ec30985 commit dd3ba73

5 files changed

Lines changed: 50 additions & 26 deletions

leaderboard/leaderboard.py

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,7 @@ def leaders(self, current_page, **options):
778778
'''
779779
return self.leaders_in(self.leaderboard_name, current_page, **options)
780780

781-
def leaders_in(self, leaderboard_name, current_page, **options):
781+
def leaders_in(self, leaderboard_name, current_page, members_only=False, **options):
782782
'''
783783
Retrieve a page of leaders from the named leaderboard.
784784
@@ -800,14 +800,33 @@ def leaders_in(self, leaderboard_name, current_page, **options):
800800

801801
ending_offset = (starting_offset + page_size) - 1
802802

803-
raw_leader_data = self._range_method(
803+
response = self._range_method(
804804
self.redis_connection,
805805
leaderboard_name,
806806
int(starting_offset),
807807
int(ending_offset),
808-
withscores=False)
809-
return self._parse_raw_members(
810-
leaderboard_name, raw_leader_data, **options)
808+
withscores=not members_only)
809+
810+
if members_only:
811+
return [{self.MEMBER_KEY: member} for member in response]
812+
813+
members = []
814+
ranks_for_members = []
815+
for i, (member, score) in enumerate(response):
816+
members.append(member)
817+
ranks_for_members.append({
818+
self.MEMBER_KEY: member,
819+
self.RANK_KEY: starting_offset + i + 1,
820+
self.SCORE_KEY: score,
821+
})
822+
823+
if options.get('with_member_data', False):
824+
self._with_member_data(leaderboard_name, members, ranks_for_members)
825+
826+
if 'sort_by' in options:
827+
self._sort_by(ranks_for_members, options['sort_by'])
828+
829+
return ranks_for_members
811830

812831
def all_leaders(self, **options):
813832
'''
@@ -1072,28 +1091,33 @@ def ranked_in_list_in(self, leaderboard_name, members, **options):
10721091

10731092
ranks_for_members.append(data)
10741093

1075-
if ('with_member_data' in options) and (True == options['with_member_data']):
1076-
for index, member_data in enumerate(self.members_data_for_in(leaderboard_name, members)):
1077-
try:
1078-
ranks_for_members[index][self.MEMBER_DATA_KEY] = member_data
1079-
except:
1080-
pass
1094+
if options.get('with_member_data', False):
1095+
self._with_member_data(leaderboard_name, members, ranks_for_members)
10811096

10821097
if 'sort_by' in options:
1083-
sort_value_if_none = float('-inf') if self.order == self.ASC else float('+inf')
1084-
if self.RANK_KEY == options['sort_by']:
1085-
ranks_for_members = sorted(
1086-
ranks_for_members,
1087-
key=lambda member: member.get(self.RANK_KEY) if member.get(self.RANK_KEY) is not None else sort_value_if_none
1088-
)
1089-
elif self.SCORE_KEY == options['sort_by']:
1090-
ranks_for_members = sorted(
1091-
ranks_for_members,
1092-
key=lambda member: member.get(self.SCORE_KEY) if member.get(self.SCORE_KEY) is not None else sort_value_if_none
1093-
)
1098+
self._sort_by(ranks_for_members, options['sort_by'])
10941099

10951100
return ranks_for_members
10961101

1102+
def _with_member_data(self, leaderboard_name, members, ranks_for_members):
1103+
for index, member_data in enumerate(self.members_data_for_in(leaderboard_name, members)):
1104+
try:
1105+
ranks_for_members[index][self.MEMBER_DATA_KEY] = member_data
1106+
except:
1107+
pass
1108+
1109+
def _sort_by(self, ranks_for_members, sort_by):
1110+
sort_value_if_none = float('-inf') if self.order == self.ASC else float('+inf')
1111+
if self.RANK_KEY == sort_by:
1112+
ranks_for_members.sort(
1113+
key=lambda member: member.get(self.RANK_KEY) if member.get(self.RANK_KEY) is not None else sort_value_if_none
1114+
)
1115+
elif self.SCORE_KEY == sort_by:
1116+
ranks_for_members.sort(
1117+
key=lambda member: member.get(self.SCORE_KEY) if member.get(self.SCORE_KEY) is not None else sort_value_if_none
1118+
)
1119+
return ranks_for_members
1120+
10971121
def merge_leaderboards(self, destination, keys, aggregate='SUM'):
10981122
'''
10991123
Merge leaderboards given by keys with this leaderboard into a named destination leaderboard.

test/leaderboard/competition_ranking_leaderboard_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
class CompetitionRankingLeaderboardTest(unittest.TestCase):
99

1010
def setUp(self):
11-
self.leaderboard = CompetitionRankingLeaderboard('ties')
11+
self.leaderboard = CompetitionRankingLeaderboard('ties', decode_responses=True)
1212

1313
def tearDown(self):
1414
self.leaderboard.redis_connection.flushdb()

test/leaderboard/reverse_competition_ranking_leaderboard_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class ReverseCompetitionRankingLeaderboardTest(unittest.TestCase):
1010

1111
def setUp(self):
1212
self.leaderboard = CompetitionRankingLeaderboard(
13-
'ties', order=Leaderboard.ASC)
13+
'ties', order=Leaderboard.ASC, decode_responses=True)
1414

1515
def tearDown(self):
1616
self.leaderboard.redis_connection.flushdb()

test/leaderboard/reverse_tie_ranking_leaderboard_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
class ReverseTieRankingLeaderboardTest(unittest.TestCase):
1010

1111
def setUp(self):
12-
self.leaderboard = TieRankingLeaderboard('ties', order=Leaderboard.ASC)
12+
self.leaderboard = TieRankingLeaderboard('ties', order=Leaderboard.ASC, decode_responses=True)
1313

1414
def tearDown(self):
1515
self.leaderboard.redis_connection.flushdb()

test/leaderboard/tie_ranking_leaderboard_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
class TieRankingLeaderboardTest(unittest.TestCase):
99

1010
def setUp(self):
11-
self.leaderboard = TieRankingLeaderboard('ties')
11+
self.leaderboard = TieRankingLeaderboard('ties', decode_responses=True)
1212

1313
def tearDown(self):
1414
self.leaderboard.redis_connection.flushdb()

0 commit comments

Comments
 (0)