Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More pipelining #58

Merged
merged 1 commit into from
Sep 16, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 39 additions & 10 deletions lib/competition_ranking_leaderboard.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,29 +67,36 @@ def ranked_in_list_in(leaderboard_name, members, options = {})
end
end unless leaderboard_options[:members_only]

included_members = []
scores = []

members.each_with_index do |member, index|
data = {}
data[@member_key] = member
unless leaderboard_options[:members_only]
data[@score_key] = responses[index * 2 + 1].to_f if responses[index * 2 + 1]

if data[@score_key] == nil
next unless leaderboard_options[:include_missing]
end

if @reverse
data[@rank_key] = @redis_connection.zcount(leaderboard_name, '-inf', "(#{data[@score_key]}") + 1 rescue nil
else
data[@rank_key] = @redis_connection.zcount(leaderboard_name, "(#{data[@score_key]}", '+inf') + 1 rescue nil
end
end

if leaderboard_options[:with_member_data]
data[@member_data_key] = member_data_for_in(leaderboard_name, member)
end
included_members << member
scores << data[@score_key]

ranks_for_members << data
end

if leaderboard_options[:with_member_data]
members_data_for_in(leaderboard_name, included_members).each_with_index do |member_data, index|
ranks_for_members[index][@member_data_key] = member_data
end
end

rankings_for_members_having_scores_in(leaderboard_name, included_members, scores).each_with_index do |rank, index|
ranks_for_members[index][@rank_key] = rank
end

case leaderboard_options[:sort_by]
when :rank
ranks_for_members = ranks_for_members.sort_by { |member| member[@rank_key] }
Expand All @@ -99,4 +106,26 @@ def ranked_in_list_in(leaderboard_name, members, options = {})

ranks_for_members
end
end

protected

# Retrieve a list of the rankings of leaders given their member names and scores
#
# @param leaderboard_name [String] Name of the leaderboard.
# @param members [Array] Member names.
# @param scores [Array] a list of scores for the members, aligned with the member names
#
# @return a list of the rankings for the passed in members and scores
def rankings_for_members_having_scores_in(leaderboard_name, members, scores)
@redis_connection.multi do |transaction|
members.each_with_index do |member, index|
if @reverse
transaction.zcount(leaderboard_name, '-inf', "(#{scores[index]}")
else
transaction.zcount(leaderboard_name, "(#{scores[index]}", '+inf')
end
end
end.map{|rank| rank ? rank + 1 : rank}
end

end
30 changes: 26 additions & 4 deletions lib/leaderboard.rb
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,26 @@ def member_data_for_in(leaderboard_name, member)
@redis_connection.hget(member_data_key(leaderboard_name), member)
end

# Retrieve the optional member data for a given member in the named leaderboard.
#
# @param leaderboard_name [String] Name of the leaderboard.
# @param members [Array] Member names.
#
# @return array of strings of optional member data.
def members_data_for_in(leaderboard_name, members)
return [] unless members.size > 0
@redis_connection.hmget(member_data_key(leaderboard_name), *members)
end

# Retrieve the optional member data for the given members in the leaderboard.
#
# @param members [Array] Member names.
#
# @return array of strings of optional member data.
def members_data_for(members)
members_data_for_in(@leaderboard_name, members)
end

# Update the optional member data for a given member in the leaderboard.
#
# @param member [String] Member name.
Expand Down Expand Up @@ -964,13 +984,15 @@ def ranked_in_list_in(leaderboard_name, members, options = {})
data[@score_key] = responses[index * 2 + 1].to_f if responses[index * 2 + 1]
end

if leaderboard_options[:with_member_data]
data[@member_data_key] = member_data_for_in(leaderboard_name, member)
end

ranks_for_members << data
end

if leaderboard_options[:with_member_data]
members_data_for_in(leaderboard_name, members).each_with_index do |member_data, index|
ranks_for_members[index][@member_data_key] = member_data
end
end

case leaderboard_options[:sort_by]
when :rank
ranks_for_members = ranks_for_members.sort_by { |member| member[@rank_key] }
Expand Down
10 changes: 6 additions & 4 deletions lib/tie_ranking_leaderboard.rb
Original file line number Diff line number Diff line change
Expand Up @@ -249,13 +249,15 @@ def ranked_in_list_in(leaderboard_name, members, options = {})
end
end

if leaderboard_options[:with_member_data]
data[@member_data_key] = member_data_for_in(leaderboard_name, member)
end

ranks_for_members << data
end

if leaderboard_options[:with_member_data]
members_data_for_in(leaderboard_name, members).each_with_index do |member_data, index|
ranks_for_members[index][@member_data_key] = member_data
end
end

case leaderboard_options[:sort_by]
when :rank
ranks_for_members = ranks_for_members.sort_by { |member| member[@rank_key] }
Expand Down