couchbase-jruby-client 0.1.0-java

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.
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