Skip to content

Commit

Permalink
Update to version 2.0.1. Allow for only single options to be passed t…
Browse files Browse the repository at this point in the history
…o leaders, around_me and ranked_in_list - Addresses #4.
  • Loading branch information
David Czarnecki committed Oct 14, 2011
1 parent 4c3aa5d commit a8202e9
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 30 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.markdown
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# leaderboard 2.0.1

* Allow for only single options to be passed to `leaders`, `around_me` and `ranked_in_list` methods - https://github.com/agoragames/leaderboard/issues/4

# leaderboard 2.0.0 (2011-08-05)

* Change `add_member` to `rank_member` - https://github.com/agoragames/leaderboard/issues/3
Expand Down
8 changes: 4 additions & 4 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ source "http://rubygems.org"
# Add dependencies to develop your gem here.
# Include everything needed to run rake, tests, features, etc.
group :development do
gem "bundler", "~> 1.0.0"
gem "jeweler", "~> 1.5.2"
gem "rcov", ">= 0"
gem "bundler"
gem "jeweler"
gem "rcov"
end

gem 'redis', "~> 2.2.0"
gem 'redis'

6 changes: 3 additions & 3 deletions README.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Builds off ideas proposed in http://blog.agoragames.com/2011/01/01/creating-high

Install the gem:

gem "leaderboard", "~> 2.0.0"
gem "leaderboard", "~> 2.0.1"

Make sure your redis server is running! Redis configuration is outside the scope of this README, but
check out the Redis documentation, http://redis.io/documentation.
Expand Down Expand Up @@ -77,10 +77,10 @@ Get page 1 in the leaderboard:
ruby-1.9.2-p180 :025 > highscore_lb.leaders(1)
=> [{:member=>"member_10", :rank=>1, :score=>10.0}, {:member=>"member_9", :rank=>2, :score=>9.0}, {:member=>"member_8", :rank=>3, :score=>8.0}, {:member=>"member_7", :rank=>4, :score=>7.0}, {:member=>"member_6", :rank=>5, :score=>6.0}, {:member=>"member_5", :rank=>6, :score=>5.0}, {:member=>"member_4", :rank=>7, :score=>4.0}, {:member=>"member_3", :rank=>8, :score=>3.0}, {:member=>"member_2", :rank=>9, :score=>2.0}, {:member=>"member_1", :rank=>10, :score=>1.0}]

You can pass various options to the calls `leaders`, `around_me` and `ranked_in_list`. Valid options are :with_scores, :with_rank, :use_zero_index_for_rank and :page_size.
You can pass various options to the calls `leaders`, `around_me` and `ranked_in_list`. Valid options are `:with_scores`, `:with_rank`, `:use_zero_index_for_rank` and `:page_size`.
Below is an example of retrieving the first page in the leaderboard without ranks:

ruby-1.9.2-p180 :026 > highscore_lb.leaders(1, :with_scores => true, :with_rank => false, :use_zero_index_for_rank => false)
ruby-1.9.2-p180 :026 > highscore_lb.leaders(1, :with_rank => false)
=> [{:member=>"member_10", :score=>9.0}, {:member=>"member_9", :score=>7.0}, {:member=>"member_8", :score=>5.0}, {:member=>"member_7", :score=>3.0}, {:member=>"member_6", :score=>1.0}, {:member=>"member_5", :score=>0.0}, {:member=>"member_4", :score=>0.0}, {:member=>"member_3", :score=>0.0}, {:member=>"member_2", :score=>0.0}, {:member=>"member_1", :score=>0.0}]

Below is an example of retrieving the first page in the leaderboard without scores or ranks:
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.0.0
2.0.1
51 changes: 31 additions & 20 deletions lib/leaderboard.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require 'redis'

class Leaderboard
VERSION = '2.0.0'.freeze
VERSION = '2.0.1'.freeze

