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 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
- * Bulk insert
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
  #
@@ -1,3 +1,3 @@
1
1
  class Leaderboard
2
- VERSION = '2.0.4'.freeze
2
+ VERSION = '2.0.5'.freeze
3
3
  end
data/test/test_helper.rb CHANGED
@@ -6,7 +6,7 @@ require 'leaderboard'
6
6
  class LeaderboardTest < Test::Unit::TestCase
7
7
 
8
8
  def test_version
9
- assert_equal '2.0.4', Leaderboard::VERSION
9
+ assert_equal '2.0.5', Leaderboard::VERSION
10
10
  end
11
11
 
12
12
  private
@@ -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
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-02-29 00:00:00.000000000 Z
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: &70133210061060 !ruby/object:Gem::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: *70133210061060
24
+ version_requirements: *2161382920
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &70133210060620 !ruby/object:Gem::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: *70133210060620
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: 182894351603387394
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: 182894351603387394
81
+ hash: 1692368560274540289
82
82
  requirements: []
83
83
  rubyforge_project: leaderboard
84
84
  rubygems_version: 1.8.10