Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 170 lines (122 sloc) 8.219 kB
64110ca @czarneckid Initial commit to leaderboard.
czarneckid authored
1 = leaderboard
2
20eb87d @czarneckid Added information to README.
czarneckid authored
3 Leaderboards backed by Redis, http://redis.io.
923a0a5 @czarneckid Removed flush method since that is probably dangerous. Updated test s…
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 s…
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 appropr…
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 appropr…
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 appropr…
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 appropr…
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 appropr…
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 an…
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
6d35873 @czarneckid Updating README
czarneckid authored
94
2f23780 @czarneckid Adding peformance metrics section.
czarneckid authored
95 == Performance Metrics
96
97 10 million sequential scores insert:
98
99 ruby-1.8.7-p302 > insert_time = Benchmark.measure do
100 ruby-1.8.7-p302 > 1.upto(10000000) do |index|
101 ruby-1.8.7-p302 > highscore_lb.add_member("member_#{index}", index)
102 ruby-1.8.7-p302 ?> end
103 ruby-1.8.7-p302 ?> end
104 => #<Benchmark::Tms:0x101605660 @label="", @stime=173.61, @total=577.52, @real=911.718175172806, @utime=403.91, @cstime=0.0, @cutime=0.0>
105
106 Average time to request an arbitrary page from the leaderboard:
107
108 ruby-1.8.7-p302 > requests_to_make = 50000
109 => 50000
110 ruby-1.8.7-p302 > lb_request_time = 0
111 => 0
112 ruby-1.8.7-p302 > 1.upto(requests_to_make) do
113 ruby-1.8.7-p302 > lb_request_time += Benchmark.measure do
114 ruby-1.8.7-p302 > highscore_lb.leaders(rand(highscore_lb.total_pages))
115 ruby-1.8.7-p302 ?> end.total
116 ruby-1.8.7-p302 ?> end
117 => 1
118 ruby-1.8.7-p302 >
119 ruby-1.8.7-p302 > p lb_request_time / requests_to_make
120 0.001808
121 => nil
122
123 10 million random scores insert:
124
125 ruby-1.8.7-p302 > insert_time = Benchmark.measure do
126 ruby-1.8.7-p302 > 1.upto(10000000) do |index|
127 ruby-1.8.7-p302 > highscore_lb.add_member("member_#{index}", rand(50000000))
128 ruby-1.8.7-p302 ?> end
129 ruby-1.8.7-p302 ?> end
130 => #<Benchmark::Tms:0x10164ebf8 @label="", @stime=172.94, @total=577.91, @real=1356.57155895233, @utime=404.97, @cstime=0.0, @cutime=0.0>
131
132 Average time to request an arbitrary page from the leaderboard:
133
134 ruby-1.8.7-p302 > requests_to_make = 50000
135 => 50000
136 ruby-1.8.7-p302 > lb_request_time = 0
137 => 0
138 ruby-1.8.7-p302 > 1.upto(requests_to_make) do
139 ruby-1.8.7-p302 > lb_request_time += Benchmark.measure do
140 ruby-1.8.7-p302 > highscore_lb.leaders(rand(highscore_lb.total_pages))
141 ruby-1.8.7-p302 ?> end.total
142 ruby-1.8.7-p302 ?> end
143 => 1
144 ruby-1.8.7-p302 >
145 ruby-1.8.7-p302 > p lb_request_time / requests_to_make
146 0.00179680000000001
147 => nil
38b8674 @czarneckid Updating README with Installation section.
czarneckid authored
148
149 == Future Ideas
150
151 * Bulk insert
1fe9495 @czarneckid Adding some more future ideas
czarneckid authored
152 * Atomicity for various operations?
38b8674 @czarneckid Updating README with Installation section.
czarneckid authored
153 * Is nil? OK to return if Redis returns no data or should it be []?
20eb87d @czarneckid Added information to README.
czarneckid authored
154
64110ca @czarneckid Initial commit to leaderboard.
czarneckid authored
155 == Contributing to leaderboard
156
157 * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
158 * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
159 * Fork the project
160 * Start a feature/bugfix branch
161 * Commit and push until you are happy with your contribution
162 * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
163 * 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.
164
165 == Copyright
166
167 Copyright (c) 2011 David Czarnecki. See LICENSE.txt for
168 further details.
169
Something went wrong with that request. Please try again.