arunthampi-memcached 0.17.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,97 @@
1
+ class Memcached
2
+
3
+ (instance_methods - NilClass.instance_methods).each do |method_name|
4
+ eval("alias :'#{method_name}_orig' :'#{method_name}'")
5
+ end
6
+
7
+ # A legacy compatibility wrapper for the Memcached class. It has basic compatibility with the <b>memcache-client</b> API.
8
+ class Rails < ::Memcached
9
+
10
+ alias :servers= :set_servers
11
+
12
+ # See Memcached#new for details.
13
+ def initialize(*args)
14
+ opts = args.last.is_a?(Hash) ? args.pop : {}
15
+ servers = Array(
16
+ args.any? ? args.unshift : opts.delete(:servers)
17
+ ).flatten.compact
18
+
19
+ opts[:prefix_key] ||= opts[:namespace]
20
+ super(servers, opts)
21
+ end
22
+
23
+ # Wraps Memcached#get so that it doesn't raise. This has the side-effect of preventing you from
24
+ # storing <tt>nil</tt> values.
25
+ def get(key, raw=false)
26
+ super(key, !raw)
27
+ rescue NotFound
28
+ end
29
+
30
+ # Wraps Memcached#cas so that it doesn't raise. Doesn't set anything if no value is present.
31
+ def cas(key, ttl=@default_ttl, raw=false, &block)
32
+ super(key, ttl, !raw, &block)
33
+ rescue NotFound
34
+ end
35
+
36
+ alias :compare_and_swap :cas
37
+
38
+ # Wraps Memcached#get.
39
+ def get_multi(keys, raw=false)
40
+ get_orig(keys, !raw)
41
+ end
42
+
43
+ # Wraps Memcached#set.
44
+ def set(key, value, ttl=@default_ttl, raw=false)
45
+ super(key, value, ttl, !raw)
46
+ end
47
+
48
+ # Wraps Memcached#add so that it doesn't raise.
49
+ def add(key, value, ttl=@default_ttl, raw=false)
50
+ super(key, value, ttl, !raw)
51
+ true
52
+ rescue NotStored
53
+ false
54
+ end
55
+
56
+ # Wraps Memcached#delete so that it doesn't raise.
57
+ def delete(key)
58
+ super
59
+ rescue NotFound
60
+ end
61
+
62
+ # Wraps Memcached#incr so that it doesn't raise.
63
+ def incr(*args)
64
+ super
65
+ rescue NotFound
66
+ end
67
+
68
+ # Wraps Memcached#decr so that it doesn't raise.
69
+ def decr(*args)
70
+ super
71
+ rescue NotFound
72
+ end
73
+
74
+ # Wraps Memcached#append so that it doesn't raise.
75
+ def append(*args)
76
+ super
77
+ rescue NotStored
78
+ end
79
+
80
+ # Wraps Memcached#prepend so that it doesn't raise.
81
+ def prepend(*args)
82
+ super
83
+ rescue NotStored
84
+ end
85
+
86
+ # Namespace accessor.
87
+ def namespace
88
+ options[:prefix_key]
89
+ end
90
+
91
+ alias :flush_all :flush
92
+
93
+ alias :"[]" :get
94
+ alias :"[]=" :set
95
+
96
+ end
97
+ end
@@ -0,0 +1,210 @@
1
+
2
+ HERE = File.dirname(__FILE__)
3
+ $LOAD_PATH << "#{HERE}/../../lib/"
4
+ UNIX_SOCKET_NAME = File.join(ENV['TMPDIR']||'/tmp','memcached')
5
+
6
+ require 'memcached'
7
+ require 'benchmark'
8
+ require 'rubygems'
9
+ require 'ruby-debug' if ENV['DEBUG']
10
+ begin; require 'memory'; rescue LoadError; end
11
+
12
+ puts `uname -a`
13
+ puts "Ruby #{RUBY_VERSION}p#{RUBY_PATCHLEVEL}"
14
+
15
+ [ ["memcached", "memcached"],
16
+ ["binary42-remix-stash", "remix/stash"],
17
+ # ["astro-remcached", "remcached"], # Clobbers the "Memcached" constant
18
+ ["memcache-client", "memcache"]].each do |gem_name, requirement|
19
+ require requirement
20
+ gem gem_name
21
+ puts "Loaded #{gem_name} #{Gem.loaded_specs[gem_name].version.to_s rescue nil}"
22
+ end
23
+
24
+ class Remix::Stash
25
+ # Remix::Stash API doesn't let you set servers
26
+ @@clusters = {:default => Remix::Stash::Cluster.new(['127.0.0.1:43042', '127.0.0.1:43043'])}
27
+ end
28
+
29
+ class Bench
30
+
31
+ def initialize(loops = nil, stack_depth = nil)
32
+ @loops = (loops || 20000).to_i
33
+ @stack_depth = (stack_depth || 0).to_i
34
+
35
+ puts "Loops is #{@loops}"
36
+ puts "Stack depth is #{@stack_depth}"
37
+
38
+ @m_value = Marshal.dump(
39
+ @small_value = ["testing"])
40
+ @m_large_value = Marshal.dump(
41
+ @large_value = [{"test" => "1", "test2" => "2", Object.new => "3", 4 => 4, "test5" => 2**65}] * 2048)
42
+
43
+ puts "Small value size is: #{@m_value.size} bytes"
44
+ puts "Large value size is: #{@m_large_value.size} bytes"
45
+
46
+ @keys = [
47
+ @k1 = "Short",
48
+ @k2 = "Sym1-2-3::45" * 8,
49
+ @k3 = "Long" * 40,
50
+ @k4 = "Medium" * 8,
51
+ @k5 = "Medium2" * 8,
52
+ @k6 = "Long3" * 40]
53
+
54
+ reset_servers
55
+ reset_clients
56
+
57
+ Benchmark.bm(36) do |x|
58
+ @benchmark = x
59
+ end
60
+ end
61
+
62
+ def run(level = @stack_depth)
63
+ level > 0 ? run(level - 1) : run_without_recursion
64
+ end
65
+
66
+ private
67
+
68
+ def reset_servers
69
+ system("ruby #{HERE}/../setup.rb")
70
+ sleep(1)
71
+ end
72
+
73
+ def reset_clients
74
+ @clients = {
75
+ "libm" => Memcached::Rails.new(
76
+ ['127.0.0.1:43042', '127.0.0.1:43043'],
77
+ :buffer_requests => false, :no_block => false, :namespace => "namespace"),
78
+ "libm:noblock" => Memcached::Rails.new(
79
+ ['127.0.0.1:43042', '127.0.0.1:43043'],
80
+ :no_block => true, :buffer_requests => true, :namespace => "namespace"),
81
+ "libm:udp" => Memcached::Rails.new(
82
+ ["#{UNIX_SOCKET_NAME}0", "#{UNIX_SOCKET_NAME}1"],
83
+ :buffer_requests => false, :no_block => false, :namespace => "namespace"),
84
+ "libm:binary" => Memcached::Rails.new(
85
+ ['127.0.0.1:43042', '127.0.0.1:43043'],
86
+ :buffer_requests => false, :no_block => false, :namespace => "namespace", :binary_protocol => true),
87
+ "libm:noblock_binary" => Memcached::Rails.new(
88
+ ['127.0.0.1:43042', '127.0.0.1:43043'],
89
+ :no_block => true, :buffer_requests => true, :namespace => "namespace", :binary_protocol => true),
90
+ "ruby" => MemCache.new(['127.0.0.1:43042', '127.0.0.1:43043'], :namespace => "namespace"),
91
+ "stash" => Remix::Stash.new(:root)}
92
+ end
93
+
94
+
95
+ def benchmark_clients(test_name, clients = @clients)
96
+ clients.keys.sort.each do |client_name|
97
+ next if client_name == "stash" and test_name == "set-large" # Don't let stash break the world
98
+ client = clients[client_name]
99
+ begin
100
+ yield client
101
+ @benchmark.report("#{test_name}:#{client_name}") { @loops.times { yield client } }
102
+ rescue => e
103
+ # puts "#{test_name}:#{client_name} => #{e.class}"
104
+ # reset_clients
105
+ end
106
+ end
107
+ end
108
+
109
+ def benchmark_hashes(hashes, test_name)
110
+ hashes.each do |hash_name, int|
111
+ @m = Memcached::Rails.new(:hash => hash_name)
112
+ @benchmark.report("#{test_name}:#{hash_name}") do
113
+ @loops.times { yield int }
114
+ end
115
+ end
116
+ end
117
+
118
+ def run_without_recursion
119
+ benchmark_clients("set") do |c|
120
+ c.set @k1, @m_value, 0, true
121
+ c.set @k2, @m_value, 0, true
122
+ c.set @k3, @m_value, 0, true
123
+ end
124
+
125
+ benchmark_clients("get") do |c|
126
+ c.get @k1, true
127
+ c.get @k2, true
128
+ c.get @k3, true
129
+ end
130
+
131
+ benchmark_clients("get-multi") do |c|
132
+ c.get_multi @keys, true
133
+ end
134
+
135
+ benchmark_clients("append") do |c|
136
+ c.append @k1, @m_value
137
+ c.append @k2, @m_value
138
+ c.append @k3, @m_value
139
+ end
140
+
141
+ benchmark_clients("delete") do |c|
142
+ c.delete @k1
143
+ c.delete @k2
144
+ c.delete @k3
145
+ end
146
+
147
+ benchmark_clients("get-missing") do |c|
148
+ c.get @k1
149
+ c.get @k2
150
+ c.get @k3
151
+ end
152
+
153
+ benchmark_clients("append-missing") do |c|
154
+ c.append @k1, @m_value
155
+ c.append @k2, @m_value
156
+ c.append @k3, @m_value
157
+ end
158
+
159
+ benchmark_clients("set-large") do |c|
160
+ c.set @k1, @m_large_value, 0, true
161
+ c.set @k2, @m_large_value, 0, true
162
+ c.set @k3, @m_large_value, 0, true
163
+ end
164
+
165
+ benchmark_clients("get-large") do |c|
166
+ c.get @k1, true
167
+ c.get @k2, true
168
+ c.get @k3, true
169
+ end
170
+
171
+ benchmark_clients("set-ruby") do |c|
172
+ c.set @k1, @value
173
+ c.set @k2, @value
174
+ c.set @k3, @value
175
+ end
176
+
177
+ benchmark_clients("get-ruby") do |c|
178
+ c.get @k1
179
+ c.get @k2
180
+ c.get @k3
181
+ end
182
+
183
+ benchmark_clients("set-ruby-large") do |c|
184
+ c.set @k1, @large_value
185
+ c.set @k2, @large_value
186
+ c.set @k3, @large_value
187
+ end
188
+
189
+ benchmark_clients("get-ruby-large") do |c|
190
+ c.get @k1
191
+ c.get @k2
192
+ c.get @k3
193
+ end
194
+
195
+ benchmark_hashes(Memcached::HASH_VALUES, "hash") do |i|
196
+ Rlibmemcached.memcached_generate_hash_rvalue(@k1, i)
197
+ Rlibmemcached.memcached_generate_hash_rvalue(@k2, i)
198
+ Rlibmemcached.memcached_generate_hash_rvalue(@k3, i)
199
+ Rlibmemcached.memcached_generate_hash_rvalue(@k4, i)
200
+ Rlibmemcached.memcached_generate_hash_rvalue(@k5, i)
201
+ Rlibmemcached.memcached_generate_hash_rvalue(@k6, i)
202
+ end
203
+ end
204
+ end
205
+
206
+ Bench.new(ENV["LOOPS"], ENV["STACK_DEPTH"]).run
207
+
208
+ Process.memory.each do |key, value|
209
+ puts "#{key}: #{value/1024.0}M"
210
+ end if Process.respond_to? :memory
@@ -0,0 +1,14 @@
1
+
2
+ require "#{File.dirname(__FILE__)}/../setup"
3
+
4
+ $LOAD_PATH << "#{File.dirname(__FILE__)}/../../lib/"
5
+ require 'rubygems'
6
+ require 'memcached'
7
+ require 'ruby-prof'
8
+
9
+ result = RubyProf.profile do
10
+ load "#{HERE}/profile/valgrind.rb"
11
+ end
12
+
13
+ printer = RubyProf::GraphPrinter.new(result)
14
+ printer.print(STDOUT, 0)
@@ -0,0 +1,147 @@
1
+
2
+ require "#{File.dirname(__FILE__)}/../setup"
3
+
4
+ $LOAD_PATH << "#{File.dirname(__FILE__)}/../../lib/"
5
+ require 'memcached'
6
+ require 'rubygems'
7
+
8
+ class Worker
9
+ def initialize(method_name, iterations)
10
+ @method = method_name || 'mixed'
11
+ @i = (iterations || 10000).to_i
12
+
13
+ puts "*** Running #{@method.inspect} test for #{@i} loops. ***"
14
+
15
+ @key1 = "key1-"*8
16
+ @key2 = "key2-"*8
17
+
18
+ @value = []
19
+ @marshalled = Marshal.dump(@value)
20
+
21
+ @opts = [
22
+ ["#{UNIX_SOCKET_NAME}0", "#{UNIX_SOCKET_NAME}1"],
23
+ {
24
+ :buffer_requests => false,
25
+ :no_block => false,
26
+ :namespace => "namespace"
27
+ }
28
+ ]
29
+ @cache = Memcached.new(*@opts)
30
+
31
+ @cache.set @key1, @value
32
+ end
33
+
34
+ def work
35
+ case @method
36
+ when "set"
37
+ @i.times do
38
+ @cache.set @key1, @value
39
+ end
40
+ when "get"
41
+ @i.times do
42
+ @cache.get @key1
43
+ end
44
+ when "delete"
45
+ @i.times do
46
+ @cache.set @key1, @value
47
+ @cache.delete @key1
48
+ end
49
+ when "delete-miss"
50
+ @i.times do
51
+ @cache.delete @key1
52
+ end
53
+ when "get-miss"
54
+ @i.times do
55
+ begin
56
+ @cache.get @key2
57
+ rescue Memcached::NotFound
58
+ end
59
+ end
60
+ when "get-increasing"
61
+ one_k = "x"*1024
62
+ @i.times do |i|
63
+ @cache.set @key1, one_k*(i+1), 0, false
64
+ @cache.get @key1, false
65
+ end
66
+ when "get-miss-increasing"
67
+ @i.times do |i|
68
+ @cache.delete @key2 rescue nil
69
+ begin
70
+ @cache.get @key2
71
+ rescue Memcached::NotFound
72
+ end
73
+ end
74
+ when "add"
75
+ @i.times do
76
+ begin
77
+ @cache.delete @key1
78
+ rescue
79
+ end
80
+ @cache.add @key1, @value
81
+ end
82
+ when "add-present"
83
+ @cache.set @key1, @value
84
+ @i.times do
85
+ begin
86
+ @cache.add @key1, @value
87
+ rescue Memcached::NotStored
88
+ end
89
+ end
90
+ when "mixed"
91
+ @i.times do
92
+ @cache.set @key1, @value
93
+ @cache.get @key1
94
+ end
95
+ when "stats"
96
+ @i.times do
97
+ @cache.stats
98
+ end
99
+ when "multiget"
100
+ @i.times do
101
+ @cache.get([@key1, @key2])
102
+ end
103
+ when "clone"
104
+ @i.times do
105
+ cache = @cache.clone
106
+ end
107
+ when "reset"
108
+ @i.times do
109
+ @cache.reset
110
+ end
111
+ when "servers"
112
+ @i.times do
113
+ @cache.servers
114
+ end
115
+ when "server_by_key"
116
+ @i.times do
117
+ @cache.server_by_key(@key1)
118
+ end
119
+ else
120
+ raise "No such method"
121
+ end
122
+
123
+ puts "*** Garbage collect. ***"
124
+ 10.times do
125
+ GC.start
126
+ sleep 0.1
127
+ end
128
+
129
+ sts, server_sts, clients = 0, 0, 0
130
+ ObjectSpace.each_object(Memcached) { clients += 1 }
131
+ ObjectSpace.each_object(Rlibmemcached::MemcachedSt) { sts += 1 }
132
+ ObjectSpace.each_object(Rlibmemcached::MemcachedServerSt) { server_sts += 1 }
133
+ puts "*** Structs: #{sts} ***"
134
+ puts "*** Server structs: #{server_sts} ***"
135
+ puts "*** Clients: #{clients} ***"
136
+ end
137
+ end
138
+
139
+ Worker.new(ENV['METHOD'], ENV['LOOPS']).work
140
+
141
+ begin
142
+ require 'memory'
143
+ Process.memory.each do |key, value|
144
+ puts "#{key}: #{value/1024.0}M"
145
+ end
146
+ rescue LoadError
147
+ end