binary42-remix-stash 0.9.4 → 0.9.5

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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.4
1
+ 0.9.5
@@ -1,7 +1,7 @@
1
1
  require 'benchmark'
2
2
  require File.dirname(__FILE__) + '/../harness'
3
3
 
4
- LARGE_NUMBER = 20_000
4
+ LARGE_NUMBER = 50_000
5
5
 
6
6
  Benchmark.bmbm do |b|
7
7
  b.report('get/set remix-stash') do
@@ -10,11 +10,17 @@ Benchmark.bmbm do |b|
10
10
  stash[:abcxyz123]
11
11
  }
12
12
  end
13
+ b.report('get/set remix-stash named') do
14
+ LARGE_NUMBER.times {|n|
15
+ stash(:stuff)[:abcxyz123] = n
16
+ stash(:stuff)[:abcxyz123]
17
+ }
18
+ end
13
19
  if defined?(CCache)
14
20
  b.report('get/set memcached') do
15
21
  LARGE_NUMBER.times {|n|
16
- CCache.set('abcxyz123', n)
17
- CCache.get('abcxyz123')
22
+ CCache.set('abcxyz123', n, 0 , true)
23
+ CCache.get('abcxyz123', true)
18
24
  }
19
25
  end
20
26
  end
@@ -21,8 +21,8 @@ Benchmark.bmbm do |b|
21
21
  if defined?(CCache)
22
22
  b.report('100k memcached') do
23
23
  LARGE_NUMBER.times {
24
- CCache.set(KEY, huge_value, 0, true)
25
- CCache.get(KEY, true)
24
+ CCache.set(KEY, huge_value, 0, false)
25
+ CCache.get(KEY, false)
26
26
  }
27
27
  end
28
28
  end
@@ -43,8 +43,8 @@ Benchmark.bmbm do |b|
43
43
  if defined?(CCache)
44
44
  b.report('20k memcached') do
45
45
  LARGE_NUMBER.times {
46
- CCache.set(KEY, large_value, 0, true)
47
- CCache.get(KEY, true)
46
+ CCache.set(KEY, large_value, 0, false)
47
+ CCache.get(KEY, false)
48
48
  }
49
49
  end
50
50
  end
@@ -65,8 +65,8 @@ Benchmark.bmbm do |b|
65
65
  if defined?(CCache)
66
66
  b.report('2k memcached') do
67
67
  LARGE_NUMBER.times {
68
- CCache.set(KEY, med_value, 0, true)
69
- CCache.get(KEY, true)
68
+ CCache.set(KEY, med_value, 0, false)
69
+ CCache.get(KEY, false)
70
70
  }
71
71
  end
72
72
  end
@@ -87,8 +87,8 @@ Benchmark.bmbm do |b|
87
87
  if defined?(CCache)
88
88
  b.report('100b memcached') do
89
89
  LARGE_NUMBER.times {
90
- CCache.set(KEY, small_value, 0, true)
91
- CCache.get(KEY, true)
90
+ CCache.set(KEY, small_value, 0, false)
91
+ CCache.get(KEY, false)
92
92
  }
93
93
  end
94
94
  end
@@ -109,8 +109,8 @@ Benchmark.bmbm do |b|
109
109
  if defined?(CCache)
110
110
  b.report('1b memcached') do
111
111
  LARGE_NUMBER.times {
112
- CCache.set(KEY, tiny_value, 0, true)
113
- CCache.get(KEY, true)
112
+ CCache.set(KEY, tiny_value, 0, false)
113
+ CCache.get(KEY, false)
114
114
  }
115
115
  end
116
116
  end
@@ -20,10 +20,10 @@ class Remix::Stash::Cluster
20
20
  begin
21
21
  io = host_to_io(*h)
22
22
  break yield(io)
23
- rescue Errno::EPIPE, Errno::ECONNRESET
23
+ rescue Errno::EPIPE, Errno::ECONNRESET, Remix::Stash::ProtocolError
24
24
  io.close
25
25
  retry
26
- rescue Remix::Stash::ProtocolError, Errno::EAGAIN
26
+ rescue Errno::EAGAIN, Errno::ECONNREFUSED
27
27
  next
28
28
  end
29
29
  end
@@ -43,38 +43,24 @@ class Remix::Stash::Cluster
43
43
  count.times do |try|
