couchbase-jruby-client 0.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.ruby-version +1 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +203 -0
  6. data/README.md +347 -0
  7. data/Rakefile +10 -0
  8. data/couchbase-jruby-client.gemspec +30 -0
  9. data/lib/couchbase/async/callback.rb +19 -0
  10. data/lib/couchbase/async/queue.rb +26 -0
  11. data/lib/couchbase/async.rb +139 -0
  12. data/lib/couchbase/bucket.rb +663 -0
  13. data/lib/couchbase/cluster.rb +105 -0
  14. data/lib/couchbase/constants.rb +12 -0
  15. data/lib/couchbase/error.rb +28 -0
  16. data/lib/couchbase/jruby/couchbase_client.rb +22 -0
  17. data/lib/couchbase/jruby/future.rb +8 -0
  18. data/lib/couchbase/operations/arithmetic.rb +301 -0
  19. data/lib/couchbase/operations/delete.rb +104 -0
  20. data/lib/couchbase/operations/get.rb +298 -0
  21. data/lib/couchbase/operations/stats.rb +16 -0
  22. data/lib/couchbase/operations/store.rb +468 -0
  23. data/lib/couchbase/operations/touch.rb +123 -0
  24. data/lib/couchbase/operations/utils.rb +49 -0
  25. data/lib/couchbase/operations.rb +23 -0
  26. data/lib/couchbase/result.rb +43 -0
  27. data/lib/couchbase/transcoder.rb +83 -0
  28. data/lib/couchbase/utils.rb +62 -0
  29. data/lib/couchbase/version.rb +3 -0
  30. data/lib/couchbase/view.rb +506 -0
  31. data/lib/couchbase/view_row.rb +272 -0
  32. data/lib/couchbase.rb +177 -0
  33. data/lib/jars/commons-codec-1.5.jar +0 -0
  34. data/lib/jars/couchbase-client-1.2.0-javadoc.jar +0 -0
  35. data/lib/jars/couchbase-client-1.2.0-sources.jar +0 -0
  36. data/lib/jars/couchbase-client-1.2.0.jar +0 -0
  37. data/lib/jars/httpcore-4.1.1.jar +0 -0
  38. data/lib/jars/httpcore-nio-4.1.1.jar +0 -0
  39. data/lib/jars/jettison-1.1.jar +0 -0
  40. data/lib/jars/netty-3.5.5.Final.jar +0 -0
  41. data/lib/jars/spymemcached-2.10.0-javadoc.jar +0 -0
  42. data/lib/jars/spymemcached-2.10.0-sources.jar +0 -0
  43. data/lib/jars/spymemcached-2.10.0.jar +0 -0
  44. data/test/profile/.gitignore +1 -0
  45. data/test/profile/Gemfile +6 -0
  46. data/test/profile/benchmark.rb +195 -0
  47. data/test/setup.rb +201 -0
  48. data/test/test_arithmetic.rb +177 -0
  49. data/test/test_async.rb +324 -0
  50. data/test/test_bucket.rb +213 -0
  51. data/test/test_cas.rb +78 -0
  52. data/test/test_couchbase.rb +29 -0
  53. data/test/test_couchbase_rails_cache_store.rb +341 -0
  54. data/test/test_delete.rb +125 -0
  55. data/test/test_errors.rb +82 -0
  56. data/test/test_format.rb +161 -0
  57. data/test/test_get.rb +417 -0
  58. data/test/test_stats.rb +57 -0
  59. data/test/test_store.rb +216 -0
  60. data/test/test_timer.rb +42 -0
  61. data/test/test_touch.rb +97 -0
  62. data/test/test_unlock.rb +119 -0
  63. data/test/test_utils.rb +58 -0
  64. data/test/test_version.rb +52 -0
  65. metadata +226 -0
