memcached 0.7.1 → 0.7.2
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.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��{\.
|