44
44
  begin
45
45
  io = host_to_io(*@hosts[(hash + try) % count])
46
- break yield(io)
47
- rescue Errno::EPIPE, Errno::ECONNRESET
46
+ return yield(io)
47
+ rescue Errno::EPIPE, Errno::ECONNRESET, Remix::Stash::ProtocolError
48
48
  io.close
49
49
  retry
50
- rescue Remix::Stash::ProtocolError, Errno::EAGAIN
50
+ rescue Errno::EAGAIN, Errno::ECONNREFUSED
51
51
  next
52
52
  end
53
- raise Remix::Stash::ClusterError,
54
- "Unable to find suitable host to communicate with for #{key.inspect} (MD5-32=#{hash})"
55
53
  end
54
+ raise Remix::Stash::ClusterError,
55
+ "Unable to find suitable host to communicate with for #{key.inspect} (MD5-32=#{hash})"
56
56
  end
57
57
 
58
58
  private
59
59
 
60
- if RUBY_PLATFORM =~ /java/
61
-
62
- def connect(host, port)
63
- socket = TCPSocket.new(host, port)
64
- set_timeout(socket)
65
- socket
66
- end
67
-
68
- else
69
-
70
- def connect(host, port)
71
- address = Socket.getaddrinfo(host, nil).first
72
- socket = Socket.new(Socket.const_get(address[0]), SOCK_STREAM, 0)
73
- set_timeout(socket)
74
- socket.connect(Socket.pack_sockaddr_in(port, address[3]))
75
- socket
76
- end
77
-
60
+ def connect(host, port)
61
+ socket = TCPSocket.new(host, port)
62
+ set_timeout(socket, 2)
63
+ socket
78
64
  end
79
65
 
80
66
  def host_to_io(key, host, port)
@@ -84,8 +70,8 @@ private
84
70
  host_to_io(key, host, port)
85
71
  end
86
72
 
87
- def set_timeout(socket)
88
- timeout = [2,0].pack('l_2') # 2 seconds
73
+ def set_timeout(socket, seconds)
74
+ timeout = [seconds, 0].pack('l_2') # 2 seconds
89
75
  socket.setsockopt(SOL_SOCKET, SO_SNDTIMEO, timeout)
90
76
  socket.setsockopt(SOL_SOCKET, SO_RCVTIMEO, timeout)
91
77
  end
@@ -86,11 +86,12 @@ module Remix::Stash::Protocol
86
86
  end
87
87
 
88
88
  GET_PACKET = HEADER_FORMAT + 'a*'
89
+ GET_BODY = 4..-1
89
90
  def get(io, key)
90
91
  header = [REQUEST, GET, key.size, 0, 0, 0, key.size, 0, 0, key].pack(GET_PACKET)
91
92
  io.write(header)
92
93
  resp = read_resp(io)
93
- resp[:status] == NO_ERROR ? parse_get(resp[:body])[:value] : nil
94
+ resp[:status] == NO_ERROR ? resp[:body][GET_BODY] : nil
94
95
  end
95
96
 
96
97
  INCR_PACKET = HEADER_FORMAT + 'NNQNa*'
@@ -114,25 +115,21 @@ module Remix::Stash::Protocol
114
115
 
115
116
  private
116
117
 
117
- def parse_get(body)
118
- extra, value = body.unpack('Na*')
119
- {:extra => extra, :value => value}
120
- end
121
-
118
+ COUNTER_SPLIT = 'NN'
122
119
  def parse_counter(body)
123
- a, b = body.unpack('NN')
120
+ a, b = body.unpack(COUNTER_SPLIT)
124
121
  b | (a << 32)
125
122
  end
126
123
 
124
+ RESP_HEADER = '@6nN'
127
125
  def read_resp(io)
128
- magic, opcode, key_length,
129
- extra, type, status,
130
- body_length, opaque, cas = *io.read(24).unpack(HEADER_FORMAT)
131
- resp = { :magic => magic, :opcode => opcode, :key_length => key_length,
132
- :extra => extra, :type => type, :status => status,
133
- :body_length => body_length, :opaque => opaque, :cas => cas }
134
- resp[:body] = io.read(body_length) if body_length > 0
135
- resp
126
+ header = io.read(24)
127
+ header or raise Remix::Stash::ProtocolError,
128
+ "No data in response header"
129
+ status, body_length = *header.unpack(RESP_HEADER)
130
+ body_length.zero? ?
131
+ {:status => status} :
132
+ {:status => status, :body => io.read(body_length)}
136
133
  end