@@ -0,0 +1,272 @@
1
+ # Author:: Couchbase <info@couchbase.com>
2
+ # Copyright:: 2011-2012 Couchbase, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ module Couchbase
19
+ # This class encapsulates structured JSON document
20
+ #
21
+ # @since 1.2.0
22
+ #
23
+ # It behaves like Hash for document included into row, and has access methods to row data as well.
24
+ #
25
+ # @see http://www.couchbase.com/docs/couchbase-manual-2.0/couchbase-views-datastore.html
26
+ class ViewRow
27
+ include Constants
28
+
29
+ # Undefine as much methods as we can to free names for views
30
+ instance_methods.each do |m|
31
+ undef_method(m) if m.to_s !~ /(?:^__|^nil\?$|^send$|^object_id$|^class$|)/
32
+ end
33
+
34
+ # The hash built from JSON document.
35
+ #
36
+ # @since 1.2.0
37
+ #
38
+ # This is complete response from the Couchbase
39
+ #
40
+ # @return [Hash]
41
+ attr_accessor :data
42
+
43
+ # The key which was emitted by map function
44
+ #
45
+ # @since 1.2.0
46
+ #
47
+ # @see http://www.couchbase.com/docs/couchbase-manual-2.0/couchbase-views-writing-map.html
48
+ #
49
+ # Usually it is String (the object +_id+) but it could be also any
50
+ # compount JSON value.
51
+ #
52
+ # @return [Object]
53
+ attr_accessor :key
54
+
55
+ # The value which was emitted by map function
56
+ #
57
+ # @since 1.2.0
58
+ #
59
+ # @see http://www.couchbase.com/docs/couchbase-manual-2.0/couchbase-views-writing-map.html
60
+ #
61
+ # @return [Object]
62
+ attr_accessor :value
63
+
64
+ # The document hash.
65
+ #
66
+ # @since 1.2.0
67
+ #
68
+ # It usually available when view executed with +:include_doc+ argument.
69
+ #
70
+ # @return [Hash]
71
+ attr_accessor :doc
72
+
73
+ # The identificator of the document
74
+ #
75
+ # @since 1.2.0
76
+ #
77
+ # @return [String]
78
+ attr_accessor :id
79
+
80
+ # The meta data linked to the document
81
+ #
82
+ # @since 1.2.0
83
+ #
84
+ # @return [Hash]
85
+ attr_accessor :meta
86
+
87
+ # Initialize the document instance
88
+ #
89
+ # @since 1.2.0
90
+ #
91
+ # It takes reference to the bucket, data hash.
92
+ #
93
+ # @param [Couchbase::Bucket] bucket the reference to connection
94
+ # @param [Hash] data the data hash, which was built from JSON document
95
+ # representation
96
+ def initialize(bucket, data)
97
+ @bucket = bucket
98
+ @data = data
99
+ @key = data[S_KEY]
100
+ @value = data[S_VALUE]
101
+ if data[S_DOC]
102
+ @meta = data[S_DOC][S_META]
103
+ @doc = data[S_DOC][S_VALUE]
104
+ end
105
+ @id = data[S_ID] || @meta && @meta[S_ID]
106
+ @last = data.delete(S_IS_LAST) || false
107
+ end
108
+
109
+ # Wraps data hash into ViewRow instance
110
+ #
111
+ # @since 1.2.0
112
+ #
113
+ # @see ViewRow#initialize
114
+ #
115
+ # @param [Couchbase::Bucket] bucket the reference to connection
116
+ # @param [Hash] data the data hash, which was built from JSON document
117
+ # representation
118
+ #
119
+ # @return [ViewRow]
120
+ def self.wrap(bucket, data)
121
+ self.new(bucket, data)
122
+ end
123
+
124
+ # Get attribute of the document
125
+ #
126
+ # @since 1.2.0
127
+ #
128
+ # Fetches attribute from underlying document hash
129
+ #
130
+ # @param [String] key the attribute name
131
+ #
132
+ # @return [Object] property value or nil
133
+ def [](key)
134
+ @doc[key]
135
+ end
136
+
137
+ # Check attribute existence
138
+ #
139
+ # @since 1.2.0
140
+ #
141
+ # @param [String] key the attribute name
142
+ #
143
+ # @return [true, false] +true+ if the given attribute is present in in
144
+ # the document.
145
+ def has_key?(key)
146
+ @doc.has_key?(key)
147
+ end
148
+
149
+ # Set document attribute
150
+ #
151
+ # @since 1.2.0
152
+ #
153
+ # Set or update the attribute in the document hash
154
+ #
155
+ # @param [String] key the attribute name
156
+ # @param [Object] value the attribute value
157
+ #
158
+ # @return [Object] the value
159
+ def []=(key, value)
160
+ @doc[key] = value
161
+ end
162
+
163
+ # Signals if this row is last in a stream
164
+ #
165
+ # @since 1.2.1
166
+ #
167
+ # @return [true, false] +true+ if this row is last in a stream
168
+ def last?
169
+ @last
170
+ end
171
+
172
+ def inspect
173
+ desc = "#<#{self.class.name}:#{self.object_id}"
174
+ [:@id, :@key, :@value, :@doc, :@meta].each do |iv|
175
+ desc << " #{iv}=#{instance_variable_get(iv).inspect}"
176
+ end
177
+ desc << ">"
178
+ desc
179
+ end
180
+ end
181
+
182
+ # This class encapsulates information about design docs
183
+ #
184
+ # @since 1.2.1
185
+ #
186
+ # It is subclass of ViewRow, but also gives access to view creation through method_missing
187
+ #
188
+ # @see http://www.couchbase.com/docs/couchbase-manual-2.0/couchbase-views-datastore.html
189
+ class DesignDoc < ViewRow
190
+ # It isn't allowed to change design document ID after
191
+ # initialization
192
+ undef id=
193
+
194
+ # Initialize the design doc instance
195
+ #
196
+ # @since 1.2.1
197
+ #
198
+ # It takes reference to the bucket, data hash. It will define view
199
+ # methods if the data object looks like design document.
200
+ #
201
+ # @param [Couchbase::Bucket] bucket the reference to connection
202
+ # @param [Hash] data the data hash, which was built from JSON document
203
+ # representation
204
+ def initialize(bucket, data)
205
+ super
206
+ @all_views = {}
207
+ @views = @doc.has_key?('views') ? @doc['views'].keys : []
208
+ @spatial = @doc.has_key?('spatial') ? @doc['spatial'].keys : []
209
+ @views.each{|name| @all_views[name] = "#{@id}/_view/#{name}"}
210
+ @spatial.each{|name| @all_views[name] = "#{@id}/_spatial/#{name}"}
211
+ end
212
+
213
+ def method_missing(meth, *args)
214
+ if path = @all_views[meth.to_s]
215
+ View.new(@bucket, path, *args)
216
+ else
217
+ super
218
+ end
219
+ end
220
+
221
+ def respond_to?(meth, *args)
222
+ if @all_views[meth.to_s]
223
+ true
224
+ else
225
+ super
226
+ end
227
+ end
228
+
229
+ def method(meth, *args)
230
+ if path = @all_views[meth.to_s]
231
+ lambda{|*p| View.new(@bucket, path, *p)}
232
+ else
233
+ super
234
+ end
235
+ end
236
+
237
+ # The list of views defined or empty array
238
+ #
239
+ # @since 1.2.1
240
+ #
241
+ # @return [Array<View>]
242
+ attr_accessor :views
243
+
244
+ # The list of spatial views defined or empty array
245
+ #
246
+ # @since 1.2.1
247
+ #
248
+ # @return [Array<View>]
249
+ attr_accessor :spatial
250
+
251
+ # Check if the document has views defines
252
+ #
253
+ # @since 1.2.1
254
+ #
255
+ # @see DesignDoc#views
256
+ #
257
+ # @return [true, false] +true+ if the document have views
258
+ def has_views?
259
+ !@views.empty?
260
+ end
261
+
262
+ def inspect
263
+ desc = "#<#{self.class.name}:#{self.object_id}"
264
+ [:@id, :@views, :@spatial].each do |iv|
265
+ desc << " #{iv}=#{instance_variable_get(iv).inspect}"
266
+ end
267
+ desc << ">"
268
+ desc
269
+ end
270
+
271
+ end
272
+ end
data/lib/couchbase.rb ADDED
@@ -0,0 +1,177 @@
1
+
2
+ unless RUBY_PLATFORM =~ /java/
3
+ error "This gem is only compatible with a java-based ruby environment like JRuby."
4
+ exit 255
5
+ end
6
+
7
+ require 'java'
8
+ require 'jars/commons-codec-1.5.jar'
9
+ require 'jars/couchbase-client-1.2.0.jar'
10
+ require 'jars/jettison-1.1.jar'
11
+ require 'jars/httpcore-4.1.1.jar'
12
+ require 'jars/netty-3.5.5.Final.jar'
13
+ require 'jars/spymemcached-2.10.0.jar'
14
+ require 'jars/httpcore-nio-4.1.1.jar'
15
+ require 'couchbase/version'
16
+ require 'uri'
17
+ require 'atomic'
18
+ require 'couchbase/transcoder'
19
+ require 'couchbase/async'
20
+ require 'couchbase/operations'
21
+ require 'couchbase/error'
22
+ require 'couchbase/constants'
23
+ require 'couchbase/utils'
24
+ require 'couchbase/bucket'
25
+ require 'couchbase/view_row'
26
+ require 'couchbase/view'
27
+ require 'couchbase/result'
28
+ require 'couchbase/cluster'
29
+
30
+ include Java
31
+
32
+ import Java::com.couchbase.client.CouchbaseClient;
33
+
34
+ at_exit do
35
+ Couchbase.disconnect
36
+ end
37
+
38
+ # Couchbase jruby client
39
+ module Couchbase
40
+
41
+ @@bucket = Atomic.new(nil)
42
+
43
+ class << self
44
+
45
+ # The method +connect+ initializes new Bucket instance with all arguments passed.
46
+ #
47
+ # @since 1.0.0
48
+ #
49
+ # @see Bucket#initialize
50
+ #
51
+ # @example Use default values for all options
52
+ # Couchbase.connect
53
+ #
54
+ # @example Establish connection with couchbase default pool and default bucket
55
+ # Couchbase.connect("http://localhost:8091/pools/default")
56
+ #
57
+ # @example Select custom bucket
58
+ # Couchbase.connect("http://localhost:8091/pools/default", :bucket => 'blog')
59
+ #
60
+ # @example Specify bucket credentials
61
+ # Couchbase.connect("http://localhost:8091/pools/default", :bucket => 'blog', :username => 'bucket', :password => 'secret')
62
+ #
63
+ # @example Use URL notation
64
+ # Couchbase.connect("http://bucket:secret@localhost:8091/pools/default/buckets/blog")
65
+ #
66
+ # @return [Bucket] connection instance
67
+ def connect(*options)
68
+ disconnect
69
+ @@bucket.update { |bucket| bucket ||= Bucket.new(*(options.flatten)) }
70
+ @@bucket.value
71
+ end
72
+ alias :new :connect
73
+
74
+ # Default connection options
75
+ #
76
+ # @since 1.1.0
77
+ #
78
+ # @example Using {Couchbase#connection_options} to change the bucket
79
+ # Couchbase.connection_options = {:bucket => 'blog'}
80
+ # Couchbase.bucket.name #=> "blog"
81
+ #
82
+ # @return [Hash, String]
83
+ attr_accessor :connection_options
84
+
85
+ # The connection instance for current thread
86
+ #
87
+ # @since 1.1.0
88
+ #
89
+ # @see Couchbase.connection_options
90
+ #
91
+ # @example
92
+ # Couchbase.bucket.set("foo", "bar")
93
+ #
94
+ # @return [Bucket]
95
+ def bucket
96
+ if !connected?
97
+ connect(connection_options)
98
+ end
99
+ @@bucket.value
100
+ end
101
+
102
+ # Set a connection instance for current thread
103
+ #
104
+ # @since 1.1.0
105
+ #
106
+ # @return [Bucket]
107
+ def bucket=(connection)
108
+ @@bucket.update { |bucket| bucket = connection }
109
+ end
110
+
111
+ def connected?
112
+ !!@@bucket.value
113
+ end
114
+
115
+ def disconnect
116
+ @@bucket.value.disconnect if connected?
117
+ @@bucket = Atomic.new(nil)
118
+ end
119
+ end
120
+ end
121
+
122
+ __END__
123
+
124
+ def self.connect(*options)
125
+ disconnect
126
+ Bucket.new(*(options.flatten))
127
+ end
128
+
129
+ def self.new(*options)
130
+ connect(options)
131
+ end
132
+
133
+ # Default connection options
134
+ #
135
+ # @since 1.1.0
136
+ #
137
+ # @example Using {Couchbase#connection_options} to change the bucket
138
+ # Couchbase.connection_options = {:bucket => 'blog'}
139
+ # Couchbase.bucket.name #=> "blog"
140
+ #
141
+ # @return [Hash, String]
142
+ attr_accessor :connection_options
143
+
144
+ # The connection instance for current thread
145
+ #
146
+ # @since 1.1.0
147
+ #
148
+ # @see Couchbase.connection_options
149
+ #
150
+ # @example
151
+ # Couchbase.bucket.set("foo", "bar")
152
+ #
153
+ # @return [Bucket]
154
+ def self.bucket
155
+ @bucket ||= connect(connection_options)
156
+ end
157
+
158
+ # Set a connection instance for current thread
159
+ #
160
+ # @since 1.1.0
161
+ #
162
+ # @return [Bucket]
163
+ def self.bucket=(connection)
164
+ @bucket = connection
165
+ end
166
+
167
+ def self.connected?
168
+ !!@bucket
169
+ end
170
+
171
+ def self.disconnect
172
+ bucket.disconnect if connected?
173
+ @bucket = nil
174
+ end
175
+
176
+ end
177
+
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1 @@
1
+ benchmark*.log
@@ -0,0 +1,6 @@
1
+ source :rubygems
2
+
3
+ gem "memcached", "~> 1.3.6"
4
+ gem "kgio", "~> 2.7.2"
5
+ gem "dalli", "~> 1.1.4"
6
+ gem "yajl-ruby", "~> 1.1.0"
@@ -0,0 +1,195 @@
1
+ # Useful environment variables:
2
+ #
3
+ # LOOPS (50000)
4
+ # how many time run exercises
5
+ #
6
+ # HOST (127.0.0.1)
7
+ # the host where cluster is running. benchmark will use default ports to
8
+ # connect to it (11211 and 8091)
9
+ #
10
+ # STACK_DEPTH (0)
11
+ # the depth of stack where exercises are run. the benchmark will
12
+ # recursively go to given depth before run
13
+ #
14
+ # TEST ('')
15
+ # use to run specific test (possible values are: set, get, get-multi,
16
+ # append, prepend, delete, get-missing, append-missing, prepend-missing,
17
+ # set-large, get-large)
18
+ #
19
+ # CLIENT ('')
20
+ # use to run with specific client (possible values are: couchbase, dalli,
21
+ # memcached, memcached:buffer)
22
+ #
23
+ # DEBUG ('')
24
+ # show exceptions
25
+ #
26
+
27
+ require "rubygems"
28
+ require "bundler/setup"
29
+
30
+ require 'benchmark'
31
+
32
+ $LOAD_PATH << File.join(File.dirname(__FILE__), "..", "..", "lib")
33
+ require 'couchbase'
34
+ require 'memcached'
35
+ require 'dalli'
36
+
37
+ puts `uname -a`
38
+ puts File.readlines('/proc/cpuinfo').sort.uniq.grep(/model name|cpu cores/) rescue nil
39
+ puts RUBY_DESCRIPTION
40
+
41
+ class Bench
42
+
43
+ def initialize(loops = nil, stack_depth = nil)
44
+ @loops = (loops || 50000).to_i
45
+ @stack_depth = (stack_depth || 0).to_i
46
+
47
+ puts "PID is #{Process.pid}"
48
+ puts "Loops is #{@loops}"
49
+ puts "Stack depth is #{@stack_depth}"
50
+
51
+ @m_value = Marshal.dump(
52
+ @small_value = ["testing"])
53
+ @m_large_value = Marshal.dump(
54
+ @large_value = [{"test" => "1", "test2" => "2", Object.new => "3", 4 => 4, "test5" => 2**65}] * 2048)
55
+
56
+ puts "Small value size is: #{@m_value.size} bytes"
57
+ puts "Large value size is: #{@m_large_value.size} bytes"
58
+
59
+ @keys = [
60
+ @k1 = "Short",
61
+ @k2 = "Sym1-2-3::45" * 8,
62
+ @k3 = "Long" * 40,
63
+ @k4 = "Medium" * 8,
64
+ @k5 = "Medium2" * 8,
65
+ @k6 = "Long3" * 40]
66
+
67
+ reset_clients
68
+
69
+ Benchmark.bm(36) do |x|
70
+ @benchmark = x
71
+ end
72
+ end
73
+
74
+ def run(level = @stack_depth)
75
+ level > 0 ? run(level - 1) : run_without_recursion
76
+ end
77
+
78
+ private
79
+
80
+ def reset_clients
81
+ host = ENV['HOST'] || '127.0.0.1'
82
+ @clients = {
83
+ "dalli" => lambda { Dalli::Client.new("#{host}:11211", :marshal => true, :threadsafe => false) },
84
+ "memcached" => lambda { Memcached::Rails.new("#{host}:11211", :no_block => false, :buffer_requests => false, :binary_protocol => true) },
85
+ "memcached:buffer" => lambda { Memcached::Rails.new("#{host}:11211", :no_block => true, :buffer_requests => true, :binary_protocol => true) },
86
+ "couchbase" => lambda { Couchbase.new("http://#{host}:8091/pools/default/buckets/default", :default_format => :marshal) }
87
+ }
88
+ end
89
+
90
+ def benchmark_clients(test_name, populate_keys = true)
91
+ return if ENV["TEST"] and !test_name.include?(ENV["TEST"])
92
+
93
+ @clients.keys.each do |client_name|
94
+ next if ENV["CLIENT"] and !client_name.include?(ENV["CLIENT"])
95
+
96
+ kid = fork do
97
+ client = @clients[client_name].call
98
+ begin
99
+ if populate_keys
100
+ client.set @k1, @m_value
101
+ client.set @k2, @m_value
102
+ client.set @k3, @m_value
103
+ else
104
+ client.delete @k1
105
+ client.delete @k2
106
+ client.delete @k3
107
+ end
108
+
109
+ GC.disable
110
+ @benchmark.report("#{test_name}: #{client_name}") { @loops.times { yield client } }
111
+ STDOUT.flush
112
+ rescue Exception => e
113
+ puts "#{test_name}: #{client_name} => #{e.inspect}" if ENV["DEBUG"]
114
+ end
115
+ exit
116
+ end
117
+ Signal.trap("INT") { Process.kill("KILL", kid); exit }
118
+ Process.wait(kid)
119
+ end
120
+ puts
121
+ end
122
+
123
+ def run_without_recursion
124
+ benchmark_clients("set") do |c|
125
+ c.set @k1, @m_value
126
+ c.set @k2, @m_value
127
+ c.set @k3, @m_value
128
+ end
129
+
130
+ benchmark_clients("get") do |c|
131
+ c.get @k1
132
+ c.get @k2
133
+ c.get @k3
134
+ end
135
+
136
+ benchmark_clients("get_multi") do |c|
137
+ if c.respond_to?(:get_multi)
138
+ c.get_multi @keys
139
+ else
140
+ c.get @keys
141
+ end
142
+ end
143
+
144
+ benchmark_clients("append") do |c|
145
+ c.append @k1, @m_value
146
+ c.append @k2, @m_value
147
+ c.append @k3, @m_value
148
+ end
149
+
150
+ benchmark_clients("prepend") do |c|
151
+ c.prepend @k1, @m_value
152
+ c.prepend @k2, @m_value
153
+ c.prepend @k3, @m_value
154
+ end
155
+
156
+ benchmark_clients("delete") do |c|
157
+ c.delete @k1
158
+ c.delete @k2
159
+ c.delete @k3
160
+ end
161
+
162
+ benchmark_clients("get_missing", false) do |c|
163
+ c.get @k1 rescue nil
164
+ c.get @k2 rescue nil
165
+ c.get @k3 rescue nil
166
+ end
167
+
168
+ benchmark_clients("append_missing", false) do |c|
169
+ c.append @k1, @m_value rescue nil
170
+ c.append @k2, @m_value rescue nil
171
+ c.append @k3, @m_value rescue nil
172
+ end
173
+
174
+ benchmark_clients("prepend_missing", false) do |c|
175
+ c.prepend @k1, @m_value rescue nil
176
+ c.prepend @k2, @m_value rescue nil
177
+ c.prepend @k3, @m_value rescue nil
178
+ end
179
+
180
+ benchmark_clients("set_large") do |c|
181
+ c.set @k1, @m_large_value
182
+ c.set @k2, @m_large_value
183
+ c.set @k3, @m_large_value
184
+ end
185
+
186
+ benchmark_clients("get_large") do |c|
187
+ c.get @k1
188
+ c.get @k2
189
+ c.get @k3
190
+ end
191
+
192
+ end
193
+ end
194
+
195
+ Bench.new(ENV["LOOPS"], ENV["STACK_DEPTH"]).run