ruby-redis-portertech 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+