dalli_memcached 1.8.0
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/BENCHMARKS +142 -0
- data/CHANGELOG +176 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +45 -0
- data/LICENSE +184 -0
- data/Manifest +209 -0
- data/README.rdoc +124 -0
- data/Rakefile +134 -0
- data/TODO +1 -0
- data/dalli_memcached.gemspec +0 -0
- data/ext/extconf-make.rb +25 -0
- data/ext/extconf.rb +78 -0
- data/ext/libmemcached-0.32/AUTHORS +7 -0
- data/ext/libmemcached-0.32/COPYING +32 -0
- data/ext/libmemcached-0.32/ChangeLog +303 -0
- data/ext/libmemcached-0.32/INSTALL +302 -0
- data/ext/libmemcached-0.32/Makefile.am +36 -0
- data/ext/libmemcached-0.32/Makefile.in +911 -0
- data/ext/libmemcached-0.32/NEWS +1 -0
- data/ext/libmemcached-0.32/README +33 -0
- data/ext/libmemcached-0.32/THANKS +14 -0
- data/ext/libmemcached-0.32/TODO +11 -0
- data/ext/libmemcached-0.32/aclocal.m4 +2108 -0
- data/ext/libmemcached-0.32/clients/Makefile.am +80 -0
- data/ext/libmemcached-0.32/clients/Makefile.in +773 -0
- data/ext/libmemcached-0.32/clients/client_options.h +32 -0
- data/ext/libmemcached-0.32/clients/execute.c +64 -0
- data/ext/libmemcached-0.32/clients/execute.h +5 -0
- data/ext/libmemcached-0.32/clients/generator.c +74 -0
- data/ext/libmemcached-0.32/clients/generator.h +20 -0
- data/ext/libmemcached-0.32/clients/memcat.c +178 -0
- data/ext/libmemcached-0.32/clients/memcp.c +251 -0
- data/ext/libmemcached-0.32/clients/memdump.c +170 -0
- data/ext/libmemcached-0.32/clients/memerror.c +80 -0
- data/ext/libmemcached-0.32/clients/memflush.c +143 -0
- data/ext/libmemcached-0.32/clients/memrm.c +160 -0
- data/ext/libmemcached-0.32/clients/memslap.c +441 -0
- data/ext/libmemcached-0.32/clients/memstat.c +326 -0
- data/ext/libmemcached-0.32/clients/utilities.c +207 -0
- data/ext/libmemcached-0.32/clients/utilities.h +41 -0
- data/ext/libmemcached-0.32/config.h.in +254 -0
- data/ext/libmemcached-0.32/config/compile +143 -0
- data/ext/libmemcached-0.32/config/config.guess +1561 -0
- data/ext/libmemcached-0.32/config/config.rpath +666 -0
- data/ext/libmemcached-0.32/config/config.sub +1686 -0
- data/ext/libmemcached-0.32/config/depcomp +630 -0
- data/ext/libmemcached-0.32/config/install-sh +520 -0
- data/ext/libmemcached-0.32/config/ltmain.sh +9636 -0
- data/ext/libmemcached-0.32/config/missing +376 -0
- data/ext/libmemcached-0.32/configure +23843 -0
- data/ext/libmemcached-0.32/configure.ac +120 -0
- data/ext/libmemcached-0.32/libmemcached/Makefile.am +111 -0
- data/ext/libmemcached-0.32/libmemcached/Makefile.in +1069 -0
- data/ext/libmemcached-0.32/libmemcached/byteorder.c +31 -0
- data/ext/libmemcached-0.32/libmemcached/common.h +189 -0
- data/ext/libmemcached-0.32/libmemcached/crc.c +86 -0
- data/ext/libmemcached-0.32/libmemcached/hsieh_hash.c +68 -0
- data/ext/libmemcached-0.32/libmemcached/jenkins_hash.c +213 -0
- data/ext/libmemcached-0.32/libmemcached/libmemcached.ver +1 -0
- data/ext/libmemcached-0.32/libmemcached/libmemcached_probes.d +30 -0
- data/ext/libmemcached-0.32/libmemcached/libmemcached_probes.h +82 -0
- data/ext/libmemcached-0.32/libmemcached/md5.c +354 -0
- data/ext/libmemcached-0.32/libmemcached/memcached.c +153 -0
- data/ext/libmemcached-0.32/libmemcached/memcached.h +305 -0
- data/ext/libmemcached-0.32/libmemcached/memcached.hpp +799 -0
- data/ext/libmemcached-0.32/libmemcached/memcached/README.txt +7 -0
- data/ext/libmemcached-0.32/libmemcached/memcached/protocol_binary.h +385 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_allocators.c +72 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_analyze.c +100 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_auto.c +207 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_behavior.c +290 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_callback.c +175 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_configure.h.in +23 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_connect.c +371 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_constants.h +146 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_delete.c +0 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_do.c +72 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_dump.c +79 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_exist.c +114 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_exist.h +20 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_fetch.c +102 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_flush.c +89 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_flush_buffers.c +23 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_get.c +494 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_get.h +87 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_hash.c +252 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_hosts.c +510 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_internal.h +31 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_io.c +594 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_io.h +72 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_key.c +28 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_parse.c +74 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_pool.h +38 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_purge.c +76 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_quit.c +75 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_response.c +529 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_result.c +57 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_result.h +59 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_sasl.c +225 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_sasl.h +44 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_server.c +159 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_server.h +93 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_stats.c +437 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_storage.c +514 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_storage.h +107 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_strerror.c +92 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_string.c +138 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_string.h +53 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_touch.c +60 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_touch.h +31 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_types.h +44 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_util.h +15 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_verbosity.c +36 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_version.c +112 -0
- data/ext/libmemcached-0.32/libmemcached/memcached_watchpoint.h +38 -0
- data/ext/libmemcached-0.32/libmemcached/murmur_hash.c +76 -0
- data/ext/libmemcached-0.32/libmemcached/visibility.h +51 -0
- data/ext/libmemcached-0.32/libmemcachedutil/Makefile.am +11 -0
- data/ext/libmemcached-0.32/libmemcachedutil/Makefile.in +604 -0
- data/ext/libmemcached-0.32/libmemcachedutil/libmemcachedutil.ver +1 -0
- data/ext/libmemcached-0.32/libmemcachedutil/memcached_pool.c +170 -0
- data/ext/libmemcached-0.32/m4/ac_cxx_compile_stdcxx_0x.m4 +103 -0
- data/ext/libmemcached-0.32/m4/ac_cxx_header_stdcxx_98.m4 +67 -0
- data/ext/libmemcached-0.32/m4/acx_pthread.m4 +276 -0
- data/ext/libmemcached-0.32/m4/byteorder.m4 +40 -0
- data/ext/libmemcached-0.32/m4/deprecated.m4 +17 -0
- data/ext/libmemcached-0.32/m4/enable_utillib.m4 +16 -0
- data/ext/libmemcached-0.32/m4/extensions.m4 +94 -0
- data/ext/libmemcached-0.32/m4/hsieh.m4 +18 -0
- data/ext/libmemcached-0.32/m4/lib-prefix.m4 +221 -0
- data/ext/libmemcached-0.32/m4/libtool.m4 +7831 -0
- data/ext/libmemcached-0.32/m4/ltoptions.m4 +369 -0
- data/ext/libmemcached-0.32/m4/ltsugar.m4 +123 -0
- data/ext/libmemcached-0.32/m4/ltversion.m4 +23 -0
- data/ext/libmemcached-0.32/m4/lt~obsolete.m4 +98 -0
- data/ext/libmemcached-0.32/m4/memcached.m4 +30 -0
- data/ext/libmemcached-0.32/m4/pandora_64bit.m4 +55 -0
- data/ext/libmemcached-0.32/m4/pandora_canonical.m4 +151 -0
- data/ext/libmemcached-0.32/m4/pandora_check_compiler_version.m4 +37 -0
- data/ext/libmemcached-0.32/m4/pandora_check_cxx_standard.m4 +16 -0
- data/ext/libmemcached-0.32/m4/pandora_enable_dtrace.m4 +41 -0
- data/ext/libmemcached-0.32/m4/pandora_ensure_gcc_version.m4 +36 -0
- data/ext/libmemcached-0.32/m4/pandora_have_better_malloc.m4 +54 -0
- data/ext/libmemcached-0.32/m4/pandora_have_sasl.m4 +133 -0
- data/ext/libmemcached-0.32/m4/pandora_header_assert.m4 +23 -0
- data/ext/libmemcached-0.32/m4/pandora_libtool.m4 +15 -0
- data/ext/libmemcached-0.32/m4/pandora_optimize.m4 +79 -0
- data/ext/libmemcached-0.32/m4/pandora_shared_ptr.m4 +56 -0
- data/ext/libmemcached-0.32/m4/pandora_vc_build.m4 +32 -0
- data/ext/libmemcached-0.32/m4/pandora_warnings.m4 +262 -0
- data/ext/libmemcached-0.32/m4/pod2man.m4 +7 -0
- data/ext/libmemcached-0.32/m4/protocol_binary.m4 +23 -0
- data/ext/libmemcached-0.32/m4/setsockopt.m4 +57 -0
- data/ext/libmemcached-0.32/m4/visibility.m4 +52 -0
- data/ext/libmemcached-0.32/support/Makefile.am +4 -0
- data/ext/libmemcached-0.32/support/Makefile.in +487 -0
- data/ext/libmemcached-0.32/support/libmemcached-fc.spec.in +105 -0
- data/ext/libmemcached-0.32/support/libmemcached.pc.in +10 -0
- data/ext/libmemcached-0.32/support/libmemcached.spec +105 -0
- data/ext/libmemcached-0.32/support/libmemcached.spec.in +105 -0
- data/ext/libmemcached-0.32/support/set_benchmark.sh +5 -0
- data/ext/libmemcached-0.32/tests/Makefile.am +113 -0
- data/ext/libmemcached-0.32/tests/Makefile.in +762 -0
- data/ext/libmemcached-0.32/tests/atomsmasher.c +245 -0
- data/ext/libmemcached-0.32/tests/function.c +4904 -0
- data/ext/libmemcached-0.32/tests/ketama_test_cases.h +108 -0
- data/ext/libmemcached-0.32/tests/output.cmp +7 -0
- data/ext/libmemcached-0.32/tests/output.res +7 -0
- data/ext/libmemcached-0.32/tests/output2.res +46 -0
- data/ext/libmemcached-0.32/tests/plus.cpp +293 -0
- data/ext/libmemcached-0.32/tests/r/memcat.res +19 -0
- data/ext/libmemcached-0.32/tests/r/memcp.res +27 -0
- data/ext/libmemcached-0.32/tests/r/memrm.res +19 -0
- data/ext/libmemcached-0.32/tests/r/memslap.res +33 -0
- data/ext/libmemcached-0.32/tests/r/memstat.res +33 -0
- data/ext/libmemcached-0.32/tests/server.c +118 -0
- data/ext/libmemcached-0.32/tests/server.h +25 -0
- data/ext/libmemcached-0.32/tests/start.c +16 -0
- data/ext/libmemcached-0.32/tests/t/memcat.test +4 -0
- data/ext/libmemcached-0.32/tests/t/memcp.test +3 -0
- data/ext/libmemcached-0.32/tests/t/memrm.test +3 -0
- data/ext/libmemcached-0.32/tests/t/memslap.test +5 -0
- data/ext/libmemcached-0.32/tests/t/memstat.test +3 -0
- data/ext/libmemcached-0.32/tests/test.c +137 -0
- data/ext/libmemcached-0.32/tests/test.h +46 -0
- data/ext/libmemcached-0.32/tests/udp.c +76 -0
- data/ext/rlibmemcached.i +258 -0
- data/ext/rlibmemcached_wrap.c +13917 -0
- data/lib/memcached.rb +33 -0
- data/lib/memcached/auth.rb +16 -0
- data/lib/memcached/behaviors.rb +78 -0
- data/lib/memcached/exceptions.rb +84 -0
- data/lib/memcached/experimental.rb +48 -0
- data/lib/memcached/marshal_codec.rb +10 -0
- data/lib/memcached/memcached.rb +732 -0
- data/lib/memcached/rails.rb +250 -0
- data/test/profile/benchmark.rb +280 -0
- data/test/profile/c_profiler.rb +14 -0
- data/test/profile/exercise.rb +185 -0
- data/test/profile/rb_profiler.rb +21 -0
- data/test/profile/valgrind.rb +10 -0
- data/test/setup.rb +30 -0
- data/test/teardown.rb +0 -0
- data/test/test_helper.rb +18 -0
- data/test/unit/binding_test.rb +8 -0
- data/test/unit/memcached_experimental_test.rb +272 -0
- data/test/unit/memcached_test.rb +1487 -0
- data/test/unit/rails_test.rb +330 -0
- metadata +347 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
require 'memcached'
|
|
2
|
+
|
|
3
|
+
class Memcached
|
|
4
|
+
|
|
5
|
+
(instance_methods - NilClass.instance_methods).each do |method_name|
|
|
6
|
+
eval("alias :'#{method_name}_orig' :'#{method_name}'")
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# A legacy compatibility wrapper for the Memcached class. It has basic compatibility with the <b>memcache-client</b> API and Rails 3.2. (Note that ActiveSupport::Duration objects are supported, but not recommended, as ttl parameters. Using Fixnum ttls, such as provided by time_constants.gem, is much faster.)
|
|
10
|
+
class Rails < ::Memcached
|
|
11
|
+
|
|
12
|
+
DEFAULTS = {
|
|
13
|
+
:logger => nil,
|
|
14
|
+
:string_return_types => false
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
attr_reader :logger
|
|
18
|
+
|
|
19
|
+
alias :servers= :set_servers
|
|
20
|
+
|
|
21
|
+
# See Memcached#new for details.
|
|
22
|
+
def initialize(*args)
|
|
23
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
|
24
|
+
servers = Array(
|
|
25
|
+
args.any? ? args.unshift : opts.delete(:servers)
|
|
26
|
+
).flatten.compact
|
|
27
|
+
|
|
28
|
+
opts[:prefix_key] = opts.delete(:namespace) if opts[:namespace]
|
|
29
|
+
opts[:prefix_delimiter] = opts.delete(:namespace_separator) if opts[:namespace_separator]
|
|
30
|
+
|
|
31
|
+
@logger = opts.delete(:logger)
|
|
32
|
+
@string_return_types = opts.delete(:string_return_types)
|
|
33
|
+
|
|
34
|
+
logger.info { "memcached #{VERSION} #{servers.inspect}" } if logger
|
|
35
|
+
super(servers, opts)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def logger=(logger)
|
|
39
|
+
@logger = logger
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def namespace
|
|
43
|
+
@options[:prefix_key]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Check if there are any servers defined?
|
|
47
|
+
def active?
|
|
48
|
+
servers.any?
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def log_exception(e)
|
|
52
|
+
logger.warn("memcached error: #{e.class}: #{e.message}") if logger
|
|
53
|
+
false
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Wraps Memcached#get so that it doesn't raise. This has the side-effect of preventing you from
|
|
57
|
+
# storing <tt>nil</tt> values.
|
|
58
|
+
def get(key, raw=false)
|
|
59
|
+
super(key, !raw)
|
|
60
|
+
rescue NotFound
|
|
61
|
+
rescue Error => e
|
|
62
|
+
log_exception e
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Alternative to #get. Accepts a key and an optional options hash supporting the single option
|
|
66
|
+
# :raw.
|
|
67
|
+
def read(key, options = nil)
|
|
68
|
+
if options
|
|
69
|
+
get(key, options[:raw])
|
|
70
|
+
else
|
|
71
|
+
get(key)
|
|
72
|
+
end
|
|
73
|
+
rescue NotFound
|
|
74
|
+
rescue Error => e
|
|
75
|
+
log_exception e
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Returns whether the key exists, even if the value is nil.
|
|
79
|
+
def exist?(key, options = {})
|
|
80
|
+
exist(key)
|
|
81
|
+
true
|
|
82
|
+
rescue NotFound
|
|
83
|
+
false
|
|
84
|
+
rescue Error => e
|
|
85
|
+
log_exception e
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Wraps Memcached#cas so that it doesn't raise. Doesn't set anything if no value is present.
|
|
89
|
+
def cas(key, ttl=@default_ttl, raw=false, &block)
|
|
90
|
+
super(key, ttl, !raw, &block)
|
|
91
|
+
true
|
|
92
|
+
rescue TypeError => e
|
|
93
|
+
# Maybe we got an ActiveSupport::Duration
|
|
94
|
+
ttl = ttl.value and retry rescue raise e
|
|
95
|
+
rescue NotFound, ConnectionDataExists
|
|
96
|
+
false
|
|
97
|
+
rescue Error => e
|
|
98
|
+
log_exception e
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
alias :compare_and_swap :cas
|
|
102
|
+
|
|
103
|
+
# Wraps Memcached#get.
|
|
104
|
+
def get_multi(keys, raw=false)
|
|
105
|
+
get_orig(keys, !raw)
|
|
106
|
+
rescue NotFound
|
|
107
|
+
rescue Error => e
|
|
108
|
+
log_exception e
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Wraps Memcached#set.
|
|
112
|
+
def set(key, value, ttl=@default_ttl, raw=false)
|
|
113
|
+
super(key, value, ttl, !raw)
|
|
114
|
+
true
|
|
115
|
+
rescue TypeError => e
|
|
116
|
+
# Maybe we got an ActiveSupport::Duration
|
|
117
|
+
ttl = ttl.value and retry rescue raise e
|
|
118
|
+
rescue NotStored
|
|
119
|
+
false
|
|
120
|
+
rescue Error => e
|
|
121
|
+
log_exception e
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Alternative to #set. Accepts a key, value, and an optional options hash supporting the
|
|
125
|
+
# options :raw and :ttl.
|
|
126
|
+
def write(key, value, options = nil)
|
|
127
|
+
value = value.to_s if options && options[:raw]
|
|
128
|
+
ttl = options ? (options[:ttl] || options[:expires_in] || @default_ttl) : @default_ttl
|
|
129
|
+
raw = options ? options[:raw] : nil
|
|
130
|
+
if options && options[:unless_exist]
|
|
131
|
+
add(key, value, ttl, raw)
|
|
132
|
+
else
|
|
133
|
+
set(key, value, ttl, raw)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def fetch(key, options = nil)
|
|
138
|
+
result = read(key, options)
|
|
139
|
+
if result.nil?
|
|
140
|
+
if block_given?
|
|
141
|
+
result = yield
|
|
142
|
+
write(key, result, options)
|
|
143
|
+
result
|
|
144
|
+
else
|
|
145
|
+
result
|
|
146
|
+
end
|
|
147
|
+
else
|
|
148
|
+
result
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Wraps Memcached#add so that it doesn't raise.
|
|
153
|
+
def add(key, value, ttl=@default_ttl, raw=false)
|
|
154
|
+
super(key, value, ttl, !raw)
|
|
155
|
+
@string_return_types ? "STORED\r\n" : true
|
|
156
|
+
rescue TypeError => e
|
|
157
|
+
# Maybe we got an ActiveSupport::Duration
|
|
158
|
+
ttl = ttl.value and retry rescue raise e
|
|
159
|
+
rescue NotStored
|
|
160
|
+
rescue Error => e
|
|
161
|
+
log_exception e
|
|
162
|
+
@string_return_types? "NOT STORED\r\n" : false
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Wraps Memcached#delete so that it doesn't raise.
|
|
166
|
+
def delete(key, options = nil)
|
|
167
|
+
super(key)
|
|
168
|
+
true
|
|
169
|
+
rescue NotFound
|
|
170
|
+
false
|
|
171
|
+
rescue Error => e
|
|
172
|
+
log_exception e
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Wraps Memcached#incr so that it doesn't raise.
|
|
176
|
+
def incr(*args)
|
|
177
|
+
super
|
|
178
|
+
rescue NotFound
|
|
179
|
+
rescue Error => e
|
|
180
|
+
log_exception e
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Wraps Memcached#decr so that it doesn't raise.
|
|
184
|
+
def decr(*args)
|
|
185
|
+
super
|
|
186
|
+
rescue NotFound
|
|
187
|
+
rescue Error => e
|
|
188
|
+
log_exception e
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Wraps Memcached#append so that it doesn't raise.
|
|
192
|
+
def append(*args)
|
|
193
|
+
super
|
|
194
|
+
rescue NotStored
|
|
195
|
+
rescue Error => e
|
|
196
|
+
log_exception e
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Wraps Memcached#prepend so that it doesn't raise.
|
|
200
|
+
def prepend(*args)
|
|
201
|
+
super
|
|
202
|
+
rescue NotStored
|
|
203
|
+
rescue Error => e
|
|
204
|
+
log_exception e
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
alias :flush_all :flush
|
|
208
|
+
alias :clear :flush
|
|
209
|
+
|
|
210
|
+
alias :"[]" :get
|
|
211
|
+
alias :"[]=" :set
|
|
212
|
+
|
|
213
|
+
def read_multi(*keys)
|
|
214
|
+
return {} if keys.empty?
|
|
215
|
+
get_multi(keys)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Return an array of server objects.
|
|
219
|
+
def servers
|
|
220
|
+
server_structs.each do |server|
|
|
221
|
+
def server.alive?
|
|
222
|
+
next_retry <= Time.now
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
# Wraps Memcached#set_servers to convert server objects to strings.
|
|
228
|
+
def set_servers(servers)
|
|
229
|
+
servers = Array(servers)
|
|
230
|
+
servers.map! do |server|
|
|
231
|
+
server.is_a?(String) ? server : inspect_server(server)
|
|
232
|
+
end
|
|
233
|
+
super
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def increment(name, amount = 1, options = nil)
|
|
237
|
+
response = super(name, amount)
|
|
238
|
+
response ? response.to_i : nil
|
|
239
|
+
rescue
|
|
240
|
+
nil
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def decrement(name, amount = 1, options = nil)
|
|
244
|
+
response = super(name, amount)
|
|
245
|
+
response ? response.to_i : nil
|
|
246
|
+
rescue
|
|
247
|
+
nil
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
end
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
Bundler.require(:benchmark)
|
|
2
|
+
|
|
3
|
+
HERE = File.dirname(__FILE__)
|
|
4
|
+
$LOAD_PATH << "#{HERE}/../../lib/"
|
|
5
|
+
UNIX_SOCKET_NAME = File.join(ENV['TMPDIR']||'/tmp','memcached')
|
|
6
|
+
JRUBY = defined?(JRUBY_VERSION)
|
|
7
|
+
|
|
8
|
+
require 'ffi/times' if JRUBY
|
|
9
|
+
require 'memcached'
|
|
10
|
+
require 'benchmark'
|
|
11
|
+
require 'rubygems'
|
|
12
|
+
require 'ruby-debug' if ENV['DEBUG'] && !JRUBY
|
|
13
|
+
if ENV['PROFILE']
|
|
14
|
+
require 'ruby-prof'
|
|
15
|
+
require 'fileutils'
|
|
16
|
+
FileUtils.mkdir_p 'profiles'
|
|
17
|
+
end
|
|
18
|
+
begin; require 'memory'; rescue LoadError; end
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
puts `uname -a`
|
|
22
|
+
puts `ruby -v`
|
|
23
|
+
puts `env | egrep '^RUBY'`
|
|
24
|
+
puts "Ruby #{RUBY_VERSION}p#{RUBY_PATCHLEVEL}"
|
|
25
|
+
|
|
26
|
+
[
|
|
27
|
+
["memcached"],
|
|
28
|
+
["remix-stash", "remix/stash"],
|
|
29
|
+
[JRUBY ? "jruby-memcache-client" : "memcache-client", "memcache"],
|
|
30
|
+
["kgio"], ["dalli"]
|
|
31
|
+
].each do |gem_name, requirement|
|
|
32
|
+
begin
|
|
33
|
+
require requirement || gem_name
|
|
34
|
+
gem gem_name
|
|
35
|
+
puts "Loaded #{gem_name} #{Gem.loaded_specs[gem_name].version.to_s rescue nil}"
|
|
36
|
+
rescue LoadError
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class Remix::Stash
|
|
41
|
+
# Remix::Stash API doesn't let you set servers
|
|
42
|
+
@@clusters = {:default => Remix::Stash::Cluster.new(['127.0.0.1:43042', '127.0.0.1:43043'])}
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class Dalli::ClientCompat < Dalli::Client
|
|
46
|
+
def set(*args)
|
|
47
|
+
super(*args[0..2])
|
|
48
|
+
end
|
|
49
|
+
def get(*args)
|
|
50
|
+
super(args.first)
|
|
51
|
+
end
|
|
52
|
+
def get_multi(*args)
|
|
53
|
+
super(args.first)
|
|
54
|
+
end
|
|
55
|
+
def append(*args)
|
|
56
|
+
super
|
|
57
|
+
rescue Dalli::DalliError
|
|
58
|
+
end
|
|
59
|
+
def prepend(*args)
|
|
60
|
+
super
|
|
61
|
+
rescue Dalli::DalliError
|
|
62
|
+
end
|
|
63
|
+
def exist?(key)
|
|
64
|
+
!get(key).nil?
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
class Bench
|
|
69
|
+
|
|
70
|
+
def initialize(loops = nil, stack_depth = nil)
|
|
71
|
+
@loops = (loops || 50000).to_i
|
|
72
|
+
@stack_depth = (stack_depth || 0).to_i
|
|
73
|
+
|
|
74
|
+
puts "PID is #{Process.pid}"
|
|
75
|
+
puts "Loops is #{@loops}"
|
|
76
|
+
puts "Stack depth is #{@stack_depth}"
|
|
77
|
+
|
|
78
|
+
@m_value = Marshal.dump(
|
|
79
|
+
@small_value = ["testing"])
|
|
80
|
+
@m_large_value = Marshal.dump(
|
|
81
|
+
@large_value = [{"test" => "1", "test2" => "2", Object.new => "3", 4 => 4, "test5" => 2**65}] * 2048)
|
|
82
|
+
|
|
83
|
+
puts "Small value size is: #{@m_value.size} bytes"
|
|
84
|
+
puts "Large value size is: #{@m_large_value.size} bytes"
|
|
85
|
+
|
|
86
|
+
@keys = [
|
|
87
|
+
@k1 = "Short",
|
|
88
|
+
@k2 = "Sym1-2-3::45" * 8,
|
|
89
|
+
@k3 = "Long" * 40,
|
|
90
|
+
@k4 = "Medium" * 8,
|
|
91
|
+
@k5 = "Medium2" * 8,
|
|
92
|
+
@k6 = "Long3" * 40]
|
|
93
|
+
|
|
94
|
+
reset_servers
|
|
95
|
+
reset_clients
|
|
96
|
+
|
|
97
|
+
Benchmark.bm(36) do |x|
|
|
98
|
+
@benchmark = x
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def run(level = @stack_depth)
|
|
103
|
+
level > 0 ? run(level - 1) : run_without_recursion
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
private
|
|
107
|
+
|
|
108
|
+
def reset_servers
|
|
109
|
+
system("ruby #{HERE}/../setup.rb")
|
|
110
|
+
sleep(1)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def reset_clients
|
|
114
|
+
# Other clients
|
|
115
|
+
@clients = {
|
|
116
|
+
"mclient:ascii" => MemCache.new(['127.0.0.1:43042', '127.0.0.1:43043']),
|
|
117
|
+
"stash:bin" => Remix::Stash.new(:root),
|
|
118
|
+
"dalli:bin" => Dalli::ClientCompat.new(['127.0.0.1:43042', '127.0.0.1:43043'], :marshal => false, :threadsafe => false)}
|
|
119
|
+
|
|
120
|
+
# Us
|
|
121
|
+
@clients.merge!({
|
|
122
|
+
"libm:ascii" => Memcached::Rails.new(
|
|
123
|
+
['127.0.0.1:43042', '127.0.0.1:43043'],
|
|
124
|
+
:buffer_requests => false, :no_block => false, :namespace => "namespace"),
|
|
125
|
+
"libm:ascii:pipeline" => Memcached::Rails.new(
|
|
126
|
+
['127.0.0.1:43042', '127.0.0.1:43043'],
|
|
127
|
+
:no_block => true, :buffer_requests => true, :noreply => true, :namespace => "namespace"),
|
|
128
|
+
"libm:ascii:udp" => Memcached::Rails.new(
|
|
129
|
+
["#{UNIX_SOCKET_NAME}0", "#{UNIX_SOCKET_NAME}1"],
|
|
130
|
+
:buffer_requests => false, :no_block => false, :namespace => "namespace"),
|
|
131
|
+
"libm:bin" => Memcached::Rails.new(
|
|
132
|
+
['127.0.0.1:43042', '127.0.0.1:43043'],
|
|
133
|
+
:buffer_requests => false, :no_block => false, :namespace => "namespace", :binary_protocol => true),
|
|
134
|
+
"libm:bin:buffer" => Memcached::Rails.new(
|
|
135
|
+
['127.0.0.1:43042', '127.0.0.1:43043'],
|
|
136
|
+
:no_block => true, :buffer_requests => true, :namespace => "namespace", :binary_protocol => true)})
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def benchmark_clients(test_name, populate_keys = true)
|
|
140
|
+
return if ENV["TEST"] and !test_name.include?(ENV["TEST"])
|
|
141
|
+
|
|
142
|
+
@clients.keys.sort.each do |client_name|
|
|
143
|
+
next if ENV["CLIENT"] and !client_name.include?(ENV["CLIENT"])
|
|
144
|
+
next if client_name == "stash" and test_name == "set-large" # Don't let stash break the world
|
|
145
|
+
|
|
146
|
+
client = @clients[client_name]
|
|
147
|
+
begin
|
|
148
|
+
if populate_keys
|
|
149
|
+
client.set @k1, @m_value, 0, true
|
|
150
|
+
client.set @k2, @m_value, 0, true
|
|
151
|
+
client.set @k3, @m_value, 0, true
|
|
152
|
+
else
|
|
153
|
+
client.delete @k1
|
|
154
|
+
client.delete @k2
|
|
155
|
+
client.delete @k3
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Force any JITs to run
|
|
159
|
+
10003.times { yield client }
|
|
160
|
+
|
|
161
|
+
GC.disable if !JRUBY
|
|
162
|
+
RubyProf.start if ENV['PROFILE']
|
|
163
|
+
@benchmark.report("#{test_name}: #{client_name}") { @loops.times { yield client } }
|
|
164
|
+
if ENV['PROFILE']
|
|
165
|
+
prof = RubyProf::MultiPrinter.new(RubyProf.stop)
|
|
166
|
+
prof.print(:path => 'profiles', :profile => "#{test_name}-#{client_name.gsub(':','-')}")
|
|
167
|
+
end
|
|
168
|
+
rescue Exception => e
|
|
169
|
+
puts "#{test_name}: #{client_name} => #{e.inspect}" if ENV["DEBUG"]
|
|
170
|
+
reset_clients
|
|
171
|
+
end
|
|
172
|
+
GC.enable if !JRUBY
|
|
173
|
+
end
|
|
174
|
+
puts
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def benchmark_hashes(hashes, test_name)
|
|
178
|
+
hashes.each do |hash_name, int|
|
|
179
|
+
@m = Memcached::Rails.new(:hash => hash_name)
|
|
180
|
+
@benchmark.report("#{test_name}:#{hash_name}") do
|
|
181
|
+
(@loops * 5).times { yield int }
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def run_without_recursion
|
|
187
|
+
benchmark_clients("set") do |c|
|
|
188
|
+
c.set @k1, @m_value, 0, true
|
|
189
|
+
c.set @k2, @m_value, 0, true
|
|
190
|
+
c.set @k3, @m_value, 0, true
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
benchmark_clients("get") do |c|
|
|
194
|
+
c.get @k1, true
|
|
195
|
+
c.get @k2, true
|
|
196
|
+
c.get @k3, true
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
benchmark_clients("get-multi") do |c|
|
|
200
|
+
c.get_multi @keys, true
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
benchmark_clients("append") do |c|
|
|
204
|
+
c.append @k1, @m_value
|
|
205
|
+
c.append @k2, @m_value
|
|
206
|
+
c.append @k3, @m_value
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
benchmark_clients("prepend") do |c|
|
|
210
|
+
c.prepend @k1, @m_value
|
|
211
|
+
c.prepend @k2, @m_value
|
|
212
|
+
c.prepend @k3, @m_value
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
benchmark_clients("delete") do |c|
|
|
216
|
+
c.delete @k1
|
|
217
|
+
c.delete @k2
|
|
218
|
+
c.delete @k3
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
benchmark_clients("exist") do |c|
|
|
222
|
+
c.exist? @k1
|
|
223
|
+
c.exist? @k2
|
|
224
|
+
c.exist? @k3
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
benchmark_clients("get-missing", false) do |c|
|
|
228
|
+
c.get @k1
|
|
229
|
+
c.get @k2
|
|
230
|
+
c.get @k3
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
benchmark_clients("append-missing", false) do |c|
|
|
234
|
+
c.append @k1, @m_value
|
|
235
|
+
c.append @k2, @m_value
|
|
236
|
+
c.append @k3, @m_value
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
benchmark_clients("prepend-missing", false) do |c|
|
|
240
|
+
c.prepend @k1, @m_value
|
|
241
|
+
c.prepend @k2, @m_value
|
|
242
|
+
c.prepend @k3, @m_value
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
benchmark_clients("exist-missing", false) do |c|
|
|
246
|
+
c.exist? @k1
|
|
247
|
+
c.exist? @k2
|
|
248
|
+
c.exist? @k3
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
benchmark_clients("set-large") do |c|
|
|
252
|
+
c.set @k1, @m_large_value, 0, true
|
|
253
|
+
c.set @k2, @m_large_value, 0, true
|
|
254
|
+
c.set @k3, @m_large_value, 0, true
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
benchmark_clients("get-large") do |c|
|
|
258
|
+
c.get @k1, true
|
|
259
|
+
c.get @k2, true
|
|
260
|
+
c.get @k3, true
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
if defined?(Memcached) && !ENV['TEST'] && !ENV['CLIENT']
|
|
264
|
+
benchmark_hashes(Memcached::HASH_VALUES, "hash") do |i|
|
|
265
|
+
Rlibmemcached.memcached_generate_hash_rvalue(@k1, i)
|
|
266
|
+
Rlibmemcached.memcached_generate_hash_rvalue(@k2, i)
|
|
267
|
+
Rlibmemcached.memcached_generate_hash_rvalue(@k3, i)
|
|
268
|
+
Rlibmemcached.memcached_generate_hash_rvalue(@k4, i)
|
|
269
|
+
Rlibmemcached.memcached_generate_hash_rvalue(@k5, i)
|
|
270
|
+
Rlibmemcached.memcached_generate_hash_rvalue(@k6, i)
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
Bench.new(ENV["LOOPS"], ENV["STACK_DEPTH"]).run
|
|
277
|
+
|
|
278
|
+
Process.memory.each do |key, value|
|
|
279
|
+
puts "#{key}: #{value/1024.0}M"
|
|
280
|
+
end if Process.respond_to? :memory
|