memcached 0.7.1 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/CHANGELOG +2 -0
- data/COMPATIBILITY +1 -0
- data/Manifest +1 -0
- data/README +7 -2
- data/ext/rlibmemcached.i +35 -1
- data/ext/rlibmemcached_wrap.c +49 -0
- data/lib/memcached/memcached.rb +28 -32
- data/lib/memcached/rails.rb +0 -4
- data/memcached.gemspec +4 -4
- data/test/profile/key.rb +41 -0
- data/test/profile/profile.rb +5 -0
- data/test/unit/memcached_test.rb +88 -28
- metadata +3 -2
- metadata.gz.sig +2 -1
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGELOG
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
|
2
|
+
v0.7.2. Auto-repair unprintable characters and too-long keys; improve performance of namespacing operation.
|
3
|
+
|
2
4
|
v0.7.1. Allow for explicit resetting of the struct on each request, at least until Brian fixes the synchronization problem.
|
3
5
|
|
4
6
|
v0.7. Rails compatibility wrapper; real multiget; rescue UnknownReadFailures in order to reset the struct..
|
data/COMPATIBILITY
CHANGED
data/Manifest
CHANGED
data/README
CHANGED
@@ -22,7 +22,7 @@ The <b>memcached</b> library wraps the pure-C libmemcached client via SWIG.
|
|
22
22
|
|
23
23
|
== Installation
|
24
24
|
|
25
|
-
You need {libmemcached 0.15}[http://tangent.org/552/libmemcached.html]. Other versions
|
25
|
+
You need Ruby 1.8.6, and {libmemcached 0.15}[http://tangent.org/552/libmemcached.html]. Other versions are not supported. You also need {memcached itself}[http://www.danga.com/memcached/] if you want to test against a local server.
|
26
26
|
|
27
27
|
Download and extract the {libmemcached tarball}[http://download.tangent.org/libmemcached-0.15.tar.gz]. Then for Linux, run:
|
28
28
|
./configure
|
@@ -35,6 +35,9 @@ For OS X/MacPorts, run:
|
|
35
35
|
Now install the gem:
|
36
36
|
sudo gem install memcached --no-rdoc --no-ri
|
37
37
|
|
38
|
+
Note that on OS X 10.5 you may need to set the architecture explicitly:
|
39
|
+
sudo env ARCHFLAGS="-arch i386" gem install memcached --no-rdoc --no-ri
|
40
|
+
|
38
41
|
== Usage
|
39
42
|
|
40
43
|
Start a local memcached server:
|
@@ -62,7 +65,9 @@ You can get multiple values at once:
|
|
62
65
|
|
63
66
|
value = 'hello'
|
64
67
|
$cache.set 'test', value
|
65
|
-
$cache.
|
68
|
+
$cache.set 'test2', value
|
69
|
+
$cache.get ['test', 'test2', 'missing']
|
70
|
+
#=> {"test" => "hello", "test2" => "hello"}
|
66
71
|
|
67
72
|
You can set a counter and increment it:
|
68
73
|
|
data/ext/rlibmemcached.i
CHANGED
@@ -12,11 +12,13 @@
|
|
12
12
|
%include "typemaps.i"
|
13
13
|
|
14
14
|
//// Input maps
|
15
|
+
|
15
16
|
%apply unsigned short { uint8_t };
|
16
17
|
%apply unsigned int { uint16_t };
|
17
18
|
%apply unsigned long { uint32_t flags, uint32_t offset };
|
18
19
|
|
19
20
|
// For behavior's weird set interface
|
21
|
+
|
20
22
|
%typemap(in) (void *data) {
|
21
23
|
int value = FIX2INT($input);
|
22
24
|
if (value == 0 || value == 1) {
|
@@ -29,6 +31,7 @@
|
|
29
31
|
};
|
30
32
|
|
31
33
|
// Array of strings map for multiget
|
34
|
+
|
32
35
|
%typemap(in) (char **keys, size_t *key_length, unsigned int number_of_keys) {
|
33
36
|
int i;
|
34
37
|
Check_Type($input, T_ARRAY);
|
@@ -46,23 +49,27 @@
|
|
46
49
|
}
|
47
50
|
|
48
51
|
// Generic strings
|
52
|
+
|
49
53
|
%typemap(in) (char *str, size_t len) {
|
50
54
|
$1 = STR2CSTR($input);
|
51
55
|
$2 = (size_t) RSTRING($input)->len;
|
52
56
|
};
|
53
57
|
|
54
58
|
%apply (char *str, size_t len) {
|
59
|
+
(char *namespace, size_t namespace_length),
|
55
60
|
(char *key, size_t key_length),
|
56
61
|
(char *value, size_t value_length)
|
57
62
|
};
|
58
63
|
|
59
64
|
//// Output maps
|
65
|
+
|
60
66
|
%apply unsigned short *OUTPUT {memcached_return *error}
|
61
67
|
%apply unsigned int *OUTPUT {uint32_t *flags}
|
62
68
|
%apply size_t *OUTPUT {size_t *value_length}
|
63
69
|
%apply unsigned long long *OUTPUT {uint64_t *value}
|
64
70
|
|
65
71
|
// String
|
72
|
+
|
66
73
|
%typemap(in, numinputs=0) (char *key, size_t *key_length) {
|
67
74
|
$1 = malloc(512*sizeof(char));
|
68
75
|
$2 = malloc(sizeof(size_t)); // XXX Could possibly be the address of a local
|
@@ -76,6 +83,7 @@
|
|
76
83
|
}
|
77
84
|
|
78
85
|
// Array of strings
|
86
|
+
|
79
87
|
%typemap(out) (char **) {
|
80
88
|
int i;
|
81
89
|
VALUE ary = rb_ary_new();
|
@@ -90,7 +98,33 @@
|
|
90
98
|
|
91
99
|
%include "/opt/local/include/libmemcached/memcached.h"
|
92
100
|
|
93
|
-
|
101
|
+
//// Custom C functions
|
102
|
+
|
103
|
+
// Namespace and validate key. We could avoid several more dispatches and allocations if we called this from the libmemcached wrappers directly.
|
104
|
+
|
105
|
+
VALUE ns(char *namespace, size_t namespace_length, char *key, size_t key_length);
|
106
|
+
%{
|
107
|
+
VALUE ns(char *namespace, size_t namespace_length, char *key, size_t key_length) {
|
108
|
+
char namespaced_key[250];
|
109
|
+
size_t namespaced_key_length = namespace_length + key_length;
|
110
|
+
|
111
|
+
if (namespaced_key_length > 250)
|
112
|
+
namespaced_key_length = 250;
|
113
|
+
|
114
|
+
strncpy(namespaced_key, namespace, namespace_length);
|
115
|
+
strncpy(namespaced_key + namespace_length, key, namespaced_key_length - namespace_length);
|
116
|
+
|
117
|
+
int i;
|
118
|
+
for (i = 0; i < namespaced_key_length; i++)
|
119
|
+
if ((namespaced_key[i] < 33) || (namespaced_key[i] > 126))
|
120
|
+
// Outside printable range
|
121
|
+
namespaced_key[i] = '_';
|
122
|
+
|
123
|
+
return rb_str_new(namespaced_key, namespaced_key_length);
|
124
|
+
};
|
125
|
+
%}
|
126
|
+
|
127
|
+
//// Manual wrappers
|
94
128
|
|
95
129
|
// Single get. SWIG likes to use SWIG_FromCharPtr instead of SWIG_FromCharPtrAndSize because
|
96
130
|
// of the retval/argout split, so it truncates return values with \0 in them.
|
data/ext/rlibmemcached_wrap.c
CHANGED
@@ -1869,6 +1869,26 @@ SWIG_From_unsigned_SS_long_SS_long (unsigned long long value)
|
|
1869
1869
|
}
|
1870
1870
|
|
1871
1871
|
|
1872
|
+
VALUE ns(char *namespace, size_t namespace_length, char *key, size_t key_length) {
|
1873
|
+
char namespaced_key[250];
|
1874
|
+
size_t namespaced_key_length = namespace_length + key_length;
|
1875
|
+
|
1876
|
+
if (namespaced_key_length > 250)
|
1877
|
+
namespaced_key_length = 250;
|
1878
|
+
|
1879
|
+
strncpy(namespaced_key, namespace, namespace_length);
|
1880
|
+
strncpy(namespaced_key + namespace_length, key, namespaced_key_length - namespace_length);
|
1881
|
+
|
1882
|
+
int i;
|
1883
|
+
for (i = 0; i < namespaced_key_length; i++)
|
1884
|
+
if ((namespaced_key[i] < 33) || (namespaced_key[i] > 126))
|
1885
|
+
// Outside printable range
|
1886
|
+
namespaced_key[i] = '_';
|
1887
|
+
|
1888
|
+
return rb_str_new(namespaced_key, namespaced_key_length);
|
1889
|
+
};
|
1890
|
+
|
1891
|
+
|
1872
1892
|
VALUE memcached_get_rvalue(memcached_st *ptr, char *key, size_t key_length, uint32_t *flags, memcached_return *error) {
|
1873
1893
|
VALUE ret;
|
1874
1894
|
size_t value_length;
|
@@ -8691,6 +8711,34 @@ fail:
|
|
8691
8711
|
}
|
8692
8712
|
|
8693
8713
|
|
8714
|
+
SWIGINTERN VALUE
|
8715
|
+
_wrap_ns(int argc, VALUE *argv, VALUE self) {
|
8716
|
+
char *arg1 = (char *) 0 ;
|
8717
|
+
size_t arg2 ;
|
8718
|
+
char *arg3 = (char *) 0 ;
|
8719
|
+
size_t arg4 ;
|
8720
|
+
VALUE result;
|
8721
|
+
VALUE vresult = Qnil;
|
8722
|
+
|
8723
|
+
if ((argc < 2) || (argc > 2)) {
|
8724
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)",argc); SWIG_fail;
|
8725
|
+
}
|
8726
|
+
{
|
8727
|
+
arg1 = STR2CSTR(argv[0]);
|
8728
|
+
arg2 = (size_t) RSTRING(argv[0])->len;
|
8729
|
+
}
|
8730
|
+
{
|
8731
|
+
arg3 = STR2CSTR(argv[1]);
|
8732
|
+
arg4 = (size_t) RSTRING(argv[1])->len;
|
8733
|
+
}
|
8734
|
+
result = (VALUE)ns(arg1,arg2,arg3,arg4);
|
8735
|
+
vresult = result;
|
8736
|
+
return vresult;
|
8737
|
+
fail:
|
8738
|
+
return Qnil;
|
8739
|
+
}
|
8740
|
+
|
8741
|
+
|
8694
8742
|
SWIGINTERN VALUE
|
8695
8743
|
_wrap_memcached_get_rvalue(int argc, VALUE *argv, VALUE self) {
|
8696
8744
|
memcached_st *arg1 = (memcached_st *) 0 ;
|
@@ -9595,6 +9643,7 @@ SWIGEXPORT void Init_rlibmemcached(void) {
|
|
9595
9643
|
rb_define_module_function(mRlibmemcached, "memcached_result_create", _wrap_memcached_result_create, -1);
|
9596
9644
|
rb_define_module_function(mRlibmemcached, "memcached_result_value", _wrap_memcached_result_value, -1);
|
9597
9645
|
rb_define_module_function(mRlibmemcached, "memcached_result_length", _wrap_memcached_result_length, -1);
|
9646
|
+
rb_define_module_function(mRlibmemcached, "ns", _wrap_ns, -1);
|
9598
9647
|
rb_define_module_function(mRlibmemcached, "memcached_get_rvalue", _wrap_memcached_get_rvalue, -1);
|
9599
9648
|
rb_define_module_function(mRlibmemcached, "memcached_fetch_rvalue", _wrap_memcached_fetch_rvalue, -1);
|
9600
9649
|
rb_define_module_function(mRlibmemcached, "memcached_stat_get_rvalue", _wrap_memcached_stat_get_rvalue, -1);
|
data/lib/memcached/memcached.rb
CHANGED
@@ -19,6 +19,8 @@ class Memcached
|
|
19
19
|
#:stopdoc:
|
20
20
|
IGNORED = 0
|
21
21
|
|
22
|
+
Lib = Rlibmemcached
|
23
|
+
|
22
24
|
NOTFOUND_INSTANCE = NotFound.new
|
23
25
|
#:startdoc:
|
24
26
|
|
@@ -46,8 +48,8 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
46
48
|
=end
|
47
49
|
|
48
50
|
def initialize(servers, opts = {})
|
49
|
-
@struct =
|
50
|
-
|
51
|
+
@struct = Lib::MemcachedSt.new
|
52
|
+
Lib.memcached_create(@struct)
|
51
53
|
|
52
54
|
# Servers
|
53
55
|
Array(servers).each_with_index do |server, index|
|
@@ -55,7 +57,7 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
55
57
|
raise ArgumentError, "Servers must be in the format ip:port (e.g., '127.0.0.1:11211')"
|
56
58
|
end
|
57
59
|
host, port = server.split(":")
|
58
|
-
|
60
|
+
Lib.memcached_server_add(@struct, host, port.to_i)
|
59
61
|
end
|
60
62
|
|
61
63
|
# Behaviors
|
@@ -90,7 +92,7 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
90
92
|
#
|
91
93
|
def clone
|
92
94
|
memcached = super
|
93
|
-
memcached.instance_variable_set('@struct',
|
95
|
+
memcached.instance_variable_set('@struct', Lib.memcached_clone(nil, @struct))
|
94
96
|
memcached
|
95
97
|
end
|
96
98
|
|
@@ -100,7 +102,7 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
100
102
|
# runs much faster, but your instance will segfault if you try to call any other methods on it
|
101
103
|
# after destroy. Defaults to <tt>true</tt>, which safely overwrites all instance methods.
|
102
104
|
def destroy(disable_methods = true)
|
103
|
-
|
105
|
+
Lib.memcached_free(@struct)
|
104
106
|
@struct = nil
|
105
107
|
if disable_methods
|
106
108
|
class << self
|
@@ -115,8 +117,8 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
115
117
|
|
116
118
|
# Reset the state of the libmemcached struct. Fixes out-of-sync errors with the Memcached pool.
|
117
119
|
def reset
|
118
|
-
new_struct =
|
119
|
-
|
120
|
+
new_struct = Lib.memcached_clone(nil, @struct)
|
121
|
+
Lib.memcached_free(@struct)
|
120
122
|
@struct = new_struct
|
121
123
|
end
|
122
124
|
|
@@ -132,7 +134,7 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
132
134
|
def server_structs
|
133
135
|
array = []
|
134
136
|
@struct.hosts.count.times do |i|
|
135
|
-
array <<
|
137
|
+
array << Lib.memcached_select_server_at(@struct, i)
|
136
138
|
end
|
137
139
|
array
|
138
140
|
end
|
@@ -152,7 +154,7 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
152
154
|
def set(key, value, timeout=0, marshal=true)
|
153
155
|
value = marshal ? Marshal.dump(value) : value.to_s
|
154
156
|
check_return_code(
|
155
|
-
|
157
|
+
Lib.memcached_set(@struct, Lib.ns(@namespace, key), value, timeout, FLAGS)
|
156
158
|
)
|
157
159
|
end
|
158
160
|
|
@@ -160,7 +162,7 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
160
162
|
def add(key, value, timeout=0, marshal=true)
|
161
163
|
value = marshal ? Marshal.dump(value) : value.to_s
|
162
164
|
check_return_code(
|
163
|
-
|
165
|
+
Lib.memcached_add(@struct, Lib.ns(@namespace, key), value, timeout, FLAGS)
|
164
166
|
)
|
165
167
|
end
|
166
168
|
|
@@ -170,14 +172,14 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
170
172
|
#
|
171
173
|
# Note that the key must be initialized to an unmarshalled integer first, via <tt>set</tt>, <tt>add</tt>, or <tt>replace</tt> with <tt>marshal</tt> set to <tt>false</tt>.
|
172
174
|
def increment(key, offset=1)
|
173
|
-
ret, value =
|
175
|
+
ret, value = Lib.memcached_increment(@struct, Lib.ns(@namespace, key), offset)
|
174
176
|
check_return_code(ret)
|
175
177
|
value
|
176
178
|
end
|
177
179
|
|
178
180
|
# Decrement a key's value. The parameters and exception behavior are the same as <tt>increment</tt>.
|
179
181
|
def decrement(key, offset=1)
|
180
|
-
ret, value =
|
182
|
+
ret, value = Lib.memcached_decrement(@struct, Lib.ns(@namespace, key), offset)
|
181
183
|
check_return_code(ret)
|
182
184
|
value
|
183
185
|
end
|
@@ -191,7 +193,7 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
191
193
|
def replace(key, value, timeout=0, marshal=true)
|
192
194
|
value = marshal ? Marshal.dump(value) : value.to_s
|
193
195
|
check_return_code(
|
194
|
-
|
196
|
+
Lib.memcached_replace(@struct, Lib.ns(@namespace, key), value, timeout, FLAGS)
|
195
197
|
)
|
196
198
|
end
|
197
199
|
|
@@ -201,7 +203,7 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
201
203
|
def append(key, value)
|
202
204
|
# Requires memcached 1.2.4
|
203
205
|
check_return_code(
|
204
|
-
|
206
|
+
Lib.memcached_append(@struct, Lib.ns(@namespace, key), value.to_s, IGNORED, FLAGS)
|
205
207
|
)
|
206
208
|
end
|
207
209
|
|
@@ -209,7 +211,7 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
209
211
|
def prepend(key, value)
|
210
212
|
# Requires memcached 1.2.4
|
211
213
|
check_return_code(
|
212
|
-
|
214
|
+
Lib.memcached_prepend(@struct, Lib.ns(@namespace, key), value.to_s, IGNORED, FLAGS)
|
213
215
|
)
|
214
216
|
end
|
215
217
|
|
@@ -231,7 +233,7 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
231
233
|
# Deletes a key/value pair from the server. Accepts a String <tt>key</tt>. Raises <b>Memcached::NotFound</b> if the key does not exist.
|
232
234
|
def delete(key)
|
233
235
|
check_return_code(
|
234
|
-
|
236
|
+
Lib.memcached_delete(@struct, Lib.ns(@namespace, key), IGNORED)
|
235
237
|
)
|
236
238
|
end
|
237
239
|
|
@@ -250,14 +252,14 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
250
252
|
def get(keys, marshal=true)
|
251
253
|
if keys.is_a? Array
|
252
254
|
# Multi get
|
253
|
-
keys.map! { |key| ns(key) }
|
255
|
+
keys.map! { |key| Lib.ns(@namespace, key) }
|
254
256
|
hash = {}
|
255
257
|
|
256
|
-
|
258
|
+
Lib.memcached_mget(@struct, keys);
|
257
259
|
|
258
260
|
keys.size.times do
|
259
|
-
value, key, flags, ret =
|
260
|
-
break if ret ==
|
261
|
+
value, key, flags, ret = Lib.memcached_fetch_rvalue(@struct)
|
262
|
+
break if ret == Lib::MEMCACHED_END
|
261
263
|
check_return_code(ret)
|
262
264
|
value = Marshal.load(value) if marshal
|
263
265
|
# Assign the value, removing the namespace, if present
|
@@ -266,7 +268,7 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
266
268
|
hash
|
267
269
|
else
|
268
270
|
# Single get
|
269
|
-
value, flags, ret =
|
271
|
+
value, flags, ret = Lib.memcached_get_rvalue(@struct, Lib.ns(@namespace, keys))
|
270
272
|
check_return_code(ret)
|
271
273
|
value = Marshal.load(value) if marshal
|
272
274
|
value
|
@@ -279,18 +281,18 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
279
281
|
def stats
|
280
282
|
stats = Hash.new([])
|
281
283
|
|
282
|
-
stat_struct, ret =
|
284
|
+
stat_struct, ret = Lib.memcached_stat(@struct, "")
|
283
285
|
check_return_code(ret)
|
284
286
|
|
285
|
-
keys, ret =
|
287
|
+
keys, ret = Lib.memcached_stat_get_keys(@struct, stat_struct)
|
286
288
|
check_return_code(ret)
|
287
289
|
|
288
290
|
keys.each do |key|
|
289
291
|
server_structs.size.times do |index|
|
290
292
|
|
291
|
-
value, ret =
|
293
|
+
value, ret = Lib.memcached_stat_get_rvalue(
|
292
294
|
@struct,
|
293
|
-
|
295
|
+
Lib.memcached_select_stat_at(@struct, stat_struct, index),
|
294
296
|
key)
|
295
297
|
check_return_code(ret)
|
296
298
|
|
@@ -304,19 +306,13 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
304
306
|
end
|
305
307
|
end
|
306
308
|
|
307
|
-
|
309
|
+
Lib.memcached_stat_free(@struct, stat_struct)
|
308
310
|
stats
|
309
311
|
end
|
310
312
|
|
311
313
|
### Operations helpers
|
312
314
|
|
313
315
|
private
|
314
|
-
|
315
|
-
# Return a namespaced key for this Memcached instance. Accepts a String <tt>key</tt> value.
|
316
|
-
def ns(key) #:doc:
|
317
|
-
# raise ClientError, "Invalid key" if key =~ /\s/ # XXX Slow
|
318
|
-
"#{@namespace}#{key}"
|
319
|
-
end
|
320
316
|
|
321
317
|
# Checks the return code from Rlibmemcached against the exception list. Raises the corresponding exception if the return code is not Memcached::Success or Memcached::ActionQueued. Accepts an integer return code.
|
322
318
|
def check_return_code(ret) #:doc:
|
data/lib/memcached/rails.rb
CHANGED
@@ -4,10 +4,6 @@ class Memcached
|
|
4
4
|
alias :get_multi :get #:nodoc:
|
5
5
|
|
6
6
|
# A legacy compatibility wrapper for the Memcached class. It has basic compatibility with the <b>memcache-client</b> API.
|
7
|
-
#
|
8
|
-
# There is currently a libmemcached stability issue with long-lived instances, so you will want to call Memcached#reset before each
|
9
|
-
# request (for example, in an ActionController filter).
|
10
|
-
#
|
11
7
|
class Rails < ::Memcached
|
12
8
|
|
13
9
|
DEFAULTS = {}
|
data/memcached.gemspec
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
|
2
|
-
# Gem::Specification for Memcached-0.7.
|
2
|
+
# Gem::Specification for Memcached-0.7.2
|
3
3
|
# Originally generated by Echoe
|
4
4
|
|
5
5
|
Gem::Specification.new do |s|
|
6
6
|
s.name = %q{memcached}
|
7
|
-
s.version = "0.7.
|
7
|
+
s.version = "0.7.2"
|
8
8
|
|
9
9
|
s.specification_version = 2 if s.respond_to? :specification_version=
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.authors = ["Evan Weaver"]
|
13
|
-
s.date = %q{2008-02-
|
13
|
+
s.date = %q{2008-02-10}
|
14
14
|
s.description = %q{An interface to the libmemcached C client.}
|
15
15
|
s.email = %q{}
|
16
16
|
s.extensions = ["ext/extconf.rb"]
|
17
|
-
s.files = ["BENCHMARKS", "CHANGELOG", "COMPATIBILITY", "ext/extconf.rb", "ext/rlibmemcached.i", "ext/rlibmemcached_wrap.c", "lib/memcached/behaviors.rb", "lib/memcached/exceptions.rb", "lib/memcached/integer.rb", "lib/memcached/memcached.rb", "lib/memcached/rails.rb", "lib/memcached.rb", "LICENSE", "Manifest", "README", "test/profile/benchmark.rb", "test/profile/profile.rb", "test/profile/valgrind.rb", "test/setup.rb", "test/teardown.rb", "test/test_helper.rb", "test/unit/binding_test.rb", "test/unit/memcached_test.rb", "test/unit/rails_test.rb", "TODO", "memcached.gemspec"]
|
17
|
+
s.files = ["BENCHMARKS", "CHANGELOG", "COMPATIBILITY", "ext/extconf.rb", "ext/rlibmemcached.i", "ext/rlibmemcached_wrap.c", "lib/memcached/behaviors.rb", "lib/memcached/exceptions.rb", "lib/memcached/integer.rb", "lib/memcached/memcached.rb", "lib/memcached/rails.rb", "lib/memcached.rb", "LICENSE", "Manifest", "README", "test/profile/benchmark.rb", "test/profile/key.rb", "test/profile/profile.rb", "test/profile/valgrind.rb", "test/setup.rb", "test/teardown.rb", "test/test_helper.rb", "test/unit/binding_test.rb", "test/unit/memcached_test.rb", "test/unit/rails_test.rb", "TODO", "memcached.gemspec"]
|
18
18
|
s.has_rdoc = true
|
19
19
|
s.homepage = %q{http://blog.evanweaver.com/files/doc/fauna/memcached/}
|
20
20
|
s.require_paths = ["lib", "ext"]
|
data/test/profile/key.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
HERE = File.dirname(__FILE__)
|
3
|
+
$LOAD_PATH << "#{HERE}/../../lib/"
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'memcached'
|
7
|
+
require 'ruby-prof'
|
8
|
+
require 'benchmark'
|
9
|
+
|
10
|
+
KEYS = ["ch\303\242teau"*10, "long"*100, "spaces space spaces", "null \000"]
|
11
|
+
|
12
|
+
@namespace = "benchmark_namespace"
|
13
|
+
@cache = Memcached.new(
|
14
|
+
['127.0.0.1:43042', '127.0.0.1:43043'],
|
15
|
+
:namespace => @namespace
|
16
|
+
)
|
17
|
+
|
18
|
+
def dispatch(n, k)
|
19
|
+
Rlibmemcached.ns(@namespace, key)
|
20
|
+
end
|
21
|
+
|
22
|
+
#result = RubyProf.profile do
|
23
|
+
Benchmark.bm(15) do |x|
|
24
|
+
x.report("direct") do
|
25
|
+
KEYS.each do |key|
|
26
|
+
10000.times do
|
27
|
+
Rlibmemcached.ns(@namespace, key)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
x.report("dispatch") do
|
32
|
+
KEYS.each do |key|
|
33
|
+
10000.times do
|
34
|
+
Rlibmemcached.ns(@namespace, key)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
#printer = RubyProf::GraphPrinter.new(result)
|
41
|
+
#printer.print(STDOUT, 0)
|
data/test/profile/profile.rb
CHANGED
data/test/unit/memcached_test.rb
CHANGED
@@ -22,6 +22,12 @@ class MemcachedTest < Test::Unit::TestCase
|
|
22
22
|
@marshalled_value = Marshal.dump(@value)
|
23
23
|
end
|
24
24
|
|
25
|
+
def teardown
|
26
|
+
ObjectSpace.each_object(Memcached) do |cache|
|
27
|
+
cache.destroy rescue Memcached::ClientError
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
25
31
|
# Initialize
|
26
32
|
|
27
33
|
def test_initialize
|
@@ -49,9 +55,9 @@ class MemcachedTest < Test::Unit::TestCase
|
|
49
55
|
|
50
56
|
def test_initialize_with_missing_server
|
51
57
|
# XXX Triggers abort trap with libmemcached --enable-debug.
|
52
|
-
|
58
|
+
cache = Memcached.new "127.0.0.1:43044"
|
53
59
|
assert_raises Memcached::SystemError do
|
54
|
-
|
60
|
+
cache.get key
|
55
61
|
end
|
56
62
|
end
|
57
63
|
|
@@ -121,19 +127,6 @@ class MemcachedTest < Test::Unit::TestCase
|
|
121
127
|
assert result.size > non_wrapped_result.size
|
122
128
|
end
|
123
129
|
|
124
|
-
def test_get_invalid_key
|
125
|
-
assert_raise(Memcached::ClientError) { @cache.get(key * 100) }
|
126
|
-
# XXX Trying to get Krow to change this to ProtocolError
|
127
|
-
assert_raise(Memcached::NotFound) { @cache.get "I'm so bad" }
|
128
|
-
end
|
129
|
-
|
130
|
-
def test_get_multi_invalid_key
|
131
|
-
assert_raise(Memcached::ClientError) { @cache.get([key * 100]) }
|
132
|
-
# XXX Trying to get Krow to change this to ProtocolError
|
133
|
-
assert_equal({},
|
134
|
-
@cache.get(["I'm so bad"]))
|
135
|
-
end
|
136
|
-
|
137
130
|
def test_get_multi
|
138
131
|
@cache.set "#{key}_1", 1
|
139
132
|
@cache.set "#{key}_2", 2
|
@@ -185,13 +178,7 @@ class MemcachedTest < Test::Unit::TestCase
|
|
185
178
|
@cache.set(key, @value)
|
186
179
|
end
|
187
180
|
end
|
188
|
-
|
189
|
-
def test_set_invalid_key
|
190
|
-
assert_raise(Memcached::ProtocolError) do
|
191
|
-
@cache.set "I'm so bad", @value
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
181
|
+
|
195
182
|
def test_set_expiry
|
196
183
|
@cache.set key, @value, 1
|
197
184
|
assert_nothing_raised do
|
@@ -202,12 +189,6 @@ class MemcachedTest < Test::Unit::TestCase
|
|
202
189
|
@cache.get key
|
203
190
|
end
|
204
191
|
end
|
205
|
-
|
206
|
-
def test_set_object_too_large
|
207
|
-
assert_raise(Memcached::ServerError) do
|
208
|
-
@cache.set key, "I'm big" * 1000000
|
209
|
-
end
|
210
|
-
end
|
211
192
|
|
212
193
|
# Delete
|
213
194
|
|
@@ -362,6 +343,85 @@ class MemcachedTest < Test::Unit::TestCase
|
|
362
343
|
end
|
363
344
|
end
|
364
345
|
|
346
|
+
# Namespace and key validation
|
347
|
+
|
348
|
+
def test_ns
|
349
|
+
assert_equal "#{@namespace}i_have_a_space",
|
350
|
+
Rlibmemcached.ns(@namespace, "i have a space")
|
351
|
+
|
352
|
+
# STR2CSTR doesn't handle strings with nulls very well, so this is what happens
|
353
|
+
assert_equal "#{@namespace}with_____",
|
354
|
+
Rlibmemcached.ns(@namespace, "with\000null")
|
355
|
+
|
356
|
+
assert_equal "#{@namespace}ch__teau",
|
357
|
+
Rlibmemcached.ns(@namespace, "ch\303\242teau")
|
358
|
+
|
359
|
+
assert_equal "#{@namespace}#{'x'*251}"[0..249],
|
360
|
+
Rlibmemcached.ns(@namespace, 'x'*251)
|
361
|
+
end
|
362
|
+
|
363
|
+
# Error states
|
364
|
+
|
365
|
+
def test_key_with_spaces
|
366
|
+
value = "value"
|
367
|
+
key = "i have a space"
|
368
|
+
assert_nothing_raised do
|
369
|
+
@cache.set key, value
|
370
|
+
end
|
371
|
+
assert_nothing_raised do
|
372
|
+
assert_equal(value, @cache.get(key))
|
373
|
+
end
|
374
|
+
# Spaces were stripped
|
375
|
+
assert_not_equal(key,
|
376
|
+
@cache.get([key]).keys.first)
|
377
|
+
end
|
378
|
+
|
379
|
+
def test_key_with_null
|
380
|
+
value = "value"
|
381
|
+
key = "with\000null"
|
382
|
+
assert_nothing_raised do
|
383
|
+
@cache.set key, value
|
384
|
+
end
|
385
|
+
assert_nothing_raised do
|
386
|
+
assert_equal(value, @cache.get(key))
|
387
|
+
end
|
388
|
+
# Multiget returns
|
389
|
+
response = @cache.get([key])
|
390
|
+
assert_equal 1, response.size
|
391
|
+
# Nulls were stripped
|
392
|
+
assert_not_equal(key, response.keys.first)
|
393
|
+
end
|
394
|
+
|
395
|
+
def test_key_with_valid_control_characters
|
396
|
+
value = "value"
|
397
|
+
key = "ch\303\242teau"
|
398
|
+
@cache.set key, value
|
399
|
+
assert_equal(value,
|
400
|
+
@cache.get(key))
|
401
|
+
assert_not_equal(key,
|
402
|
+
@cache.get([key]).keys.first)
|
403
|
+
end
|
404
|
+
|
405
|
+
def test_key_too_long
|
406
|
+
key = "x"*251
|
407
|
+
assert_nothing_raised do
|
408
|
+
@cache.set key, @value
|
409
|
+
end
|
410
|
+
assert_nothing_raised do
|
411
|
+
assert_equal(@value,
|
412
|
+
@cache.get(key))
|
413
|
+
end
|
414
|
+
# Key was truncated
|
415
|
+
assert_not_equal(key,
|
416
|
+
@cache.get([key]).keys.first)
|
417
|
+
end
|
418
|
+
|
419
|
+
def test_set_object_too_large
|
420
|
+
assert_raise(Memcached::ServerError) do
|
421
|
+
@cache.set key, "I'm big" * 1000000
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
365
425
|
# Stats
|
366
426
|
|
367
427
|
def test_stats
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: memcached
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Weaver
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
yZ0=
|
31
31
|
-----END CERTIFICATE-----
|
32
32
|
|
33
|
-
date: 2008-02-
|
33
|
+
date: 2008-02-10 00:00:00 -05:00
|
34
34
|
default_executable:
|
35
35
|
dependencies: []
|
36
36
|
|
@@ -59,6 +59,7 @@ files:
|
|
59
59
|
- Manifest
|
60
60
|
- README
|
61
61
|
- test/profile/benchmark.rb
|
62
|
+
- test/profile/key.rb
|
62
63
|
- test/profile/profile.rb
|
63
64
|
- test/profile/valgrind.rb
|
64
65
|
- test/setup.rb
|
metadata.gz.sig
CHANGED
@@ -1 +1,2 @@
|
|
1
|
-
|
1
|
+
w��/o�+i�&� A=\����WA�:]�&��_@� ��;
|
2
|
+
�.\�6���<3�'��@�sZ����c%)�y�c��;�0���ێ�<F��嗯����i�%���w�1��Zl���cNk�:.� ���nWO '�n[�$�1����G��{\.
|