class CompetitionRankingLeaderboard

Public Instance Methods

rank_for_in(leaderboard_name, member) click to toggle source

Retrieve the rank for a member in the named leaderboard.

@param leaderboard_name [String] Name of the leaderboard. @param member [String] Member name.

@return the rank for a member in the leaderboard.

# File lib/competition_ranking_leaderboard.rb, line 10
def rank_for_in(leaderboard_name, member)
  member_score = score_for_in(leaderboard_name, member)
  if @reverse
    return @redis_connection.zcount(leaderboard_name, '-inf', "(#{member_score}") + 1 rescue nil
  else
    return @redis_connection.zcount(leaderboard_name, "(#{member_score}", '+inf') + 1 rescue nil
  end
end
ranked_in_list_in(leaderboard_name, members, options = {}) click to toggle source

Retrieve a page of leaders from the named leaderboard for a given list of members.

@param leaderboard_name [String] Name of the leaderboard. @param members [Array] Member names. @param options [Hash] Options to be used when retrieving the page from the named leaderboard.

@return a page of leaders from the named leaderboard for a given list of members.

# File lib/competition_ranking_leaderboard.rb, line 53
def ranked_in_list_in(leaderboard_name, members, options = {})
  leaderboard_options = DEFAULT_LEADERBOARD_REQUEST_OPTIONS.dup
  leaderboard_options.merge!(options)

  ranks_for_members = []

  responses = @redis_connection.multi do |transaction|
    members.each do |member|
      if @reverse
        transaction.zrank(leaderboard_name, member)
      else
        transaction.zrevrank(leaderboard_name, member)
      end
      transaction.zscore(leaderboard_name, member)
    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
    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] }
  when :score
    ranks_for_members = ranks_for_members.sort_by { |member| member[@score_key] }
  end

  ranks_for_members
end
score_and_rank_for_in(leaderboard_name, member) click to toggle source

Retrieve the score and rank for a member in the named leaderboard.

@param leaderboard_name [String]Name of the leaderboard. @param member [String] Member name.

@return the score and rank for a member in the named leaderboard as a Hash.

# File lib/competition_ranking_leaderboard.rb, line 25
def score_and_rank_for_in(leaderboard_name, member)
  responses = @redis_connection.multi do |transaction|
    transaction.zscore(leaderboard_name, member)
    if @reverse
      transaction.zrank(leaderboard_name, member)
    else
      transaction.zrevrank(leaderboard_name, member)
    end
  end

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

  {@member_key => member, @score_key => responses[0], @rank_key => responses[1]}
end

Protected Instance Methods

rankings_for_members_having_scores_in(leaderboard_name, members, scores) click to toggle source

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

# File lib/competition_ranking_leaderboard.rb, line 119
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