DEFAULT_PAGE_SIZE = 25
DEFAULT_OPTIONS = {
Expand Down Expand Up @@ -162,16 +162,19 @@ def remove_members_in_score_range_in(leaderboard_name, min_score, max_score)
@redis_connection.zremrangebyscore(leaderboard_name, min_score, max_score)
end

def leaders(current_page, options = DEFAULT_LEADERBOARD_REQUEST_OPTIONS)
def leaders(current_page, options = {})
leaders_in(@leaderboard_name, current_page, options)
end

def leaders_in(leaderboard_name, current_page, options = DEFAULT_LEADERBOARD_REQUEST_OPTIONS)
def leaders_in(leaderboard_name, current_page, options = {})
leaderboard_options = DEFAULT_LEADERBOARD_REQUEST_OPTIONS.dup
leaderboard_options.merge!(options)

if current_page < 1
current_page = 1
end

page_size = validate_page_size(options[:page_size]) || @page_size
page_size = validate_page_size(leaderboard_options[:page_size]) || @page_size

if current_page > total_pages_in(leaderboard_name, page_size)
current_page = total_pages_in(leaderboard_name, page_size)
Expand All @@ -188,20 +191,23 @@ def leaders_in(leaderboard_name, current_page, options = DEFAULT_LEADERBOARD_REQ

raw_leader_data = @redis_connection.zrevrange(leaderboard_name, starting_offset, ending_offset, :with_scores => false)
if raw_leader_data
return ranked_in_list_in(leaderboard_name, raw_leader_data, options)
return ranked_in_list_in(leaderboard_name, raw_leader_data, leaderboard_options)
else
return []
end
end

def around_me(member, options = DEFAULT_LEADERBOARD_REQUEST_OPTIONS)
def around_me(member, options = {})
around_me_in(@leaderboard_name, member, options)
end

def around_me_in(leaderboard_name, member, options = DEFAULT_LEADERBOARD_REQUEST_OPTIONS)
def around_me_in(leaderboard_name, member, options = {})
leaderboard_options = DEFAULT_LEADERBOARD_REQUEST_OPTIONS.dup
leaderboard_options.merge!(options)

reverse_rank_for_member = @redis_connection.zrevrank(leaderboard_name, member)

page_size = validate_page_size(options[:page_size]) || @page_size
page_size = validate_page_size(leaderboard_options[:page_size]) || @page_size

starting_offset = reverse_rank_for_member - (page_size / 2)
if starting_offset < 0
Expand All @@ -212,42 +218,47 @@ def around_me_in(leaderboard_name, member, options = DEFAULT_LEADERBOARD_REQUEST

raw_leader_data = @redis_connection.zrevrange(leaderboard_name, starting_offset, ending_offset, :with_scores => false)
if raw_leader_data
return ranked_in_list_in(leaderboard_name, raw_leader_data, options)
return ranked_in_list_in(leaderboard_name, raw_leader_data, leaderboard_options)
else
return []
end
end

def ranked_in_list(members, options = DEFAULT_LEADERBOARD_REQUEST_OPTIONS)
def ranked_in_list(members, options = {})
ranked_in_list_in(@leaderboard_name, members, options)
end

def ranked_in_list_in(leaderboard_name, members, options = DEFAULT_LEADERBOARD_REQUEST_OPTIONS)
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|
transaction.zrevrank(leaderboard_name, member) if options[:with_rank]
transaction.zscore(leaderboard_name, member) if options[:with_scores]
transaction.zrevrank(leaderboard_name, member) if leaderboard_options[:with_rank]
transaction.zscore(leaderboard_name, member) if leaderboard_options[:with_scores]
end
end

members.each_with_index do |member, index|
data = {}
data[:member] = member
if options[:with_scores]
if options[:with_rank]
if options[:use_zero_index_for_rank]
if leaderboard_options[:with_scores]
if leaderboard_options[:with_rank]
if leaderboard_options[:use_zero_index_for_rank]
data[:rank] = responses[index * 2]
else
data[:rank] = responses[index * 2] + 1
end

data[:score] = responses[index * 2 + 1].to_f
else
data[:score] = responses[index].to_f
end

data[:score] = responses[index * 2 + 1].to_f
else
if options[:with_rank]
if options[:use_zero_index_for_rank]
if leaderboard_options[:with_rank]
if leaderboard_options[:use_zero_index_for_rank]
data[:rank] = responses[index]
else
data[:rank] = responses[index] + 1
Expand Down
39 changes: 37 additions & 2 deletions test/test_leaderboard.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def teardown
end

def test_version
assert_equal '2.0.0', Leaderboard::VERSION
assert_equal '2.0.1', Leaderboard::VERSION
end

def test_initialize_with_defaults
Expand Down Expand Up @@ -134,7 +134,7 @@ def test_leaders_without_retrieving_scores_and_ranks
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)

assert_equal Leaderboard::DEFAULT_PAGE_SIZE, @leaderboard.total_members
leaders = @leaderboard.leaders(1, {:with_scores => false, :with_ranks => false})
leaders = @leaderboard.leaders(1, {:with_scores => false, :with_rank => false})

member_25 = {:member => 'member_25'}
assert_equal member_25, leaders[0]
Expand All @@ -143,6 +143,41 @@ def test_leaders_without_retrieving_scores_and_ranks
assert_equal member_1, leaders[24]
end

def test_leaders_with_only_various_options_should_respect_other_defaults
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE + 1)

leaders = @leaderboard.leaders(1, :page_size => 1)
assert_equal 1, leaders.size

leaders = @leaderboard.leaders(1, :with_rank => false)
assert_equal Leaderboard::DEFAULT_PAGE_SIZE, leaders.size
member_26 = {:member => 'member_26', :score => 26}
member_25 = {:member => 'member_25', :score => 25}
member_24 = {:member => 'member_24', :score => 24}
assert_equal member_26, leaders[0]
assert_equal member_25, leaders[1]
assert_equal member_24, leaders[2]

leaders = @leaderboard.leaders(1, :with_scores => false)
assert_equal Leaderboard::DEFAULT_PAGE_SIZE, leaders.size
member_26 = {:member => 'member_26', :rank => 1}
member_25 = {:member => 'member_25', :rank => 2}
assert_equal member_26, leaders[0]
assert_equal member_25, leaders[1]

leaders = @leaderboard.leaders(1, :with_scores => false, :with_rank => false)
assert_equal Leaderboard::DEFAULT_PAGE_SIZE, leaders.size
member_26 = {:member => 'member_26'}
member_25 = {:member => 'member_25'}
assert_equal member_26, leaders[0]
assert_equal member_25, leaders[1]

leaders = @leaderboard.leaders(1, :with_rank => false, :page_size => 1)
assert_equal 1, leaders.size
member_26 = {:member => 'member_26', :score => 26}
assert_equal member_26, leaders[0]
end

def test_around_me
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE * 3 + 1)

Expand Down

0 comments on commit a8202e9

Please sign in to comment.