137
134
 
138
135
  def split64(n)
data/lib/remix/stash.rb CHANGED
@@ -32,7 +32,7 @@ class Remix::Stash
32
32
  def initialize(name)
33
33
  @name = name
34
34
  @scope = nil
35
- @opts = name == :root ? {:coherency => :action, :ttl => 0} : {}
35
+ @opts = name == :root ? {:coherency => :action, :ttl => 0, :cluster => :default} : {}
36
36
  end
37
37
 
38
38
  def add(*keys)
@@ -79,11 +79,15 @@ class Remix::Stash
79
79
  cluster(opts).select(key) {|io| Protocol.decr(io, key, step)}
80
80
  end
81
81
 
82
- def default(opts = {})
83
- base = @opts.merge!(opts)
84
- if opts.has_key? :coherency
85
- [:dynamic, :action, :transaction].include?(opts[:coherency]) or raise ArgumentError,
86
- "Invalid coherency setting used (#{opts[:coherency].inspect})"
82
+ def default(opts = nil)
83
+ if opts
84
+ base = @opts.merge!(opts)
85
+ if opts.has_key? :coherency
86
+ [:dynamic, :action, :transaction].include?(opts[:coherency]) or raise ArgumentError,
87
+ "Invalid coherency setting used (#{opts[:coherency].inspect})"
88
+ end
89
+ else
90
+ base = @opts
87
91
  end
88
92
  root = @@instances[:root] || Stash.new(:root)
89
93
  self == root ?
@@ -178,19 +182,22 @@ class Remix::Stash
178
182
  private
179
183
 
180
184
  KEY_SEPARATOR = '/'
181
- def canonical_key(keys, opts = default_opts)
182
- "#{implicit_scope}#{keys.join(KEY_SEPARATOR)}#{vector(opts)}"
185
+ def canonical_key(keys, opts)
186
+ v = vector(opts)
187
+ if @scope
188
+ "#{implicit_scope}#{keys.join(KEY_SEPARATOR)}#{vector(opts)}"
189
+ elsif v
190
+ keys.join(KEY_SEPARATOR) << v
191
+ else
192
+ keys.join(KEY_SEPARATOR)
193
+ end
183
194
  end
184
195
 
185
196
  def cluster(opts = {})
186
- @@clusters[opts[:cluster] || :default]
197
+ @@clusters[opts[:cluster]]
187
198
  end
188
199
 
189
- def coherency
190
- default[:coherency]
191
- end
192
-
193
- def default_opts(params = {})
200
+ def default_opts(params)
194
201
  params.last.is_a?(Hash) ? default.merge(params.pop) : default
195
202
  end
196
203
 
@@ -198,14 +205,8 @@ private
198
205
  Marshal.dump(value)
199
206
  end
200
207
 
201
- EMPTY_SCOPE = ''
202
208
  def implicit_scope
203
- if @scope
204
- scope = @scope.call(self)
205
- scope ? "#{scope}/" : EMPTY_SCOPE
206
- else
207
- EMPTY_SCOPE
208
- end
209
+ @scope.call(self) if @scope
209
210
  end
210
211
 
211
212
  def load_value(data)
@@ -218,7 +219,7 @@ private
218
219
 
219
220
  def vector(opts)
220
221
  return if @name == :root
221
- return @vector if @vector && coherency != :dynamic
222
+ return @vector if @vector && opts[:coherency] != :dynamic
222
223
  vk = vector_key
223
224
  cluster(opts).select(vk) do |io|
224
225
  @vector = Protocol.get(io, vk)
data/remix-stash.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{remix-stash}
8
- s.version = "0.9.4"
8
+ s.version = "0.9.5"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Brian Mitchell"]
12
- s.date = %q{2009-09-17}
12
+ s.date = %q{2009-09-21}
13
13
  s.email = %q{binary42@gmail.com}
14
14
  s.extra_rdoc_files = [
15
15
  "LICENSE",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: binary42-remix-stash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.4
4
+ version: 0.9.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Mitchell
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-09-17 00:00:00 -07:00
12
+ date: 2009-09-21 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15