ffi-rzmq 0.9.2 → 0.9.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.
- data/History.txt +18 -0
- data/ffi-rzmq.gemspec +1 -1
- data/lib/ffi-rzmq/message.rb +16 -7
- data/lib/ffi-rzmq/socket.rb +66 -80
- data/lib/ffi-rzmq/version.rb +1 -1
- data/spec/socket_spec.rb +16 -6
- metadata +4 -6
data/History.txt
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
== 0.9.3 / 20111214
|
2
|
+
* Performance optimizations for #getsockopt.
|
3
|
+
|
4
|
+
* Fixed Message#copy and Message#move. They didn't work before.
|
5
|
+
|
6
|
+
* Cache LibZM::Msg.size in the ZMQ::Message class so that
|
7
|
+
initialization can skip recalculating what is effectively a
|
8
|
+
constant value. This speeds up ZMQ::Message instantiation by
|
9
|
+
5 to 10%. Wow.
|
10
|
+
|
11
|
+
* Modified calls to #super to use explicit arguments (e.g. #super())
|
12
|
+
because otherwise the Ruby runtime has to (at runtime) dig out
|
13
|
+
the arguments that are expected to be passed up the chain. By
|
14
|
+
explicitly listing the args and using parentheses, the runtime
|
15
|
+
can avoid that work and dispatch directly. This effects all
|
16
|
+
Ruby runtimes, but it was through the work of Evan Phoenix that
|
17
|
+
I figured this out. Results in a 2-5% speedup on method dispatch.
|
18
|
+
|
1
19
|
== 0.9.2 / 20111115
|
2
20
|
* Removed all references to the version4 API.
|
3
21
|
|
data/ffi-rzmq.gemspec
CHANGED
@@ -21,7 +21,7 @@ MRI 1.9.x, Rubinius and JRuby.}
|
|
21
21
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
22
|
s.require_paths = ["lib"]
|
23
23
|
|
24
|
-
s.add_runtime_dependency "ffi"
|
24
|
+
s.add_runtime_dependency "ffi"#, [">= 1.0.9"]
|
25
25
|
s.add_development_dependency "rspec", ["~> 2.6"]
|
26
26
|
s.add_development_dependency "rake"
|
27
27
|
end
|
data/lib/ffi-rzmq/message.rb
CHANGED
@@ -94,12 +94,10 @@ module ZMQ
|
|
94
94
|
end
|
95
95
|
|
96
96
|
def initialize message = nil
|
97
|
-
@state = :uninitialized
|
98
|
-
|
99
97
|
# allocate our own pointer so that we can tell it to *not* zero out
|
100
98
|
# the memory; it's pointless work since the library is going to
|
101
99
|
# overwrite it anyway.
|
102
|
-
@pointer = FFI::MemoryPointer.new
|
100
|
+
@pointer = FFI::MemoryPointer.new Message.msg_size, 1, false
|
103
101
|
|
104
102
|
if message
|
105
103
|
copy_in_string message
|
@@ -147,11 +145,11 @@ module ZMQ
|
|
147
145
|
alias :pointer :address
|
148
146
|
|
149
147
|
def copy source
|
150
|
-
LibZMQ.zmq_msg_copy @pointer, source
|
148
|
+
LibZMQ.zmq_msg_copy @pointer, source
|
151
149
|
end
|
152
150
|
|
153
151
|
def move source
|
154
|
-
LibZMQ.zmq_msg_move @pointer, source
|
152
|
+
LibZMQ.zmq_msg_move @pointer, source
|
155
153
|
end
|
156
154
|
|
157
155
|
# Provides the size of the data buffer for this +zmq_msg_t+ C struct.
|
@@ -193,6 +191,12 @@ module ZMQ
|
|
193
191
|
|
194
192
|
rc
|
195
193
|
end
|
194
|
+
|
195
|
+
# cache the msg size so we don't have to recalculate it when creating
|
196
|
+
# each new instance
|
197
|
+
@msg_size = LibZMQ::Msg.size
|
198
|
+
|
199
|
+
def self.msg_size() @msg_size; end
|
196
200
|
|
197
201
|
end # class Message
|
198
202
|
|
@@ -228,7 +232,7 @@ module ZMQ
|
|
228
232
|
# handles deallocation of the native memory buffer.
|
229
233
|
#
|
230
234
|
def copy_in_bytes bytes, len
|
231
|
-
rc = super
|
235
|
+
rc = super(bytes, len)
|
232
236
|
|
233
237
|
# make sure we have a way to deallocate this memory if the object goes
|
234
238
|
# out of scope
|
@@ -240,7 +244,7 @@ module ZMQ
|
|
240
244
|
# buffer.
|
241
245
|
#
|
242
246
|
def close
|
243
|
-
rc = super
|
247
|
+
rc = super()
|
244
248
|
remove_finalizer
|
245
249
|
rc
|
246
250
|
end
|
@@ -268,6 +272,11 @@ module ZMQ
|
|
268
272
|
end
|
269
273
|
end
|
270
274
|
|
275
|
+
# cache the msg size so we don't have to recalculate it when creating
|
276
|
+
# each new instance
|
277
|
+
# need to do this again because ivars are not inheritable
|
278
|
+
@msg_size = LibZMQ::Msg.size
|
279
|
+
|
271
280
|
end # class ManagedMessage
|
272
281
|
|
273
282
|
end # module ZMQ
|
data/lib/ffi-rzmq/socket.rb
CHANGED
@@ -82,7 +82,9 @@ module ZMQ
|
|
82
82
|
raise ContextError.new 'zmq_socket', 0, ETERM, "Context pointer was null"
|
83
83
|
end
|
84
84
|
|
85
|
-
@
|
85
|
+
@more_parts_array = []
|
86
|
+
@option_lookup = []
|
87
|
+
populate_option_lookup
|
86
88
|
|
87
89
|
define_finalizer
|
88
90
|
end
|
@@ -123,17 +125,17 @@ module ZMQ
|
|
123
125
|
# ZMQ::Util.resultcode_ok?(rc) ? puts("succeeded") : puts("failed")
|
124
126
|
#
|
125
127
|
def setsockopt name, value, length = nil
|
126
|
-
if
|
128
|
+
if 1 == @option_lookup[name]
|
127
129
|
length = 8
|
128
130
|
pointer = LibC.malloc length
|
129
131
|
pointer.write_long_long value
|
130
132
|
|
131
|
-
elsif
|
133
|
+
elsif 0 == @option_lookup[name]
|
132
134
|
length = 4
|
133
135
|
pointer = LibC.malloc length
|
134
136
|
pointer.write_int value
|
135
137
|
|
136
|
-
elsif
|
138
|
+
elsif 2 == @option_lookup[name]
|
137
139
|
length ||= value.size
|
138
140
|
|
139
141
|
# note: not checking errno for failed memory allocations :(
|
@@ -166,10 +168,9 @@ module ZMQ
|
|
166
168
|
# end
|
167
169
|
#
|
168
170
|
def more_parts?
|
169
|
-
|
170
|
-
rc = getsockopt ZMQ::RCVMORE, array
|
171
|
+
rc = getsockopt ZMQ::RCVMORE, @more_parts_array
|
171
172
|
|
172
|
-
Util.resultcode_ok?(rc) ?
|
173
|
+
Util.resultcode_ok?(rc) ? @more_parts_array.at(0) : false
|
173
174
|
end
|
174
175
|
|
175
176
|
# Binds the socket to an +address+.
|
@@ -213,20 +214,22 @@ module ZMQ
|
|
213
214
|
private
|
214
215
|
|
215
216
|
def __getsockopt__ name, array
|
216
|
-
|
217
|
+
# a small optimization so we only have to determine the option
|
218
|
+
# type a single time; gives approx 5% speedup to do it this way.
|
219
|
+
option_type = @option_lookup[name]
|
220
|
+
|
221
|
+
value, length = sockopt_buffers option_type
|
217
222
|
|
218
223
|
rc = LibZMQ.zmq_getsockopt @socket, name, value, length
|
219
224
|
|
220
225
|
if Util.resultcode_ok?(rc)
|
221
|
-
|
222
|
-
value.read_int
|
223
|
-
elsif long_long_option?(name)
|
226
|
+
array[0] = if 1 == option_type
|
224
227
|
value.read_long_long
|
225
|
-
elsif
|
228
|
+
elsif 0 == option_type
|
229
|
+
value.read_int
|
230
|
+
elsif 2 == option_type
|
226
231
|
value.read_string(length.read_int)
|
227
232
|
end
|
228
|
-
|
229
|
-
array << result
|
230
233
|
end
|
231
234
|
|
232
235
|
rc
|
@@ -235,28 +238,28 @@ module ZMQ
|
|
235
238
|
# Calls to ZMQ.getsockopt require us to pass in some pointers. We can cache and save those buffers
|
236
239
|
# for subsequent calls. This is a big perf win for calling RCVMORE which happens quite often.
|
237
240
|
# Cannot save the buffer for the IDENTITY.
|
238
|
-
def sockopt_buffers
|
239
|
-
if
|
241
|
+
def sockopt_buffers option_type
|
242
|
+
if 1 == option_type
|
240
243
|
# int64_t or uint64_t
|
241
|
-
unless @
|
244
|
+
unless @longlong_cache
|
242
245
|
length = FFI::MemoryPointer.new :size_t
|
243
246
|
length.write_int 8
|
244
|
-
@
|
247
|
+
@longlong_cache = [FFI::MemoryPointer.new(:int64), length]
|
245
248
|
end
|
246
249
|
|
247
|
-
@
|
250
|
+
@longlong_cache
|
248
251
|
|
249
|
-
elsif
|
252
|
+
elsif 0 == option_type
|
250
253
|
# int, 0mq assumes int is 4-bytes
|
251
|
-
unless @
|
254
|
+
unless @int_cache
|
252
255
|
length = FFI::MemoryPointer.new :size_t
|
253
256
|
length.write_int 4
|
254
|
-
@
|
257
|
+
@int_cache = [FFI::MemoryPointer.new(:int32), length]
|
255
258
|
end
|
256
259
|
|
257
|
-
@
|
260
|
+
@int_cache
|
258
261
|
|
259
|
-
elsif
|
262
|
+
elsif 2 == option_type
|
260
263
|
length = FFI::MemoryPointer.new :size_t
|
261
264
|
# could be a string of up to 255 bytes
|
262
265
|
length.write_int 255
|
@@ -264,50 +267,30 @@ module ZMQ
|
|
264
267
|
|
265
268
|
else
|
266
269
|
# uh oh, someone passed in an unknown option; use a slop buffer
|
267
|
-
unless @
|
270
|
+
unless @int_cache
|
268
271
|
length = FFI::MemoryPointer.new :size_t
|
269
272
|
length.write_int 4
|
270
|
-
@
|
273
|
+
@int_cache = [FFI::MemoryPointer.new(:int32), length]
|
271
274
|
end
|
272
275
|
|
273
|
-
@
|
276
|
+
@int_cache
|
274
277
|
end
|
275
278
|
end
|
276
|
-
|
277
|
-
def
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
TYPE == name ||
|
287
|
-
BACKLOG == name
|
288
|
-
end
|
289
|
-
|
290
|
-
def string_option? name
|
291
|
-
SUBSCRIBE == name ||
|
292
|
-
UNSUBSCRIBE == name
|
293
|
-
end
|
294
|
-
|
295
|
-
def long_long_option? name
|
296
|
-
RCVMORE == name ||
|
297
|
-
AFFINITY == name
|
298
|
-
end
|
299
|
-
|
300
|
-
def unsupported_setsock_option? name
|
301
|
-
RCVMORE == name
|
302
|
-
end
|
303
|
-
|
304
|
-
def unsupported_getsock_option? name
|
305
|
-
UNSUBSCRIBE == name ||
|
306
|
-
SUBSCRIBE == name
|
279
|
+
|
280
|
+
def populate_option_lookup
|
281
|
+
# integer options
|
282
|
+
[EVENTS, LINGER, RECONNECT_IVL, FD, TYPE, BACKLOG].each { |option| @option_lookup[option] = 0 }
|
283
|
+
|
284
|
+
# long long options
|
285
|
+
[RCVMORE, AFFINITY].each { |option| @option_lookup[option] = 1 }
|
286
|
+
|
287
|
+
# string options
|
288
|
+
[SUBSCRIBE, UNSUBSCRIBE].each { |option| @option_lookup[option] = 2 }
|
307
289
|
end
|
308
290
|
|
309
291
|
def release_cache
|
310
|
-
@
|
292
|
+
@longlong_cache = nil
|
293
|
+
@int_cache = nil
|
311
294
|
end
|
312
295
|
end # module CommonSocketBehavior
|
313
296
|
|
@@ -330,11 +313,14 @@ module ZMQ
|
|
330
313
|
|
331
314
|
|
332
315
|
private
|
333
|
-
|
334
|
-
def
|
335
|
-
super
|
336
|
-
|
316
|
+
|
317
|
+
def populate_option_lookup
|
318
|
+
super()
|
319
|
+
|
320
|
+
# string options
|
321
|
+
[IDENTITY].each { |option| @option_lookup[option] = 2 }
|
337
322
|
end
|
323
|
+
|
338
324
|
end # module IdentitySupport
|
339
325
|
|
340
326
|
|
@@ -658,23 +644,16 @@ module ZMQ
|
|
658
644
|
def noblock? flags
|
659
645
|
(NOBLOCK & flags) == NOBLOCK
|
660
646
|
end
|
647
|
+
|
648
|
+
def populate_option_lookup
|
649
|
+
super()
|
650
|
+
|
651
|
+
# integer options
|
652
|
+
[RECONNECT_IVL_MAX].each { |option| @option_lookup[option] = 0 }
|
661
653
|
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
end
|
666
|
-
|
667
|
-
def long_long_option? name
|
668
|
-
super ||
|
669
|
-
HWM == name ||
|
670
|
-
SWAP == name ||
|
671
|
-
RATE == name ||
|
672
|
-
RECOVERY_IVL == name ||
|
673
|
-
RECOVERY_IVL_MSEC == name ||
|
674
|
-
MCAST_LOOP == name ||
|
675
|
-
SNDBUF == name ||
|
676
|
-
RCVBUF == name
|
677
|
-
end
|
654
|
+
# long long options
|
655
|
+
[HWM, SWAP, RATE, RECOVERY_IVL, RECOVERY_IVL_MSEC, MCAST_LOOP, SNDBUF, RCVBUF].each { |option| @option_lookup[option] = 1 }
|
656
|
+
end
|
678
657
|
|
679
658
|
# these finalizer-related methods cannot live in the CommonSocketBehavior
|
680
659
|
# module; they *must* be in the class definition directly
|
@@ -986,7 +965,7 @@ module ZMQ
|
|
986
965
|
alias :noblock? :dontwait?
|
987
966
|
|
988
967
|
def int_option? name
|
989
|
-
super ||
|
968
|
+
super(name) ||
|
990
969
|
RECONNECT_IVL_MAX == name ||
|
991
970
|
RCVHWM == name ||
|
992
971
|
SNDHWM == name ||
|
@@ -995,6 +974,13 @@ module ZMQ
|
|
995
974
|
SNDBUF == name ||
|
996
975
|
RCVBUF == name
|
997
976
|
end
|
977
|
+
|
978
|
+
def populate_option_lookup
|
979
|
+
super()
|
980
|
+
|
981
|
+
# integer options
|
982
|
+
[RECONNECT_IVL_MAX, RCVHWM, SNDHWM, RATE, RECOVERY_IVL, SNDBUF, RCVBUF].each { |option| @option_lookup[option] = 0 }
|
983
|
+
end
|
998
984
|
|
999
985
|
# these finalizer-related methods cannot live in the CommonSocketBehavior
|
1000
986
|
# module; they *must* be in the class definition directly
|
data/lib/ffi-rzmq/version.rb
CHANGED
data/spec/socket_spec.rb
CHANGED
@@ -366,12 +366,22 @@ module ZMQ
|
|
366
366
|
array[0].should == value
|
367
367
|
end
|
368
368
|
|
369
|
-
|
370
|
-
value
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
369
|
+
if ZMQ::SUB == socket_type || ZMQ::XSUB == socket_type
|
370
|
+
it "should default to a value of 0" do
|
371
|
+
value = 0
|
372
|
+
array = []
|
373
|
+
rc = socket.getsockopt(ZMQ::LINGER, array)
|
374
|
+
rc.should == 0
|
375
|
+
array[0].should == value
|
376
|
+
end
|
377
|
+
else
|
378
|
+
it "should default to a value of -1" do
|
379
|
+
value = -1
|
380
|
+
array = []
|
381
|
+
rc = socket.getsockopt(ZMQ::LINGER, array)
|
382
|
+
rc.should == 0
|
383
|
+
array[0].should == value
|
384
|
+
end
|
375
385
|
end
|
376
386
|
end # context using option ZMQ::LINGER
|
377
387
|
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: ffi-rzmq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.9.
|
5
|
+
version: 0.9.3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Chuck Remes
|
@@ -10,8 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
14
|
-
default_executable:
|
13
|
+
date: 2011-12-20 00:00:00 Z
|
15
14
|
dependencies:
|
16
15
|
- !ruby/object:Gem::Dependency
|
17
16
|
name: ffi
|
@@ -21,7 +20,7 @@ dependencies:
|
|
21
20
|
requirements:
|
22
21
|
- - ">="
|
23
22
|
- !ruby/object:Gem::Version
|
24
|
-
version:
|
23
|
+
version: "0"
|
25
24
|
type: :runtime
|
26
25
|
version_requirements: *id001
|
27
26
|
- !ruby/object:Gem::Dependency
|
@@ -115,7 +114,6 @@ files:
|
|
115
114
|
- spec/reqrep_spec.rb
|
116
115
|
- spec/socket_spec.rb
|
117
116
|
- spec/spec_helper.rb
|
118
|
-
has_rdoc: true
|
119
117
|
homepage: http://github.com/chuckremes/ffi-rzmq
|
120
118
|
licenses: []
|
121
119
|
|
@@ -139,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
137
|
requirements: []
|
140
138
|
|
141
139
|
rubyforge_project: ffi-rzmq
|
142
|
-
rubygems_version: 1.
|
140
|
+
rubygems_version: 1.8.9
|
143
141
|
signing_key:
|
144
142
|
specification_version: 3
|
145
143
|
summary: This gem wraps the ZeroMQ (0mq) networking library using Ruby FFI (foreign function interface).
|