ruby-redis-portertech 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ module Redis
2
+
3
+ VERSION = '0.0.3'
4
+
5
+ end
@@ -0,0 +1,279 @@
1
+ module Redis
2
+
3
+ #WARN Time complexity may not match C version in this module yet.
4
+ #TODO Should add and delete manipulate @keys instead of clearing?
5
+
6
+ module ZSets
7
+
8
+ class ZSet
9
+ include Enumerable
10
+
11
+ def initialize
12
+ @hash = Hash.new
13
+ @keys = nil
14
+ @keys_reverse = nil
15
+ end
16
+
17
+ def add(o, s = 0.0)
18
+ @hash[o] = s
19
+ @keys = nil
20
+ @keys_reverse = nil
21
+ self
22
+ end
23
+
24
+ def delete(o)
25
+ @keys = nil
26
+ @keys_reverse = nil
27
+ @hash.delete(o)
28
+ self
29
+ end
30
+
31
+ def include?(o)
32
+ @hash.include?(o)
33
+ end
34
+
35
+ def score(o)
36
+ @hash[o]
37
+ end
38
+
39
+ def size
40
+ @hash.size
41
+ end
42
+
43
+ def empty?
44
+ @hash.empty?
45
+ end
46
+
47
+ def each
48
+ block_given? or return enum_for(__method__)
49
+ to_a.each { |o| yield(o) }
50
+ self
51
+ end
52
+
53
+ def to_a
54
+ unless @keys
55
+ (@keys = @hash.to_a).sort! do |a, b|
56
+ a.reverse <=> b.reverse
57
+ end
58
+ end
59
+ @keys
60
+ end
61
+
62
+ def to_a_reverse
63
+ unless @keys_reverse
64
+ @keys_reverse = to_a.reverse
65
+ end
66
+ @keys_reverse
67
+ end
68
+
69
+ def range reverse, start ,stop, conversions, withscores = false
70
+ start = conversions.redis_i start
71
+ stop = conversions.redis_i stop
72
+ array = reverse ? to_a_reverse : to_a
73
+ start = 0 if start < -size
74
+ return array[start..stop].flatten(1) if withscores
75
+ (array[start..stop]||[]).collect{|i|i.first}
76
+ end
77
+
78
+ def range_by_score reverse, min, max, conversions, *args
79
+ withscores = offset = count = nil
80
+ until args.empty?
81
+ case args.shift.upcase
82
+ when 'LIMIT'
83
+ offset = args.shift.to_i
84
+ count = args.shift.to_i
85
+ when 'WITHSCORES'
86
+ withscores = true
87
+ else
88
+ raise 'bad arguments'
89
+ end
90
+ end
91
+ result = []
92
+ min_exclusive = false
93
+ if min[0..0] == '('
94
+ min_exclusive = true
95
+ min = min[1..-1]
96
+ end
97
+ min = conversions.redis_f min
98
+ max_exclusive = false
99
+ if max[0..0] == '('
100
+ max_exclusive = true
101
+ max = max[1..-1]
102
+ end
103
+ max = conversions.redis_f max
104
+ if reverse
105
+ x = min; min = max; max = x
106
+ end
107
+ (reverse ? to_a_reverse : to_a).each do |member, score|
108
+ next if min > score or (min_exclusive and min >= score)
109
+ next if max < score or (max_exclusive and max <= score)
110
+ if offset
111
+ offset -= 1
112
+ next unless offset < 0
113
+ offset = nil
114
+ end
115
+ result << member
116
+ result << score if withscores
117
+ if count
118
+ count -= 1
119
+ break if count == 0
120
+ end
121
+ end
122
+ result
123
+ end
124
+
125
+ def self.aggregate database, is_and, destination, numkeys, conversions, *args
126
+ numkeys = numkeys.to_i
127
+ aggregate = 'SUM'
128
+ keys = []
129
+ keys << args.shift while (numkeys -= 1) >= 0
130
+ weights = Array.new keys.size, 1
131
+ until args.empty?
132
+ case args.shift.upcase
133
+ when 'WEIGHTS'
134
+ weights = []
135
+ keys.size.times {weights << conversions.redis_f(args.shift, 'weight value is not a double')}
136
+ when 'AGGREGATE'
137
+ aggregate = args.shift.upcase
138
+ else
139
+ raise 'bad arguments'
140
+ end
141
+ end
142
+ results = []
143
+ keys.zip(weights) do |key, weight|
144
+ inner_result = ZSet.new
145
+ record = database[key] || ZSet.new
146
+ record.each do |member, score|
147
+ inner_result.add member, (score||1) * weight
148
+ end
149
+ results << inner_result
150
+ end
151
+ result = results.reduce do |memo, result|
152
+ n = is_and ? new : memo
153
+ result.each do |member, score|
154
+ next if is_and and !memo.include?(member)
155
+ test = [score, memo.score(member)].compact
156
+ text << 0 if test.empty?
157
+ case aggregate
158
+ when 'SUM'
159
+ score = test.reduce :+
160
+ when 'MIN'
161
+ score = test.min
162
+ when 'MAX'
163
+ score = test.max
164
+ else
165
+ raise 'bad arguments'
166
+ end
167
+ n.add member, score
168
+ end
169
+ n
170
+ end
171
+ database[destination] = result unless result.empty?
172
+ result.size
173
+ end
174
+
175
+ end
176
+
177
+ def redis_ZADD key, score, member
178
+ record = (@database[key] ||= ZSet.new)
179
+ result = !record.include?(member)
180
+ record.add member, redis_f(score)
181
+ result
182
+ end
183
+
184
+ def redis_ZINCRBY key, increment, member
185
+ record = (@database[key] ||= ZSet.new)
186
+ increment = redis_f increment
187
+ if record.include?(member)
188
+ score = record.score(member) + increment
189
+ else
190
+ score = increment
191
+ end
192
+ raise 'NaN' if score.nan?
193
+ record.add member, score
194
+ score
195
+ end
196
+
197
+ def redis_ZRANK key, member
198
+ record = (@database[key] || ZSet.new).to_a
199
+ record.index {|i| i[0]==member}
200
+ end
201
+
202
+ def redis_ZREM key, member
203
+ record = @database[key] || []
204
+ return false unless record.include? member
205
+ record.delete member
206
+ @database.delete key if record.empty?
207
+ return true
208
+ end
209
+
210
+ def redis_ZSCORE key, member
211
+ (@database[key] || ZSet.new).score member
212
+ end
213
+
214
+ def redis_ZREVRANK key, member
215
+ record = (@database[key] || ZSet.new).to_a_reverse
216
+ record.index {|i| i[0]==member}
217
+ end
218
+
219
+ def redis_ZCARD key
220
+ (@database[key] || []).size
221
+ end
222
+
223
+ def redis_ZREMRANGEBYSCORE key, min, max
224
+ record = @database[key] || ZSet.new
225
+ range = record.range_by_score(false, min, max, self)
226
+ range.each do |member, score|
227
+ record.delete member
228
+ end
229
+ range.size
230
+ end
231
+
232
+ def redis_ZCOUNT key, min, max
233
+ record = @database[key] || ZSet.new
234
+ record.range_by_score(false, min, max, self).size
235
+ end
236
+
237
+ def redis_ZREVRANGEBYSCORE key, min, max, *args
238
+ record = @database[key] || ZSet.new
239
+ record.range_by_score true, min, max, self, *args
240
+ end
241
+
242
+ def redis_ZRANGEBYSCORE key, min, max, *args
243
+ record = @database[key] || ZSet.new
244
+ record.range_by_score false, min, max, self, *args
245
+ end
246
+
247
+ def redis_ZRANGE key, start ,stop, withscores = false
248
+ record = @database[key] || ZSet.new
249
+ start = redis_i start
250
+ stop = redis_i stop
251
+ record.range false, start, stop, self, withscores
252
+ end
253
+
254
+ def redis_ZREVRANGE key, start ,stop, withscores = false
255
+ record = @database[key] || ZSet.new
256
+ start = redis_i start
257
+ stop = redis_i stop
258
+ record.range true, start, stop, self, withscores
259
+ end
260
+
261
+ def redis_ZREMRANGEBYRANK key, start, stop
262
+ record = @database[key] || ZSet.new
263
+ range = record.range false, start, stop, self
264
+ range.each do |member, score|
265
+ record.delete member
266
+ end
267
+ range.size
268
+ end
269
+
270
+ def redis_ZUNIONSTORE destination, numkeys, *args
271
+ ZSet.aggregate @database, false, destination, numkeys, self, *args
272
+ end
273
+
274
+ def redis_ZINTERSTORE destination, numkeys, *args
275
+ ZSet.aggregate @database, true, destination, numkeys, self, *args
276
+ end
277
+
278
+ end
279
+ end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-redis-portertech
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 3
10
+ version: 0.0.3
11
+ platform: ruby
12
+ authors:
13
+ - David Turnbull
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-11-21 00:00:00 -08:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: eventmachine
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: minitest
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id002
49
+ description:
50
+ email:
51
+ - dturnbull@gmail.com
52
+ executables:
53
+ - ruby-redis
54
+ extensions: []
55
+
56
+ extra_rdoc_files: []
57
+
58
+ files:
59
+ - bin/ruby-redis
60
+ - lib/redis/bin.rb
61
+ - lib/redis/client.rb
62
+ - lib/redis/config.rb
63
+ - lib/redis/connection.rb
64
+ - lib/redis/database.rb
65
+ - lib/redis/hashes.rb
66
+ - lib/redis/keys.rb
67
+ - lib/redis/lists.rb
68
+ - lib/redis/logger.rb
69
+ - lib/redis/protocol.rb
70
+ - lib/redis/pubsub.rb
71
+ - lib/redis/reader.rb
72
+ - lib/redis/sender.rb
73
+ - lib/redis/server.rb
74
+ - lib/redis/sets.rb
75
+ - lib/redis/strict.rb
76
+ - lib/redis/strings.rb
77
+ - lib/redis/synchrony.rb
78
+ - lib/redis/version.rb
79
+ - lib/redis/zsets.rb
80
+ - lib/redis.rb
81
+ - LICENSE
82
+ - README.md
83
+ has_rdoc: true
84
+ homepage: https://github.com/dturnbull/ruby-redis
85
+ licenses: []
86
+
87
+ post_install_message:
88
+ rdoc_options: []
89
+
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ hash: 3
98
+ segments:
99
+ - 0
100
+ version: "0"
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ hash: 23
107
+ segments:
108
+ - 1
109
+ - 3
110
+ - 6
111
+ version: 1.3.6
112
+ requirements: []
113
+
114
+ rubyforge_project: ruby-redis
115
+ rubygems_version: 1.3.7
116
+ signing_key:
117
+ specification_version: 3
118
+ summary: Ruby implementation of a Redis server and client
119
+ test_files: []
120
+