leaderboard 2.0.4 → 2.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.markdown +4 -0
- data/README.markdown +48 -2
- data/lib/leaderboard.rb +23 -0
- data/lib/leaderboard/version.rb +1 -1
- data/test/test_helper.rb +1 -1
- data/test/test_leaderboard.rb +14 -0
- data/test/test_rev_leaderboard.rb +14 -0
- metadata +8 -8
data/CHANGELOG.markdown
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## leaderboard 2.0.5 (2012-03-14)
|
4
|
+
|
5
|
+
* Added `rank_members(members_and_scores)` and `rank_members_in(leaderboard_name, members_and_scores)` allowing you to pass in some variable number of `member_name, score` and so on or an actual array of those data items. Use this method to do bulk insert of data, but be mindful of the amount of data you are inserting since a single transaction can get quite large.
|
6
|
+
|
3
7
|
## leaderboard 2.0.4 (2012-02-29)
|
4
8
|
|
5
9
|
* Added `page_for(member, page_size = DEFAULT_PAGE_SIZE)` and `page_for_in(leaderboard_name, member, page_size = DEFAULT_PAGE_SIZE)` calls to allow you to determine the page where a member falls in the leaderboard
|
data/README.markdown
CHANGED
@@ -146,7 +146,23 @@ Get rank and score for an arbitrary list of members (e.g. friends):
|
|
146
146
|
```ruby
|
147
147
|
ruby-1.9.2-p180 :034 > highscore_lb.ranked_in_list(['member_1', 'member_62', 'member_67'])
|
148
148
|
=> [{:member=>"member_1", :rank=>56, :score=>1.0}, {:member=>"member_62", :rank=>34, :score=>62.0}, {:member=>"member_67", :rank=>29, :score=>67.0}]
|
149
|
-
```
|
149
|
+
```
|
150
|
+
|
151
|
+
Insert multiple data items for members and their associated scores:
|
152
|
+
|
153
|
+
As a splat:
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
highscore_lb.rank_members('member_1', 1, 'member_5', 5, 'member_10', 10)
|
157
|
+
```
|
158
|
+
|
159
|
+
Or as an array:
|
160
|
+
|
161
|
+
```ruby
|
162
|
+
highscore_lb.rank_members(['member_1', 1, 'member_5', 5, 'member_10', 10])
|
163
|
+
```
|
164
|
+
|
165
|
+
Use this method to do bulk insert of data, but be mindful of the amount of data you are inserting since a single transaction can get quite large.
|
150
166
|
|
151
167
|
### Other useful methods
|
152
168
|
|
@@ -164,6 +180,7 @@ Get rank and score for an arbitrary list of members (e.g. friends):
|
|
164
180
|
remove_members_in_score_range(min_score, max_score): Remove members from the leaderboard within a score range
|
165
181
|
percentile_for(member): Calculate the percentile for a given member
|
166
182
|
page_for(member, page_size): Determine the page where a member falls in the leaderboard
|
183
|
+
rank_members(members_and_scores): Rank an array of members in the leaderboard where you can call via (member_name, score) or pass in an array of [member_name, score]
|
167
184
|
merge_leaderboards(destination, keys, options = {:aggregate => :min}): Merge leaderboards given by keys with this leaderboard into destination
|
168
185
|
intersect_leaderboards(destination, keys, options = {:aggregate => :min}): Intersect leaderboards given by keys with this leaderboard into destination
|
169
186
|
```
|
@@ -228,9 +245,38 @@ Average time to request an arbitrary page from the leaderboard:
|
|
228
245
|
=> 0.0014615999999999531
|
229
246
|
```
|
230
247
|
|
248
|
+
Bulk insert performance:
|
249
|
+
|
250
|
+
Ranking individual members:
|
251
|
+
|
252
|
+
```ruby
|
253
|
+
1.9.3p0 :015 > insert_time = Benchmark.measure do
|
254
|
+
1.9.3p0 :016 > 1.upto(1000000) do |index|
|
255
|
+
1.9.3p0 :017 > highscore_lb.rank_member("member_#{index}", index)
|
256
|
+
1.9.3p0 :018?> end
|
257
|
+
1.9.3p0 :019?> end
|
258
|
+
=> 29.340000 15.050000 44.390000 ( 81.673507)
|
259
|
+
```
|
260
|
+
|
261
|
+
Ranking multiple members at once:
|
262
|
+
|
263
|
+
```ruby
|
264
|
+
1.9.3p0 :020 > member_data = []
|
265
|
+
=> []
|
266
|
+
1.9.3p0 :021 > 1.upto(1000000) do |index|
|
267
|
+
1.9.3p0 :022 > member_data << "member_#{index}"
|
268
|
+
1.9.3p0 :023?> member_data << index
|
269
|
+
1.9.3p0 :024?> end
|
270
|
+
=> 1
|
271
|
+
1.9.3p0 :025 > insert_time = Benchmark.measure do
|
272
|
+
1.9.3p0 :026 > highscore_lb.rank_members(member_data)
|
273
|
+
1.9.3p0 :027?> end
|
274
|
+
=> 22.390000 6.380000 28.770000 ( 31.144027)
|
275
|
+
```
|
276
|
+
|
231
277
|
## Future Ideas
|
232
278
|
|
233
|
-
*
|
279
|
+
* Ideas?
|
234
280
|
|
235
281
|
## Ports
|
236
282
|
|
data/lib/leaderboard.rb
CHANGED
@@ -102,6 +102,29 @@ class Leaderboard
|
|
102
102
|
def rank_member_in(leaderboard_name, member, score)
|
103
103
|
@redis_connection.zadd(leaderboard_name, score, member)
|
104
104
|
end
|
105
|
+
|
106
|
+
# Rank an array of members in the leaderboard.
|
107
|
+
#
|
108
|
+
# @param members_and_scores [Splat or Array] Variable list of members and scores
|
109
|
+
def rank_members(*members_and_scores)
|
110
|
+
rank_members_in(@leaderboard_name, *members_and_scores)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Rank an array of members in the named leaderboard.
|
114
|
+
#
|
115
|
+
# @param leaderboard_name [String] Name of the leaderboard.
|
116
|
+
# @param members_and_scores [Splat or Array] Variable list of members and scores
|
117
|
+
def rank_members_in(leaderboard_name, *members_and_scores)
|
118
|
+
if members_and_scores.is_a?(Array)
|
119
|
+
members_and_scores.flatten!
|
120
|
+
end
|
121
|
+
|
122
|
+
@redis_connection.multi do |transaction|
|
123
|
+
members_and_scores.each_slice(2) do |member_and_score|
|
124
|
+
transaction.zadd(leaderboard_name, member_and_score[1], member_and_score[0])
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
105
128
|
|
106
129
|
# Remove a member from the leaderboard.
|
107
130
|
#
|
data/lib/leaderboard/version.rb
CHANGED
data/test/test_helper.rb
CHANGED
data/test/test_leaderboard.rb
CHANGED
@@ -467,4 +467,18 @@ class TestLeaderboard < LeaderboardTest
|
|
467
467
|
assert_equal 2, @leaderboard.page_for('member_10', 10)
|
468
468
|
assert_equal 2, @leaderboard.page_for('member_1', 10)
|
469
469
|
end
|
470
|
+
|
471
|
+
def test_rank_members
|
472
|
+
assert_equal 0, @leaderboard.total_members
|
473
|
+
@leaderboard.rank_members('member_1', 1, 'member_10', 10)
|
474
|
+
assert_equal 2, @leaderboard.total_members
|
475
|
+
assert_equal 'member_10', @leaderboard.leaders(1).first[:member]
|
476
|
+
end
|
477
|
+
|
478
|
+
def test_rank_members_with_array
|
479
|
+
assert_equal 0, @leaderboard.total_members
|
480
|
+
@leaderboard.rank_members(['member_1', 1, 'member_10', 10])
|
481
|
+
assert_equal 2, @leaderboard.total_members
|
482
|
+
assert_equal 'member_10', @leaderboard.leaders(1).first[:member]
|
483
|
+
end
|
470
484
|
end
|
@@ -467,4 +467,18 @@ class TestRevLeaderboard < LeaderboardTest
|
|
467
467
|
assert_equal 2, @leaderboard.page_for('member_17', 10)
|
468
468
|
assert_equal 2, @leaderboard.page_for('member_11', 10)
|
469
469
|
end
|
470
|
+
|
471
|
+
def test_rank_members
|
472
|
+
assert_equal 0, @leaderboard.total_members
|
473
|
+
@leaderboard.rank_members('member_1', 1, 'member_10', 10)
|
474
|
+
assert_equal 2, @leaderboard.total_members
|
475
|
+
assert_equal 'member_1', @leaderboard.leaders(1).first[:member]
|
476
|
+
end
|
477
|
+
|
478
|
+
def test_rank_members_with_array
|
479
|
+
assert_equal 0, @leaderboard.total_members
|
480
|
+
@leaderboard.rank_members(['member_1', 1, 'member_10', 10])
|
481
|
+
assert_equal 2, @leaderboard.total_members
|
482
|
+
assert_equal 'member_1', @leaderboard.leaders(1).first[:member]
|
483
|
+
end
|
470
484
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: leaderboard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-03-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|
16
|
-
requirement: &
|
16
|
+
requirement: &2161382920 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2161382920
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &2161382500 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2161382500
|
36
36
|
description: Leaderboards backed by Redis in Ruby
|
37
37
|
email:
|
38
38
|
- dczarnecki@agoragames.com
|
@@ -69,7 +69,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
69
69
|
version: '0'
|
70
70
|
segments:
|
71
71
|
- 0
|
72
|
-
hash:
|
72
|
+
hash: 1692368560274540289
|
73
73
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
74
|
none: false
|
75
75
|
requirements:
|
@@ -78,7 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
78
|
version: '0'
|
79
79
|
segments:
|
80
80
|
- 0
|
81
|
-
hash:
|
81
|
+
hash: 1692368560274540289
|
82
82
|
requirements: []
|
83
83
|
rubyforge_project: leaderboard
|
84
84
|
rubygems_version: 1.8.10
|