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.
Files changed (209) hide show
  1. data/BENCHMARKS +142 -0
  2. data/CHANGELOG +176 -0
  3. data/Gemfile +11 -0
  4. data/Gemfile.lock +45 -0
  5. data/LICENSE +184 -0
  6. data/Manifest +209 -0
  7. data/README.rdoc +124 -0
  8. data/Rakefile +134 -0
  9. data/TODO +1 -0
  10. data/dalli_memcached.gemspec +0 -0
  11. data/ext/extconf-make.rb +25 -0
  12. data/ext/extconf.rb +78 -0
  13. data/ext/libmemcached-0.32/AUTHORS +7 -0
  14. data/ext/libmemcached-0.32/COPYING +32 -0
  15. data/ext/libmemcached-0.32/ChangeLog +303 -0
  16. data/ext/libmemcached-0.32/INSTALL +302 -0
  17. data/ext/libmemcached-0.32/Makefile.am +36 -0
  18. data/ext/libmemcached-0.32/Makefile.in +911 -0
  19. data/ext/libmemcached-0.32/NEWS +1 -0
  20. data/ext/libmemcached-0.32/README +33 -0
  21. data/ext/libmemcached-0.32/THANKS +14 -0
  22. data/ext/libmemcached-0.32/TODO +11 -0
  23. data/ext/libmemcached-0.32/aclocal.m4 +2108 -0
  24. data/ext/libmemcached-0.32/clients/Makefile.am +80 -0
  25. data/ext/libmemcached-0.32/clients/Makefile.in +773 -0
  26. data/ext/libmemcached-0.32/clients/client_options.h +32 -0
  27. data/ext/libmemcached-0.32/clients/execute.c +64 -0
  28. data/ext/libmemcached-0.32/clients/execute.h +5 -0
  29. data/ext/libmemcached-0.32/clients/generator.c +74 -0
  30. data/ext/libmemcached-0.32/clients/generator.h +20 -0
  31. data/ext/libmemcached-0.32/clients/memcat.c +178 -0
  32. data/ext/libmemcached-0.32/clients/memcp.c +251 -0
  33. data/ext/libmemcached-0.32/clients/memdump.c +170 -0
  34. data/ext/libmemcached-0.32/clients/memerror.c +80 -0
  35. data/ext/libmemcached-0.32/clients/memflush.c +143 -0
  36. data/ext/libmemcached-0.32/clients/memrm.c +160 -0
  37. data/ext/libmemcached-0.32/clients/memslap.c +441 -0
  38. data/ext/libmemcached-0.32/clients/memstat.c +326 -0
  39. data/ext/libmemcached-0.32/clients/utilities.c +207 -0
  40. data/ext/libmemcached-0.32/clients/utilities.h +41 -0
  41. data/ext/libmemcached-0.32/config.h.in +254 -0
  42. data/ext/libmemcached-0.32/config/compile +143 -0
  43. data/ext/libmemcached-0.32/config/config.guess +1561 -0
  44. data/ext/libmemcached-0.32/config/config.rpath +666 -0
  45. data/ext/libmemcached-0.32/config/config.sub +1686 -0
  46. data/ext/libmemcached-0.32/config/depcomp +630 -0
  47. data/ext/libmemcached-0.32/config/install-sh +520 -0
  48. data/ext/libmemcached-0.32/config/ltmain.sh +9636 -0
  49. data/ext/libmemcached-0.32/config/missing +376 -0
  50. data/ext/libmemcached-0.32/configure +23843 -0
  51. data/ext/libmemcached-0.32/configure.ac +120 -0
  52. data/ext/libmemcached-0.32/libmemcached/Makefile.am +111 -0
  53. data/ext/libmemcached-0.32/libmemcached/Makefile.in +1069 -0
  54. data/ext/libmemcached-0.32/libmemcached/byteorder.c +31 -0
  55. data/ext/libmemcached-0.32/libmemcached/common.h +189 -0
  56. data/ext/libmemcached-0.32/libmemcached/crc.c +86 -0
  57. data/ext/libmemcached-0.32/libmemcached/hsieh_hash.c +68 -0
  58. data/ext/libmemcached-0.32/libmemcached/jenkins_hash.c +213 -0
  59. data/ext/libmemcached-0.32/libmemcached/libmemcached.ver +1 -0
  60. data/ext/libmemcached-0.32/libmemcached/libmemcached_probes.d +30 -0
  61. data/ext/libmemcached-0.32/libmemcached/libmemcached_probes.h +82 -0
  62. data/ext/libmemcached-0.32/libmemcached/md5.c +354 -0
  63. data/ext/libmemcached-0.32/libmemcached/memcached.c +153 -0
  64. data/ext/libmemcached-0.32/libmemcached/memcached.h +305 -0
  65. data/ext/libmemcached-0.32/libmemcached/memcached.hpp +799 -0
  66. data/ext/libmemcached-0.32/libmemcached/memcached/README.txt +7 -0
  67. data/ext/libmemcached-0.32/libmemcached/memcached/protocol_binary.h +385 -0
  68. data/ext/libmemcached-0.32/libmemcached/memcached_allocators.c +72 -0
  69. data/ext/libmemcached-0.32/libmemcached/memcached_analyze.c +100 -0
  70. data/ext/libmemcached-0.32/libmemcached/memcached_auto.c +207 -0
  71. data/ext/libmemcached-0.32/libmemcached/memcached_behavior.c +290 -0
  72. data/ext/libmemcached-0.32/libmemcached/memcached_callback.c +175 -0
  73. data/ext/libmemcached-0.32/libmemcached/memcached_configure.h.in +23 -0
  74. data/ext/libmemcached-0.32/libmemcached/memcached_connect.c +371 -0
  75. data/ext/libmemcached-0.32/libmemcached/memcached_constants.h +146 -0
  76. data/ext/libmemcached-0.32/libmemcached/memcached_delete.c +0 -0
  77. data/ext/libmemcached-0.32/libmemcached/memcached_do.c +72 -0
  78. data/ext/libmemcached-0.32/libmemcached/memcached_dump.c +79 -0
  79. data/ext/libmemcached-0.32/libmemcached/memcached_exist.c +114 -0
  80. data/ext/libmemcached-0.32/libmemcached/memcached_exist.h +20 -0
  81. data/ext/libmemcached-0.32/libmemcached/memcached_fetch.c +102 -0
  82. data/ext/libmemcached-0.32/libmemcached/memcached_flush.c +89 -0
  83. data/ext/libmemcached-0.32/libmemcached/memcached_flush_buffers.c +23 -0
  84. data/ext/libmemcached-0.32/libmemcached/memcached_get.c +494 -0
  85. data/ext/libmemcached-0.32/libmemcached/memcached_get.h +87 -0
  86. data/ext/libmemcached-0.32/libmemcached/memcached_hash.c +252 -0
  87. data/ext/libmemcached-0.32/libmemcached/memcached_hosts.c +510 -0
  88. data/ext/libmemcached-0.32/libmemcached/memcached_internal.h +31 -0
  89. data/ext/libmemcached-0.32/libmemcached/memcached_io.c +594 -0
  90. data/ext/libmemcached-0.32/libmemcached/memcached_io.h +72 -0
  91. data/ext/libmemcached-0.32/libmemcached/memcached_key.c +28 -0
  92. data/ext/libmemcached-0.32/libmemcached/memcached_parse.c +74 -0
  93. data/ext/libmemcached-0.32/libmemcached/memcached_pool.h +38 -0
  94. data/ext/libmemcached-0.32/libmemcached/memcached_purge.c +76 -0
  95. data/ext/libmemcached-0.32/libmemcached/memcached_quit.c +75 -0
  96. data/ext/libmemcached-0.32/libmemcached/memcached_response.c +529 -0
  97. data/ext/libmemcached-0.32/libmemcached/memcached_result.c +57 -0
  98. data/ext/libmemcached-0.32/libmemcached/memcached_result.h +59 -0
  99. data/ext/libmemcached-0.32/libmemcached/memcached_sasl.c +225 -0
  100. data/ext/libmemcached-0.32/libmemcached/memcached_sasl.h +44 -0
  101. data/ext/libmemcached-0.32/libmemcached/memcached_server.c +159 -0
  102. data/ext/libmemcached-0.32/libmemcached/memcached_server.h +93 -0
  103. data/ext/libmemcached-0.32/libmemcached/memcached_stats.c +437 -0
  104. data/ext/libmemcached-0.32/libmemcached/memcached_storage.c +514 -0
  105. data/ext/libmemcached-0.32/libmemcached/memcached_storage.h +107 -0
  106. data/ext/libmemcached-0.32/libmemcached/memcached_strerror.c +92 -0
  107. data/ext/libmemcached-0.32/libmemcached/memcached_string.c +138 -0
  108. data/ext/libmemcached-0.32/libmemcached/memcached_string.h +53 -0
  109. data/ext/libmemcached-0.32/libmemcached/memcached_touch.c +60 -0
  110. data/ext/libmemcached-0.32/libmemcached/memcached_touch.h +31 -0
  111. data/ext/libmemcached-0.32/libmemcached/memcached_types.h +44 -0
  112. data/ext/libmemcached-0.32/libmemcached/memcached_util.h +15 -0
  113. data/ext/libmemcached-0.32/libmemcached/memcached_verbosity.c +36 -0
  114. data/ext/libmemcached-0.32/libmemcached/memcached_version.c +112 -0
  115. data/ext/libmemcached-0.32/libmemcached/memcached_watchpoint.h +38 -0
  116. data/ext/libmemcached-0.32/libmemcached/murmur_hash.c +76 -0
  117. data/ext/libmemcached-0.32/libmemcached/visibility.h +51 -0
  118. data/ext/libmemcached-0.32/libmemcachedutil/Makefile.am +11 -0
  119. data/ext/libmemcached-0.32/libmemcachedutil/Makefile.in +604 -0
  120. data/ext/libmemcached-0.32/libmemcachedutil/libmemcachedutil.ver +1 -0
  121. data/ext/libmemcached-0.32/libmemcachedutil/memcached_pool.c +170 -0
  122. data/ext/libmemcached-0.32/m4/ac_cxx_compile_stdcxx_0x.m4 +103 -0
  123. data/ext/libmemcached-0.32/m4/ac_cxx_header_stdcxx_98.m4 +67 -0
  124. data/ext/libmemcached-0.32/m4/acx_pthread.m4 +276 -0
  125. data/ext/libmemcached-0.32/m4/byteorder.m4 +40 -0
  126. data/ext/libmemcached-0.32/m4/deprecated.m4 +17 -0
  127. data/ext/libmemcached-0.32/m4/enable_utillib.m4 +16 -0
  128. data/ext/libmemcached-0.32/m4/extensions.m4 +94 -0
  129. data/ext/libmemcached-0.32/m4/hsieh.m4 +18 -0
  130. data/ext/libmemcached-0.32/m4/lib-prefix.m4 +221 -0
  131. data/ext/libmemcached-0.32/m4/libtool.m4 +7831 -0
  132. data/ext/libmemcached-0.32/m4/ltoptions.m4 +369 -0
  133. data/ext/libmemcached-0.32/m4/ltsugar.m4 +123 -0
  134. data/ext/libmemcached-0.32/m4/ltversion.m4 +23 -0
  135. data/ext/libmemcached-0.32/m4/lt~obsolete.m4 +98 -0
  136. data/ext/libmemcached-0.32/m4/memcached.m4 +30 -0
  137. data/ext/libmemcached-0.32/m4/pandora_64bit.m4 +55 -0
  138. data/ext/libmemcached-0.32/m4/pandora_canonical.m4 +151 -0
  139. data/ext/libmemcached-0.32/m4/pandora_check_compiler_version.m4 +37 -0
  140. data/ext/libmemcached-0.32/m4/pandora_check_cxx_standard.m4 +16 -0
  141. data/ext/libmemcached-0.32/m4/pandora_enable_dtrace.m4 +41 -0
  142. data/ext/libmemcached-0.32/m4/pandora_ensure_gcc_version.m4 +36 -0
  143. data/ext/libmemcached-0.32/m4/pandora_have_better_malloc.m4 +54 -0
  144. data/ext/libmemcached-0.32/m4/pandora_have_sasl.m4 +133 -0
  145. data/ext/libmemcached-0.32/m4/pandora_header_assert.m4 +23 -0
  146. data/ext/libmemcached-0.32/m4/pandora_libtool.m4 +15 -0
  147. data/ext/libmemcached-0.32/m4/pandora_optimize.m4 +79 -0
  148. data/ext/libmemcached-0.32/m4/pandora_shared_ptr.m4 +56 -0
  149. data/ext/libmemcached-0.32/m4/pandora_vc_build.m4 +32 -0
  150. data/ext/libmemcached-0.32/m4/pandora_warnings.m4 +262 -0
  151. data/ext/libmemcached-0.32/m4/pod2man.m4 +7 -0
  152. data/ext/libmemcached-0.32/m4/protocol_binary.m4 +23 -0
  153. data/ext/libmemcached-0.32/m4/setsockopt.m4 +57 -0
  154. data/ext/libmemcached-0.32/m4/visibility.m4 +52 -0
  155. data/ext/libmemcached-0.32/support/Makefile.am +4 -0
  156. data/ext/libmemcached-0.32/support/Makefile.in +487 -0
  157. data/ext/libmemcached-0.32/support/libmemcached-fc.spec.in +105 -0
  158. data/ext/libmemcached-0.32/support/libmemcached.pc.in +10 -0
  159. data/ext/libmemcached-0.32/support/libmemcached.spec +105 -0
  160. data/ext/libmemcached-0.32/support/libmemcached.spec.in +105 -0
  161. data/ext/libmemcached-0.32/support/set_benchmark.sh +5 -0
  162. data/ext/libmemcached-0.32/tests/Makefile.am +113 -0
  163. data/ext/libmemcached-0.32/tests/Makefile.in +762 -0
  164. data/ext/libmemcached-0.32/tests/atomsmasher.c +245 -0
  165. data/ext/libmemcached-0.32/tests/function.c +4904 -0
  166. data/ext/libmemcached-0.32/tests/ketama_test_cases.h +108 -0
  167. data/ext/libmemcached-0.32/tests/output.cmp +7 -0
  168. data/ext/libmemcached-0.32/tests/output.res +7 -0
  169. data/ext/libmemcached-0.32/tests/output2.res +46 -0
  170. data/ext/libmemcached-0.32/tests/plus.cpp +293 -0
  171. data/ext/libmemcached-0.32/tests/r/memcat.res +19 -0
  172. data/ext/libmemcached-0.32/tests/r/memcp.res +27 -0
  173. data/ext/libmemcached-0.32/tests/r/memrm.res +19 -0
  174. data/ext/libmemcached-0.32/tests/r/memslap.res +33 -0
  175. data/ext/libmemcached-0.32/tests/r/memstat.res +33 -0
  176. data/ext/libmemcached-0.32/tests/server.c +118 -0
  177. data/ext/libmemcached-0.32/tests/server.h +25 -0
  178. data/ext/libmemcached-0.32/tests/start.c +16 -0
  179. data/ext/libmemcached-0.32/tests/t/memcat.test +4 -0
  180. data/ext/libmemcached-0.32/tests/t/memcp.test +3 -0
  181. data/ext/libmemcached-0.32/tests/t/memrm.test +3 -0
  182. data/ext/libmemcached-0.32/tests/t/memslap.test +5 -0
  183. data/ext/libmemcached-0.32/tests/t/memstat.test +3 -0
  184. data/ext/libmemcached-0.32/tests/test.c +137 -0
  185. data/ext/libmemcached-0.32/tests/test.h +46 -0
  186. data/ext/libmemcached-0.32/tests/udp.c +76 -0
  187. data/ext/rlibmemcached.i +258 -0
  188. data/ext/rlibmemcached_wrap.c +13917 -0
  189. data/lib/memcached.rb +33 -0
  190. data/lib/memcached/auth.rb +16 -0
  191. data/lib/memcached/behaviors.rb +78 -0
  192. data/lib/memcached/exceptions.rb +84 -0
  193. data/lib/memcached/experimental.rb +48 -0
  194. data/lib/memcached/marshal_codec.rb +10 -0
  195. data/lib/memcached/memcached.rb +732 -0
  196. data/lib/memcached/rails.rb +250 -0
  197. data/test/profile/benchmark.rb +280 -0
  198. data/test/profile/c_profiler.rb +14 -0
  199. data/test/profile/exercise.rb +185 -0
  200. data/test/profile/rb_profiler.rb +21 -0
  201. data/test/profile/valgrind.rb +10 -0
  202. data/test/setup.rb +30 -0
  203. data/test/teardown.rb +0 -0
  204. data/test/test_helper.rb +18 -0
  205. data/test/unit/binding_test.rb +8 -0
  206. data/test/unit/memcached_experimental_test.rb +272 -0
  207. data/test/unit/memcached_test.rb +1487 -0
  208. data/test/unit/rails_test.rb +330 -0
  209. 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