Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 171 lines (123 sloc) 8.523 kb
64110ca @czarneckid Initial commit to leaderboard.
czarneckid authored
1 = leaderboard
2
f1d44fb @czarneckid Added clarification about being Ruby
czarneckid authored
3 Leaderboards backed by Redis in Ruby, http://redis.io.
923a0a5 @czarneckid Removed flush method since that is probably dangerous. Updated test suit...
czarneckid authored
4
5 Builds off ideas proposed in http://blog.agoragames.com/2011/01/01/creating-high-score-tables-leaderboards-using-redis/.
6
38b8674 @czarneckid Updating README with Installation section.
czarneckid authored
7 == Installation
8
9 Install the gem:
10
11 gem install leaderboard
12
13 Make sure your redis server is running! Redis configuration is outside the scope of this README, but
14 check out the Redis documentation, http://redis.io/documentation.
4076a3e @czarneckid Updating README
czarneckid authored
15
16 == Compatibility
17
18 The gem has been built and tested under Ruby 1.8.7 and Ruby 1.9.2
38b8674 @czarneckid Updating README with Installation section.
czarneckid authored
19
20eb87d @czarneckid Added information to README.
czarneckid authored
20 == Usage
923a0a5 @czarneckid Removed flush method since that is probably dangerous. Updated test suit...
czarneckid authored
21
20eb87d @czarneckid Added information to README.
czarneckid authored
22 Create a new leaderboard or attach to an existing leaderboard named 'highscores':
64110ca @czarneckid Initial commit to leaderboard.
czarneckid authored
23
20eb87d @czarneckid Added information to README.
czarneckid authored
24 ruby-1.8.7-p302 > highscore_lb = Leaderboard.new('highscores')
25 => #<Leaderboard:0x1018e4250 @page_size=25, @port=6379, @host="localhost", @redis_connection=#<Redis client v2.1.1 connected to redis://localhost:6379/0 (Redis v2.1.10)>, @leaderboard_name="highscores">
1857ccc @czarneckid Updating README
czarneckid authored
26
27 If you need to pass in options for Redis, you can do this with the redis_options parameter:
28
29 redis_options = {:host => 'localhost', :port => 6379, :password => 'password', :db => 'some_redis_db'}
30 highscore_lb = Leaderboard.new('highscores', redis_options[:host], redis_options[:port], Leaderboard::DEFAULT_PAGE_SIZE, redis_options))
6d35873 @czarneckid Updating README
czarneckid authored
31
32 You can set the page size to something other than the default page size (25):
33
34 ruby-1.8.7-p302 > highscore_lb.page_size = 5
35 => 5
36 ruby-1.8.7-p302 > highscore_lb
37 => #<Leaderboard:0x1018e2130 @leaderboard_name="highscores", @page_size=5, @port=6379, @redis_connection=#<Redis client v2.1.1 connected to redis://localhost:6379/0 (Redis v2.1.10)>, @host="localhost", @redis_options={:host=>"localhost", :port=>6379}>
20eb87d @czarneckid Added information to README.
czarneckid authored
38
39 Add members to your leaderboard:
40
41 ruby-1.8.7-p302 > 1.upto(10) do |index|
42 ruby-1.8.7-p302 > highscore_lb.add_member("member_#{index}", index)
43 ruby-1.8.7-p302 ?> end
44 => 1
45
46 Get some information about your leaderboard:
47
48 ruby-1.8.7-p302 > highscore_lb.total_members
49 => 10
50 ruby-1.8.7-p302 > highscore_lb.total_pages
51 => 1
52
765d0ad @czarneckid Added method modifiers: with_rank, use_zero_index_for_rank to appropriat...
czarneckid authored
53 Get some information about a specific member(s) in the leaderboard:
20eb87d @czarneckid Added information to README.
czarneckid authored
54
55 ruby-1.8.7-p302 > highscore_lb.score_for('member_4')
56 => 4.0
57 ruby-1.8.7-p302 > highscore_lb.rank_for('member_4')
765d0ad @czarneckid Added method modifiers: with_rank, use_zero_index_for_rank to appropriat...
czarneckid authored
58 => 7
20eb87d @czarneckid Added information to README.
czarneckid authored
59 ruby-1.8.7-p302 > highscore_lb.rank_for('member_10')
765d0ad @czarneckid Added method modifiers: with_rank, use_zero_index_for_rank to appropriat...
czarneckid authored
60 => 1
20eb87d @czarneckid Added information to README.
czarneckid authored
61
62 Get page 1 in the leaderboard:
63
64 ruby-1.8.7-p302 > highscore_lb.leaders(1)
765d0ad @czarneckid Added method modifiers: with_rank, use_zero_index_for_rank to appropriat...
czarneckid authored
65 => [{:member=>"member_10", :rank=>1, :score=>"10"}, {:member=>"member_9", :rank=>2, :score=>"9"}, {:member=>"member_8", :rank=>3, :score=>"8"}, {:member=>"member_7", :rank=>4, :score=>"7"}, {:member=>"member_6", :rank=>5, :score=>"6"}, {:member=>"member_5", :rank=>6, :score=>"5"}, {:member=>"member_4", :rank=>7, :score=>"4"}, {:member=>"member_3", :rank=>8, :score=>"3"}, {:member=>"member_2", :rank=>9, :score=>"2"}, {:member=>"member_1", :rank=>10, :score=>"1"}]
66
20eb87d @czarneckid Added information to README.
czarneckid authored
67 Add more members to your leaderboard:
68
69 ruby-1.8.7-p302 > 50.upto(95) do |index|
70 ruby-1.8.7-p302 > highscore_lb.add_member("member_#{index}", index)
71 ruby-1.8.7-p302 ?> end
72 => 50
73 ruby-1.8.7-p302 > highscore_lb.total_pages
74 => 3
75
76 Get an "Around Me" leaderboard for a member:
77
78 ruby-1.8.7-p302 > highscore_lb.around_me('member_53')
765d0ad @czarneckid Added method modifiers: with_rank, use_zero_index_for_rank to appropriat...
czarneckid authored
79 => [{:member=>"member_65", :rank=>31, :score=>"65"}, {:member=>"member_64", :rank=>32, :score=>"64"}, {:member=>"member_63", :rank=>33, :score=>"63"}, {:member=>"member_62", :rank=>34, :score=>"62"}, {:member=>"member_61", :rank=>35, :score=>"61"}, {:member=>"member_60", :rank=>36, :score=>"60"}, {:member=>"member_59", :rank=>37, :score=>"59"}, {:member=>"member_58", :rank=>38, :score=>"58"}, {:member=>"member_57", :rank=>39, :score=>"57"}, {:member=>"member_56", :rank=>40, :score=>"56"}, {:member=>"member_55", :rank=>41, :score=>"55"}, {:member=>"member_54", :rank=>42, :score=>"54"}, {:member=>"member_53", :rank=>43, :score=>"53"}, {:member=>"member_52", :rank=>44, :score=>"52"}, {:member=>"member_51", :rank=>45, :score=>"51"}, {:member=>"member_50", :rank=>46, :score=>"50"}, {:member=>"member_10", :rank=>47, :score=>"10"}, {:member=>"member_9", :rank=>48, :score=>"9"}, {:member=>"member_8", :rank=>49, :score=>"8"}, {:member=>"member_7", :rank=>50, :score=>"7"}, {:member=>"member_6", :rank=>51, :score=>"6"}, {:member=>"member_5", :rank=>52, :score=>"5"}, {:member=>"member_4", :rank=>53, :score=>"4"}, {:member=>"member_3", :rank=>54, :score=>"3"}, {:member=>"member_2", :rank=>55, :score=>"2"}]
80
20eb87d @czarneckid Added information to README.
czarneckid authored
81 Get rank and score for an arbitrary list of members (e.g. friends):
82
83 ruby-1.8.7-p302 > highscore_lb.ranked_in_list(['member_1', 'member_62', 'member_67'], true)
083bdc9 @czarneckid Update README to reflect new data structure for ranked_in_list method.
czarneckid authored
84 => [{:rank=>55, :member=>"member_1", :score=>1.0}, {:rank=>33, :member=>"member_62", :score=>62.0}, {:rank=>28, :member=>"member_67", :score=>67.0}]
d2db28c @czarneckid Updating README with more methods
czarneckid authored
85
d48d5d9 @czarneckid Updating README
czarneckid authored
86 === Other useful methods
d2db28c @czarneckid Updating README with more methods
czarneckid authored
87
88 remove_member(member): Remove a member from the leaderboard
89 total_members_in_score_range(min_score, max_score): Count the number of members within a score range in the leaderboard
90 change_score_for(member, delta): Change the score for a member by some amount delta (delta could be positive or negative)
91 check_member?(member): Check to see whether member is in the leaderboard
4596d86 @czarneckid Added score_and_rank_for and remove_members_in_score_range methods and t...
czarneckid authored
92 score_and_rank_for(member, use_zero_index_for_rank = false): Retrieve the score and rank for a member in a single call
93 remove_members_in_score_range(min_score, max_score): Remove members from the leaderboard within a score range
3c08991 @czarneckid Added merge_leaderboards and intersect_leaderboards methods and tests. U...
czarneckid authored
94 merge_leaderboards(destination, keys, options = {:aggregate => :min}): Merge leaderboards given by keys with this leaderboard into destination
95 intersect_leaderboards(destination, keys, options = {:aggregate => :min}): Intersect leaderboards given by keys with this leaderboard into destination
6d35873 @czarneckid Updating README
czarneckid authored
96
2f23780 @czarneckid Adding peformance metrics section.
czarneckid authored
97 == Performance Metrics
98
99 10 million sequential scores insert:
100
101 ruby-1.8.7-p302 > insert_time = Benchmark.measure do
102 ruby-1.8.7-p302 > 1.upto(10000000) do |index|
103 ruby-1.8.7-p302 > highscore_lb.add_member("member_#{index}", index)
104 ruby-1.8.7-p302 ?> end
105 ruby-1.8.7-p302 ?> end
106 => #<Benchmark::Tms:0x101605660 @label="", @stime=173.61, @total=577.52, @real=911.718175172806, @utime=403.91, @cstime=0.0, @cutime=0.0>
107
108 Average time to request an arbitrary page from the leaderboard:
109
110 ruby-1.8.7-p302 > requests_to_make = 50000
111 => 50000
112 ruby-1.8.7-p302 > lb_request_time = 0
113 => 0
114 ruby-1.8.7-p302 > 1.upto(requests_to_make) do
115 ruby-1.8.7-p302 > lb_request_time += Benchmark.measure do
116 ruby-1.8.7-p302 > highscore_lb.leaders(rand(highscore_lb.total_pages))
117 ruby-1.8.7-p302 ?> end.total
118 ruby-1.8.7-p302 ?> end
119 => 1
120 ruby-1.8.7-p302 >
121 ruby-1.8.7-p302 > p lb_request_time / requests_to_make
122 0.001808
123 => nil
124
125 10 million random scores insert:
126
127 ruby-1.8.7-p302 > insert_time = Benchmark.measure do
128 ruby-1.8.7-p302 > 1.upto(10000000) do |index|
129 ruby-1.8.7-p302 > highscore_lb.add_member("member_#{index}", rand(50000000))
130 ruby-1.8.7-p302 ?> end
131 ruby-1.8.7-p302 ?> end
132 => #<Benchmark::Tms:0x10164ebf8 @label="", @stime=172.94, @total=577.91, @real=1356.57155895233, @utime=404.97, @cstime=0.0, @cutime=0.0>
133
134 Average time to request an arbitrary page from the leaderboard:
135
136 ruby-1.8.7-p302 > requests_to_make = 50000
137 => 50000
138 ruby-1.8.7-p302 > lb_request_time = 0
139 => 0
140 ruby-1.8.7-p302 > 1.upto(requests_to_make) do
141 ruby-1.8.7-p302 > lb_request_time += Benchmark.measure do
142 ruby-1.8.7-p302 > highscore_lb.leaders(rand(highscore_lb.total_pages))
143 ruby-1.8.7-p302 ?> end.total
144 ruby-1.8.7-p302 ?> end
145 => 1
146 ruby-1.8.7-p302 >
147 ruby-1.8.7-p302 > p lb_request_time / requests_to_make
148 0.00179680000000001
149 => nil
38b8674 @czarneckid Updating README with Installation section.
czarneckid authored
150
151 == Future Ideas
152
153 * Bulk insert
1fe9495 @czarneckid Adding some more future ideas
czarneckid authored
154 * Atomicity for various operations?
38b8674 @czarneckid Updating README with Installation section.
czarneckid authored
155 * Is nil? OK to return if Redis returns no data or should it be []?
20eb87d @czarneckid Added information to README.
czarneckid authored
156
64110ca @czarneckid Initial commit to leaderboard.
czarneckid authored
157 == Contributing to leaderboard
158
159 * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
160 * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
161 * Fork the project
162 * Start a feature/bugfix branch
163 * Commit and push until you are happy with your contribution
164 * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
165 * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
166
167 == Copyright
168
4fe4c05 @czarneckid Updating CHANGELOG. Updating README. Re-generated gemspec.
czarneckid authored
169 Copyright (c) 2011 David Czarnecki. See LICENSE.txt for further details.
64110ca @czarneckid Initial commit to leaderboard.
czarneckid authored
170
Something went wrong with that request. Please try again.