memcached 0.7.2 → 0.8
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/BENCHMARKS +53 -82
- data/CHANGELOG +2 -0
- data/COMPATIBILITY +1 -1
- data/README +4 -5
- data/TODO +0 -2
- data/ext/rlibmemcached.i +11 -19
- data/ext/rlibmemcached_wrap.c +27 -36
- data/lib/memcached.rb +13 -8
- data/lib/memcached/behaviors.rb +4 -4
- data/lib/memcached/exceptions.rb +2 -1
- data/lib/memcached/memcached.rb +21 -13
- data/memcached.gemspec +3 -3
- data/test/unit/memcached_test.rb +64 -3
- metadata +2 -2
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/BENCHMARKS
CHANGED
@@ -10,34 +10,34 @@ You can easily run your own benchmarks, as long as you have memcached itself on
|
|
10
10
|
These benchmarks were run on 32-bit Intel OS X 10.4:
|
11
11
|
|
12
12
|
user system total real
|
13
|
-
set:plain:noblock:memcached 0.
|
14
|
-
set:plain:memcached 0.
|
15
|
-
set:plain:memcache-client
|
16
|
-
set:ruby:noblock:memcached 0.
|
17
|
-
set:ruby:memcached 0.
|
18
|
-
set:ruby:caffeine
|
19
|
-
set:ruby:memcache-client 47.
|
20
|
-
get:plain:memcached 0.
|
21
|
-
get:plain:memcache-client 47.
|
22
|
-
get:ruby:memcached 0.
|
23
|
-
get:ruby:caffeine 5.
|
24
|
-
get:ruby:memcache-client 47.
|
25
|
-
missing:ruby:memcached 0.
|
26
|
-
missing:ruby:caffeine 5.
|
27
|
-
missing:ruby:memcache-client
|
28
|
-
mixed:ruby:noblock:memcached 0.
|
29
|
-
mixed:ruby:memcached 0.
|
30
|
-
mixed:ruby:caffeine
|
31
|
-
mixed:ruby:memcache-client
|
32
|
-
hash:
|
33
|
-
hash:
|
34
|
-
hash:
|
35
|
-
hash:
|
36
|
-
hash:
|
37
|
-
hash:
|
38
|
-
hash:
|
39
|
-
hash:
|
40
|
-
hash:
|
13
|
+
set:plain:noblock:memcached 0.110000 0.020000 0.130000 ( 0.306181)
|
14
|
+
set:plain:memcached 0.260000 0.330000 0.590000 ( 1.332132)
|
15
|
+
set:plain:memcache-client 46.830000 0.640000 47.470000 ( 49.439137)
|
16
|
+
set:ruby:noblock:memcached 0.190000 0.020000 0.210000 ( 0.344947)
|
17
|
+
set:ruby:memcached 0.360000 0.340000 0.700000 ( 1.502977)
|
18
|
+
set:ruby:caffeine 5.480000 0.890000 6.370000 ( 7.224237)
|
19
|
+
set:ruby:memcache-client 47.460000 0.630000 48.090000 ( 50.113758)
|
20
|
+
get:plain:memcached 0.340000 0.340000 0.680000 ( 1.346579)
|
21
|
+
get:plain:memcache-client 47.480000 0.600000 48.080000 ( 49.662450)
|
22
|
+
get:ruby:memcached 0.400000 0.350000 0.750000 ( 1.464317)
|
23
|
+
get:ruby:caffeine 5.410000 0.900000 6.310000 ( 7.142927)
|
24
|
+
get:ruby:memcache-client 47.600000 0.720000 48.320000 ( 51.090209)
|
25
|
+
missing:ruby:memcached 0.750000 0.380000 1.130000 ( 1.786494)
|
26
|
+
missing:ruby:caffeine 5.130000 0.870000 6.000000 ( 6.854605)
|
27
|
+
missing:ruby:memcache-client 46.870000 0.610000 47.480000 ( 49.318730)
|
28
|
+
mixed:ruby:noblock:memcached 0.740000 0.840000 1.580000 ( 2.747368)
|
29
|
+
mixed:ruby:memcached 0.740000 0.680000 1.420000 ( 2.825775)
|
30
|
+
mixed:ruby:caffeine 9.670000 1.770000 11.440000 ( 13.203683)
|
31
|
+
mixed:ruby:memcache-client 94.910000 1.380000 96.290000 (101.312885)
|
32
|
+
hash:fnv1a_64:memcached 1.170000 1.360000 2.530000 ( 5.374056)
|
33
|
+
hash:crc:memcached 1.160000 1.330000 2.490000 ( 5.422227)
|
34
|
+
hash:fnv1_32:memcached 1.150000 1.350000 2.500000 ( 5.356032)
|
35
|
+
hash:fnv1_64:memcached 1.200000 1.370000 2.570000 ( 5.487689)
|
36
|
+
hash:default:memcached 1.160000 1.360000 2.520000 ( 5.506072)
|
37
|
+
hash:md5:memcached 1.240000 1.320000 2.560000 ( 5.930740)
|
38
|
+
hash:hsieh:memcached 1.150000 1.370000 2.520000 ( 5.505223)
|
39
|
+
hash:ketama:memcached 1.230000 1.340000 2.570000 ( 5.759874)
|
40
|
+
hash:fnv1a_32:memcached 1.150000 1.360000 2.510000 ( 5.562683)
|
41
41
|
|
42
42
|
|
43
43
|
== x86-64 Linux
|
@@ -45,57 +45,28 @@ These benchmarks were run on 32-bit Intel OS X 10.4:
|
|
45
45
|
These benchmarks were run on AMD64 RHEL4:
|
46
46
|
|
47
47
|
user system total real
|
48
|
-
set:plain:noblock:memcached 0.
|
49
|
-
set:plain:memcached 0.
|
50
|
-
set:plain:memcache-client 13.
|
51
|
-
set:ruby:noblock:memcached 0.
|
52
|
-
set:ruby:memcached 0.
|
53
|
-
set:ruby:memcache-client 13.
|
54
|
-
get:plain:memcached 0.
|
55
|
-
get:plain:memcache-client 14.
|
56
|
-
get:ruby:memcached 0.
|
57
|
-
get:ruby:memcache-client 14.
|
58
|
-
missing:ruby:memcached 0.
|
59
|
-
missing:ruby:memcache-client 13.
|
60
|
-
mixed:ruby:noblock:memcached 0.
|
61
|
-
mixed:ruby:memcached 0.
|
62
|
-
mixed:ruby:memcache-client 27.
|
63
|
-
hash:
|
64
|
-
hash:fnv1_32:memcached 0.
|
65
|
-
hash:fnv1_64:memcached 0.
|
66
|
-
hash:default:memcached
|
67
|
-
hash:
|
68
|
-
hash:
|
69
|
-
hash:
|
70
|
-
hash:
|
71
|
-
hash:
|
72
|
-
|
73
|
-
== x86-64 Linux/Xen
|
74
|
-
|
75
|
-
These benchmarks were run on AMD64 Ubuntu 6.0.6 as a Xen guest:
|
76
|
-
|
77
|
-
user system total real
|
78
|
-
set:plain:noblock:memcached 0.090000 0.100000 0.190000 ( 0.767657)
|
79
|
-
set:plain:memcached 0.120000 0.200000 0.320000 ( 1.480487)
|
80
|
-
set:plain:memcache-client 18.620000 11.380000 30.000000 ( 32.116703)
|
81
|
-
set:ruby:noblock:memcached 0.220000 0.050000 0.270000 ( 0.296509)
|
82
|
-
set:ruby:memcached 0.150000 0.210000 0.360000 ( 1.345469)
|
83
|
-
set:ruby:memcache-client 19.310000 11.750000 31.060000 ( 32.858902)
|
84
|
-
get:plain:memcached 0.120000 0.130000 0.250000 ( 1.291883)
|
85
|
-
get:plain:memcache-client 19.580000 11.930000 31.510000 ( 32.982464)
|
86
|
-
get:ruby:memcached 0.120000 0.160000 0.280000 ( 1.404061)
|
87
|
-
get:ruby:memcache-client 19.520000 11.740000 31.260000 ( 33.537986)
|
88
|
-
missing:ruby:memcached 0.440000 0.240000 0.680000 ( 1.527592)
|
89
|
-
missing:ruby:memcache-client 19.030000 11.760000 30.790000 ( 31.800959)
|
90
|
-
mixed:ruby:noblock:memcached 0.100000 0.080000 0.180000 (100.035915)
|
91
|
-
mixed:ruby:memcached 0.380000 0.380000 0.760000 ( 2.728911)
|
92
|
-
mixed:ruby:memcache-client 38.890000 23.740000 62.630000 ( 66.185559)
|
93
|
-
hash:hsieh:memcached 0.440000 0.680000 1.120000 ( 5.119760)
|
94
|
-
hash:crc:memcached 0.410000 0.810000 1.220000 ( 5.378614)
|
95
|
-
hash:md5:memcached 0.430000 0.710000 1.140000 ( 5.410604)
|
96
|
-
hash:ketama:memcached 0.770000 0.850000 1.620000 ( 5.379337)
|
97
|
-
hash:fnv1a_32:memcached 0.300000 0.650000 0.950000 ( 5.110063)
|
98
|
-
hash:default:memcached 0.220000 0.530000 0.750000 ( 5.183058)
|
99
|
-
hash:fnv1a_64:memcached 0.300000 0.550000 0.850000 ( 5.152530)
|
100
|
-
hash:fnv1_32:memcached 0.360000 0.770000 1.130000 ( 5.150417)
|
101
|
-
hash:fnv1_64:memcached 0.510000 0.650000 1.160000 ( 5.038078)
|
48
|
+
set:plain:noblock:memcached 0.100000 0.010000 0.110000 ( 3.387985)
|
49
|
+
set:plain:memcached 0.160000 0.310000 0.470000 ( 0.744728)
|
50
|
+
set:plain:memcache-client 13.710000 0.110000 13.820000 ( 14.021691)
|
51
|
+
set:ruby:noblock:memcached 0.170000 0.000000 0.170000 ( 3.513274)
|
52
|
+
set:ruby:memcached 0.210000 0.380000 0.590000 ( 0.812180)
|
53
|
+
set:ruby:memcache-client 13.600000 0.220000 13.820000 ( 14.232239)
|
54
|
+
get:plain:memcached 0.150000 0.310000 0.460000 ( 0.747339)
|
55
|
+
get:plain:memcache-client 14.020000 0.290000 14.310000 ( 14.706064)
|
56
|
+
get:ruby:memcached 0.320000 0.250000 0.570000 ( 0.828972)
|
57
|
+
get:ruby:memcache-client 14.050000 0.220000 14.270000 ( 14.648995)
|
58
|
+
missing:ruby:memcached 0.530000 0.280000 0.810000 ( 1.117403)
|
59
|
+
missing:ruby:memcache-client 13.660000 0.200000 13.860000 ( 14.315195)
|
60
|
+
mixed:ruby:noblock:memcached 0.500000 0.490000 0.990000 ( 1.541679)
|
61
|
+
mixed:ruby:memcached 0.470000 0.550000 1.020000 ( 1.691884)
|
62
|
+
mixed:ruby:memcache-client 27.640000 0.480000 28.120000 ( 28.921745)
|
63
|
+
hash:crc:memcached 0.650000 1.200000 1.850000 ( 3.112681)
|
64
|
+
hash:fnv1_32:memcached 0.660000 1.140000 1.800000 ( 2.985026)
|
65
|
+
hash:fnv1_64:memcached 0.630000 1.280000 1.910000 ( 3.027491)
|
66
|
+
hash:default:memcached 0.680000 1.120000 1.800000 ( 2.991388)
|
67
|
+
hash:hsieh:memcached 0.760000 1.220000 1.980000 ( 3.074890)
|
68
|
+
hash:fnv1a_32:memcached 0.680000 1.190000 1.870000 ( 2.996147)
|
69
|
+
hash:md5:memcached 0.650000 1.230000 1.880000 ( 3.126424)
|
70
|
+
hash:ketama:memcached 0.650000 1.200000 1.850000 ( 3.062838)
|
71
|
+
hash:fnv1a_64:memcached 0.610000 1.300000 1.910000 ( 3.030487)
|
72
|
+
|
data/CHANGELOG
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
|
2
|
+
v0.8. CAS support. Update to libmemcached 0.16.
|
3
|
+
|
2
4
|
v0.7.2. Auto-repair unprintable characters and too-long keys; improve performance of namespacing operation.
|
3
5
|
|
4
6
|
v0.7.1. Allow for explicit resetting of the struct on each request, at least until Brian fixes the synchronization problem.
|
data/COMPATIBILITY
CHANGED
data/README
CHANGED
@@ -22,15 +22,14 @@ The <b>memcached</b> library wraps the pure-C libmemcached client via SWIG.
|
|
22
22
|
|
23
23
|
== Installation
|
24
24
|
|
25
|
-
You need Ruby 1.8.6, and {libmemcached 0.
|
25
|
+
You need Ruby 1.8.6, and {libmemcached 0.16}[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
|
+
For Linux, download and extract the {libmemcached tarball}[http://download.tangent.org/libmemcached-0.16.tar.gz]. Then run:
|
28
28
|
./configure
|
29
29
|
make && sudo make install
|
30
30
|
|
31
|
-
For OS X
|
32
|
-
|
33
|
-
make && sudo make install
|
31
|
+
For OS X, you may be able to install it from MacPorts:
|
32
|
+
sudo port install libmemcached @0.16_0
|
34
33
|
|
35
34
|
Now install the gem:
|
36
35
|
sudo gem install memcached --no-rdoc --no-ri
|
data/ext/rlibmemcached.i
CHANGED
@@ -16,22 +16,16 @@
|
|
16
16
|
%apply unsigned short { uint8_t };
|
17
17
|
%apply unsigned int { uint16_t };
|
18
18
|
%apply unsigned long { uint32_t flags, uint32_t offset };
|
19
|
+
/* %apply unsigned long long { uint64_t cas }; */
|
19
20
|
|
20
|
-
// For behavior's
|
21
|
-
|
21
|
+
// For behavior's set interface
|
22
22
|
%typemap(in) (void *data) {
|
23
23
|
int value = FIX2INT($input);
|
24
|
-
|
25
|
-
|
26
|
-
} else {
|
27
|
-
// Only pass by reference for :distribution and :hash
|
28
|
-
value = value - 2;
|
29
|
-
$1 = &value;
|
30
|
-
}
|
24
|
+
// printf("%d\n", value);
|
25
|
+
$1 = &value;
|
31
26
|
};
|
32
27
|
|
33
28
|
// Array of strings map for multiget
|
34
|
-
|
35
29
|
%typemap(in) (char **keys, size_t *key_length, unsigned int number_of_keys) {
|
36
30
|
int i;
|
37
31
|
Check_Type($input, T_ARRAY);
|
@@ -49,7 +43,6 @@
|
|
49
43
|
}
|
50
44
|
|
51
45
|
// Generic strings
|
52
|
-
|
53
46
|
%typemap(in) (char *str, size_t len) {
|
54
47
|
$1 = STR2CSTR($input);
|
55
48
|
$2 = (size_t) RSTRING($input)->len;
|
@@ -63,23 +56,22 @@
|
|
63
56
|
|
64
57
|
//// Output maps
|
65
58
|
|
59
|
+
/* %apply unsigned long long { uint64_t cas }; */
|
66
60
|
%apply unsigned short *OUTPUT {memcached_return *error}
|
67
61
|
%apply unsigned int *OUTPUT {uint32_t *flags}
|
68
62
|
%apply size_t *OUTPUT {size_t *value_length}
|
69
63
|
%apply unsigned long long *OUTPUT {uint64_t *value}
|
70
64
|
|
71
65
|
// String
|
72
|
-
|
73
66
|
%typemap(in, numinputs=0) (char *key, size_t *key_length) {
|
74
|
-
|
75
|
-
|
67
|
+
char string[256];
|
68
|
+
size_t length = 0;
|
69
|
+
$1 = string;
|
70
|
+
$2 = &length;
|
76
71
|
};
|
77
72
|
%typemap(argout) (char *key, size_t *key_length) {
|
78
|
-
|
79
|
-
|
80
|
-
free($1);
|
81
|
-
free($2);
|
82
|
-
}
|
73
|
+
// Pushes an empty string when *key_length == 0
|
74
|
+
rb_ary_push($result, rb_str_new($1, *$2));
|
83
75
|
}
|
84
76
|
|
85
77
|
// Array of strings
|
data/ext/rlibmemcached_wrap.c
CHANGED
@@ -3690,7 +3690,7 @@ fail:
|
|
3690
3690
|
SWIGINTERN VALUE
|
3691
3691
|
_wrap_MemcachedStatSt_limit_maxbytes_set(int argc, VALUE *argv, VALUE self) {
|
3692
3692
|
struct memcached_stat_st *arg1 = (struct memcached_stat_st *) 0 ;
|
3693
|
-
|
3693
|
+
uint64_t arg2 ;
|
3694
3694
|
void *argp1 = 0 ;
|
3695
3695
|
int res1 = 0 ;
|
3696
3696
|
void *argp2 ;
|
@@ -3705,14 +3705,14 @@ _wrap_MemcachedStatSt_limit_maxbytes_set(int argc, VALUE *argv, VALUE self) {
|
|
3705
3705
|
}
|
3706
3706
|
arg1 = (struct memcached_stat_st *)(argp1);
|
3707
3707
|
{
|
3708
|
-
res2 = SWIG_ConvertPtr(argv[0], &argp2,
|
3708
|
+
res2 = SWIG_ConvertPtr(argv[0], &argp2, SWIGTYPE_p_uint64_t, 0 );
|
3709
3709
|
if (!SWIG_IsOK(res2)) {
|
3710
|
-
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "limit_maxbytes" "', argument " "2"" of type '" "
|
3710
|
+
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "limit_maxbytes" "', argument " "2"" of type '" "uint64_t""'");
|
3711
3711
|
}
|
3712
3712
|
if (!argp2) {
|
3713
|
-
SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "limit_maxbytes" "', argument " "2"" of type '" "
|
3713
|
+
SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "limit_maxbytes" "', argument " "2"" of type '" "uint64_t""'");
|
3714
3714
|
} else {
|
3715
|
-
arg2 = *((
|
3715
|
+
arg2 = *((uint64_t *)(argp2));
|
3716
3716
|
}
|
3717
3717
|
}
|
3718
3718
|
if (arg1) (arg1)->limit_maxbytes = arg2;
|
@@ -3726,7 +3726,7 @@ fail:
|
|
3726
3726
|
SWIGINTERN VALUE
|
3727
3727
|
_wrap_MemcachedStatSt_limit_maxbytes_get(int argc, VALUE *argv, VALUE self) {
|
3728
3728
|
struct memcached_stat_st *arg1 = (struct memcached_stat_st *) 0 ;
|
3729
|
-
|
3729
|
+
uint64_t result;
|
3730
3730
|
void *argp1 = 0 ;
|
3731
3731
|
int res1 = 0 ;
|
3732
3732
|
VALUE vresult = Qnil;
|
@@ -3740,7 +3740,7 @@ _wrap_MemcachedStatSt_limit_maxbytes_get(int argc, VALUE *argv, VALUE self) {
|
|
3740
3740
|
}
|
3741
3741
|
arg1 = (struct memcached_stat_st *)(argp1);
|
3742
3742
|
result = ((arg1)->limit_maxbytes);
|
3743
|
-
vresult = SWIG_NewPointerObj((
|
3743
|
+
vresult = SWIG_NewPointerObj((uint64_t *)memcpy((uint64_t *)malloc(sizeof(uint64_t)),&result,sizeof(uint64_t)), SWIGTYPE_p_uint64_t, SWIG_POINTER_OWN | 0 );
|
3744
3744
|
return vresult;
|
3745
3745
|
fail:
|
3746
3746
|
return Qnil;
|
@@ -6879,13 +6879,8 @@ _wrap_memcached_behavior_set(int argc, VALUE *argv, VALUE self) {
|
|
6879
6879
|
arg2 = (memcached_behavior)(val2);
|
6880
6880
|
{
|
6881
6881
|
int value = FIX2INT(argv[2]);
|
6882
|
-
|
6883
|
-
|
6884
|
-
} else {
|
6885
|
-
// Only pass by reference for :distribution and :hash
|
6886
|
-
value = value - 2;
|
6887
|
-
arg3 = &value;
|
6888
|
-
}
|
6882
|
+
// printf("%d\n", value);
|
6883
|
+
arg3 = &value;
|
6889
6884
|
}
|
6890
6885
|
result = (memcached_return)memcached_behavior_set(arg1,arg2,arg3);
|
6891
6886
|
vresult = SWIG_From_int((int)(result));
|
@@ -7373,8 +7368,10 @@ _wrap_memcached_fetch(int argc, VALUE *argv, VALUE self) {
|
|
7373
7368
|
VALUE vresult = Qnil;
|
7374
7369
|
|
7375
7370
|
{
|
7376
|
-
|
7377
|
-
|
7371
|
+
char string[256];
|
7372
|
+
size_t length = 0;
|
7373
|
+
arg2 = string;
|
7374
|
+
arg3 = &length;
|
7378
7375
|
}
|
7379
7376
|
arg4 = &temp4;
|
7380
7377
|
arg5 = &temp5;
|
@@ -7390,11 +7387,8 @@ _wrap_memcached_fetch(int argc, VALUE *argv, VALUE self) {
|
|
7390
7387
|
result = (char *)memcached_fetch(arg1,arg2,arg3,arg4,arg5,arg6);
|
7391
7388
|
vresult = SWIG_FromCharPtr(result);
|
7392
7389
|
{
|
7393
|
-
|
7394
|
-
|
7395
|
-
free(arg2);
|
7396
|
-
free(arg3);
|
7397
|
-
}
|
7390
|
+
// Pushes an empty string when *key_length == 0
|
7391
|
+
rb_ary_push(vresult, rb_str_new(arg2, *arg3));
|
7398
7392
|
}
|
7399
7393
|
if (SWIG_IsTmpObj(res4)) {
|
7400
7394
|
vresult = SWIG_Ruby_AppendOutput(vresult, SWIG_From_size_t((*arg4)));
|
@@ -8552,13 +8546,8 @@ _wrap_memcached_callback_set(int argc, VALUE *argv, VALUE self) {
|
|
8552
8546
|
arg2 = (memcached_callback)(val2);
|
8553
8547
|
{
|
8554
8548
|
int value = FIX2INT(argv[2]);
|
8555
|
-
|
8556
|
-
|
8557
|
-
} else {
|
8558
|
-
// Only pass by reference for :distribution and :hash
|
8559
|
-
value = value - 2;
|
8560
|
-
arg3 = &value;
|
8561
|
-
}
|
8549
|
+
// printf("%d\n", value);
|
8550
|
+
arg3 = &value;
|
8562
8551
|
}
|
8563
8552
|
result = (memcached_return)memcached_callback_set(arg1,arg2,arg3);
|
8564
8553
|
vresult = SWIG_From_int((int)(result));
|
@@ -8806,8 +8795,10 @@ _wrap_memcached_fetch_rvalue(int argc, VALUE *argv, VALUE self) {
|
|
8806
8795
|
VALUE vresult = Qnil;
|
8807
8796
|
|
8808
8797
|
{
|
8809
|
-
|
8810
|
-
|
8798
|
+
char string[256];
|
8799
|
+
size_t length = 0;
|
8800
|
+
arg2 = string;
|
8801
|
+
arg3 = &length;
|
8811
8802
|
}
|
8812
8803
|
arg4 = &temp4;
|
8813
8804
|
arg5 = &temp5;
|
@@ -8822,11 +8813,8 @@ _wrap_memcached_fetch_rvalue(int argc, VALUE *argv, VALUE self) {
|
|
8822
8813
|
result = (VALUE)memcached_fetch_rvalue(arg1,arg2,arg3,arg4,arg5);
|
8823
8814
|
vresult = result;
|
8824
8815
|
{
|
8825
|
-
|
8826
|
-
|
8827
|
-
free(arg2);
|
8828
|
-
free(arg3);
|
8829
|
-
}
|
8816
|
+
// Pushes an empty string when *key_length == 0
|
8817
|
+
rb_ary_push(vresult, rb_str_new(arg2, *arg3));
|
8830
8818
|
}
|
8831
8819
|
if (SWIG_IsTmpObj(res4)) {
|
8832
8820
|
vresult = SWIG_Ruby_AppendOutput(vresult, SWIG_From_unsigned_SS_int((*arg4)));
|
@@ -9331,7 +9319,7 @@ SWIGEXPORT void Init_rlibmemcached(void) {
|
|
9331
9319
|
rb_define_const(mRlibmemcached, "MEMCACHED_MAX_HOST_LENGTH", SWIG_From_int((int)(64)));
|
9332
9320
|
rb_define_const(mRlibmemcached, "MEMCACHED_WHEEL_SIZE", SWIG_From_int((int)(1024)));
|
9333
9321
|
rb_define_const(mRlibmemcached, "MEMCACHED_STRIDE", SWIG_From_int((int)(4)));
|
9334
|
-
rb_define_const(mRlibmemcached, "LIBMEMCACHED_VERSION_STRING", SWIG_FromCharPtr("0.
|
9322
|
+
rb_define_const(mRlibmemcached, "LIBMEMCACHED_VERSION_STRING", SWIG_FromCharPtr("0.16"));
|
9335
9323
|
rb_define_const(mRlibmemcached, "MEMCACHED_SUCCESS", SWIG_From_int((int)(MEMCACHED_SUCCESS)));
|
9336
9324
|
rb_define_const(mRlibmemcached, "MEMCACHED_FAILURE", SWIG_From_int((int)(MEMCACHED_FAILURE)));
|
9337
9325
|
rb_define_const(mRlibmemcached, "MEMCACHED_HOST_LOOKUP_FAILURE", SWIG_From_int((int)(MEMCACHED_HOST_LOOKUP_FAILURE)));
|
@@ -9364,6 +9352,7 @@ SWIGEXPORT void Init_rlibmemcached(void) {
|
|
9364
9352
|
rb_define_const(mRlibmemcached, "MEMCACHED_FETCH_NOTFINISHED", SWIG_From_int((int)(MEMCACHED_FETCH_NOTFINISHED)));
|
9365
9353
|
rb_define_const(mRlibmemcached, "MEMCACHED_TIMEOUT", SWIG_From_int((int)(MEMCACHED_TIMEOUT)));
|
9366
9354
|
rb_define_const(mRlibmemcached, "MEMCACHED_BUFFERED", SWIG_From_int((int)(MEMCACHED_BUFFERED)));
|
9355
|
+
rb_define_const(mRlibmemcached, "MEMCACHED_BAD_KEY_PROVIDED", SWIG_From_int((int)(MEMCACHED_BAD_KEY_PROVIDED)));
|
9367
9356
|
rb_define_const(mRlibmemcached, "MEMCACHED_MAXIMUM_RETURN", SWIG_From_int((int)(MEMCACHED_MAXIMUM_RETURN)));
|
9368
9357
|
rb_define_const(mRlibmemcached, "MEMCACHED_DISTRIBUTION_MODULA", SWIG_From_int((int)(MEMCACHED_DISTRIBUTION_MODULA)));
|
9369
9358
|
rb_define_const(mRlibmemcached, "MEMCACHED_DISTRIBUTION_CONSISTENT", SWIG_From_int((int)(MEMCACHED_DISTRIBUTION_CONSISTENT)));
|
@@ -9379,6 +9368,8 @@ SWIGEXPORT void Init_rlibmemcached(void) {
|
|
9379
9368
|
rb_define_const(mRlibmemcached, "MEMCACHED_BEHAVIOR_DISTRIBUTION", SWIG_From_int((int)(MEMCACHED_BEHAVIOR_DISTRIBUTION)));
|
9380
9369
|
rb_define_const(mRlibmemcached, "MEMCACHED_BEHAVIOR_BUFFER_REQUESTS", SWIG_From_int((int)(MEMCACHED_BEHAVIOR_BUFFER_REQUESTS)));
|
9381
9370
|
rb_define_const(mRlibmemcached, "MEMCACHED_BEHAVIOR_USER_DATA", SWIG_From_int((int)(MEMCACHED_BEHAVIOR_USER_DATA)));
|
9371
|
+
rb_define_const(mRlibmemcached, "MEMCACHED_BEHAVIOR_SORT_HOSTS", SWIG_From_int((int)(MEMCACHED_BEHAVIOR_SORT_HOSTS)));
|
9372
|
+
rb_define_const(mRlibmemcached, "MEMCACHED_BEHAVIOR_VERIFY_KEY", SWIG_From_int((int)(MEMCACHED_BEHAVIOR_VERIFY_KEY)));
|
9382
9373
|
rb_define_const(mRlibmemcached, "MEMCACHED_CALLBACK_USER_DATA", SWIG_From_int((int)(MEMCACHED_CALLBACK_USER_DATA)));
|
9383
9374
|
rb_define_const(mRlibmemcached, "MEMCACHED_CALLBACK_CLEANUP_FUNCTION", SWIG_From_int((int)(MEMCACHED_CALLBACK_CLEANUP_FUNCTION)));
|
9384
9375
|
rb_define_const(mRlibmemcached, "MEMCACHED_CALLBACK_CLONE_FUNCTION", SWIG_From_int((int)(MEMCACHED_CALLBACK_CLONE_FUNCTION)));
|
data/lib/memcached.rb
CHANGED
@@ -1,11 +1,4 @@
|
|
1
1
|
|
2
|
-
require 'rlibmemcached'
|
3
|
-
require 'memcached/integer'
|
4
|
-
require 'memcached/exceptions'
|
5
|
-
require 'memcached/behaviors'
|
6
|
-
require 'memcached/memcached'
|
7
|
-
require 'memcached/rails'
|
8
|
-
|
9
2
|
=begin rdoc
|
10
3
|
The generated SWIG module for accessing libmemcached's C API.
|
11
4
|
|
@@ -21,4 +14,16 @@ A number of SWIG typemaps and C helper methods are also defined in <tt>ext/libme
|
|
21
14
|
|
22
15
|
=end
|
23
16
|
module Rlibmemcached
|
24
|
-
end
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'rlibmemcached'
|
20
|
+
|
21
|
+
class Memcached
|
22
|
+
Lib = Rlibmemcached
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'memcached/integer'
|
26
|
+
require 'memcached/exceptions'
|
27
|
+
require 'memcached/behaviors'
|
28
|
+
require 'memcached/memcached'
|
29
|
+
require 'memcached/rails'
|
data/lib/memcached/behaviors.rb
CHANGED
@@ -4,8 +4,8 @@ class Memcached
|
|
4
4
|
#:stopdoc:
|
5
5
|
|
6
6
|
def self.load_constants(prefix, hash = {}, offset = 0)
|
7
|
-
|
8
|
-
hash[const_name[prefix.length..-1].downcase.to_sym] =
|
7
|
+
Lib.constants.grep(/^#{prefix}/).each do |const_name|
|
8
|
+
hash[const_name[prefix.length..-1].downcase.to_sym] = Lib.const_get(const_name) + offset
|
9
9
|
end
|
10
10
|
hash
|
11
11
|
end
|
@@ -42,8 +42,8 @@ class Memcached
|
|
42
42
|
# STDERR.puts "Setting #{behavior}:#{b_id} => #{value}:#{v_id}"
|
43
43
|
|
44
44
|
unless value == false
|
45
|
-
# XXX Setting false still turns on the behavior; maybe a
|
46
|
-
|
45
|
+
# XXX Setting false still turns on the behavior; maybe a Lib bug
|
46
|
+
Lib.memcached_behavior_set(@struct, b_id, v_id)
|
47
47
|
end
|
48
48
|
|
49
49
|
end
|
data/lib/memcached/exceptions.rb
CHANGED
@@ -9,6 +9,7 @@ Subclasses correspond one-to-one with server response strings or libmemcached er
|
|
9
9
|
|
10
10
|
== Subclasses
|
11
11
|
|
12
|
+
* Memcached::ABadKeyWasProvidedOrCharactersOutOfRange
|
12
13
|
* Memcached::AKeyLengthOfZeroWasProvided
|
13
14
|
* Memcached::ATimeoutOccurred
|
14
15
|
* Memcached::ActionNotSupported
|
@@ -56,7 +57,7 @@ Subclasses correspond one-to-one with server response strings or libmemcached er
|
|
56
57
|
class << self
|
57
58
|
private
|
58
59
|
def camelize(string)
|
59
|
-
string.downcase.split(' ').map {|s| s.capitalize}.join
|
60
|
+
string.downcase.gsub('/', ' or ').split(' ').map {|s| s.capitalize}.join
|
60
61
|
end
|
61
62
|
end
|
62
63
|
|
data/lib/memcached/memcached.rb
CHANGED
@@ -13,14 +13,15 @@ class Memcached
|
|
13
13
|
:buffer_requests => false,
|
14
14
|
:support_cas => false,
|
15
15
|
:tcp_nodelay => false,
|
16
|
-
:namespace => nil
|
17
|
-
}
|
16
|
+
:namespace => nil
|
17
|
+
}
|
18
|
+
|
19
|
+
# :sort_hosts => false # XXX No effect due to libmemcached 0.16 bug
|
20
|
+
# :verify_key => false # XXX We do this ourselves already in Rlibmemcached.ns()
|
18
21
|
|
19
22
|
#:stopdoc:
|
20
23
|
IGNORED = 0
|
21
24
|
|
22
|
-
Lib = Rlibmemcached
|
23
|
-
|
24
25
|
NOTFOUND_INSTANCE = NotFound.new
|
25
26
|
#:startdoc:
|
26
27
|
|
@@ -48,11 +49,12 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
48
49
|
=end
|
49
50
|
|
50
51
|
def initialize(servers, opts = {})
|
51
|
-
@struct = Lib::MemcachedSt.new
|
52
|
+
@struct = Lib::MemcachedSt.new
|
52
53
|
Lib.memcached_create(@struct)
|
53
54
|
|
54
55
|
# Servers
|
55
|
-
|
56
|
+
# XXX We have to sort them ahead of time due to a libmemcached 0.16 bug
|
57
|
+
Array(servers).sort.each_with_index do |server, index|
|
56
58
|
unless server.is_a? String and server =~ /^(\d{1,3}\.){3}\d{1,3}:\d{1,5}$/
|
57
59
|
raise ArgumentError, "Servers must be in the format ip:port (e.g., '127.0.0.1:11211')"
|
58
60
|
end
|
@@ -104,6 +106,7 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
104
106
|
def destroy(disable_methods = true)
|
105
107
|
Lib.memcached_free(@struct)
|
106
108
|
@struct = nil
|
109
|
+
|
107
110
|
if disable_methods
|
108
111
|
class << self
|
109
112
|
Memcached.instance_methods.each do |method_name|
|
@@ -215,17 +218,22 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
215
218
|
)
|
216
219
|
end
|
217
220
|
|
218
|
-
# Not yet implemented.
|
219
|
-
#
|
220
221
|
# Reads a key's value from the server and yields it to a block. Replaces the key's value with the result of the block as long as the key hasn't been updated in the meantime, otherwise raises <b>Memcached::NotStored</b>. Accepts a String <tt>key</tt> and a block.
|
221
222
|
#
|
222
223
|
# Also accepts an optional <tt>timeout</tt> value.
|
223
224
|
#
|
224
|
-
# CAS stands for "compare and swap", and avoids the need for manual key mutexing. CAS support must be enabled in Memcached.new or a <b>Memcached::ClientError</b> will be raised.
|
225
|
-
|
226
|
-
|
227
|
-
raise NotImplemented
|
225
|
+
# CAS stands for "compare and swap", and avoids the need for manual key mutexing. CAS support must be enabled in Memcached.new or a <b>Memcached::ClientError</b> will be raised. Note that CAS may be buggy in memcached itself.
|
226
|
+
#
|
227
|
+
def cas(key, timeout = 0, marshal = true)
|
228
228
|
raise ClientError, "CAS not enabled for this Memcached instance" unless options[:support_cas]
|
229
|
+
|
230
|
+
value = get(key)
|
231
|
+
value = yield value
|
232
|
+
value = marshal ? Marshal.dump(value) : value.to_s
|
233
|
+
|
234
|
+
check_return_code(
|
235
|
+
Lib.memcached_cas(@struct, Lib.ns(@namespace, key), value, timeout, FLAGS, @struct.result.cas)
|
236
|
+
)
|
229
237
|
end
|
230
238
|
|
231
239
|
### Deleters
|
@@ -316,7 +324,7 @@ Please note that when non-blocking IO is enabled, setter and deleter methods do
|
|
316
324
|
|
317
325
|
# 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.
|
318
326
|
def check_return_code(ret) #:doc:
|
319
|
-
# 0.
|
327
|
+
# 0.16 --enable-debug returns 0 for an ActionQueued result but --disable-debug does not
|
320
328
|
return if ret == 0 or ret == 31
|
321
329
|
raise EXCEPTIONS[ret], ""
|
322
330
|
end
|
data/memcached.gemspec
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
|
2
|
-
# Gem::Specification for Memcached-0.
|
2
|
+
# Gem::Specification for Memcached-0.8
|
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
|
+
s.version = "0.8"
|
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-18}
|
14
14
|
s.description = %q{An interface to the libmemcached C client.}
|
15
15
|
s.email = %q{}
|
16
16
|
s.extensions = ["ext/extconf.rb"]
|
data/test/unit/memcached_test.rb
CHANGED
@@ -74,6 +74,32 @@ class MemcachedTest < Test::Unit::TestCase
|
|
74
74
|
cache.set key, @value
|
75
75
|
end
|
76
76
|
end
|
77
|
+
|
78
|
+
def test_initialize_sort_hosts
|
79
|
+
# Original
|
80
|
+
cache = Memcached.new(@servers.sort)
|
81
|
+
assert_equal @servers.sort,
|
82
|
+
cache.servers
|
83
|
+
cache.destroy
|
84
|
+
|
85
|
+
# Reversed
|
86
|
+
# XXX Fails due to libmemcached 0.16 bug
|
87
|
+
# cache = Memcached.new(@servers.sort.reverse)
|
88
|
+
# assert_equal @servers.sort.reverse,
|
89
|
+
# cache.servers
|
90
|
+
# cache.destroy
|
91
|
+
|
92
|
+
# Reversed with sort_hosts
|
93
|
+
cache = Memcached.new(@servers.sort.reverse,
|
94
|
+
:sort_hosts => true)
|
95
|
+
assert_equal @servers.sort,
|
96
|
+
cache.servers
|
97
|
+
cache.destroy
|
98
|
+
end
|
99
|
+
|
100
|
+
# def test_initialize_verify_key
|
101
|
+
# # XXX Not necessary
|
102
|
+
# end
|
77
103
|
|
78
104
|
def test_initialize_single_server
|
79
105
|
cache = Memcached.new '127.0.0.1:43042'
|
@@ -144,6 +170,15 @@ class MemcachedTest < Test::Unit::TestCase
|
|
144
170
|
@cache.get(["#{key}_1", "#{key}_2", "#{key}_3", "#{key}_4"])
|
145
171
|
)
|
146
172
|
end
|
173
|
+
|
174
|
+
def test_get_multi_completely_missing
|
175
|
+
@cache.delete "#{key}_1" rescue nil
|
176
|
+
@cache.delete "#{key}_2" rescue nil
|
177
|
+
assert_equal(
|
178
|
+
{},
|
179
|
+
@cache.get(["#{key}_1", "#{key}_2"])
|
180
|
+
)
|
181
|
+
end
|
147
182
|
|
148
183
|
def test_set_and_get_unmarshalled
|
149
184
|
@cache.set key, @value
|
@@ -336,11 +371,37 @@ class MemcachedTest < Test::Unit::TestCase
|
|
336
371
|
end
|
337
372
|
|
338
373
|
def test_cas
|
339
|
-
|
340
|
-
@
|
341
|
-
|
374
|
+
cache = Memcached.new(
|
375
|
+
@servers,
|
376
|
+
:namespace => @namespace,
|
377
|
+
:support_cas => true
|
378
|
+
)
|
379
|
+
value2 = OpenStruct.new(:d => 3, :e => 4, :f => GenericClass)
|
380
|
+
|
381
|
+
# Existing set
|
382
|
+
cache.set key, @value
|
383
|
+
cache.cas(key) do |current|
|
384
|
+
assert_equal @value, current
|
385
|
+
value2
|
386
|
+
end
|
387
|
+
assert_equal value2, cache.get(key)
|
388
|
+
|
389
|
+
# Missing set
|
390
|
+
cache.delete key
|
391
|
+
assert_raises(Memcached::NotFound) do
|
392
|
+
cache.cas(key) {}
|
393
|
+
end
|
394
|
+
|
395
|
+
# Conflicting set
|
396
|
+
cache.set key, @value
|
397
|
+
assert_raises(Memcached::ConnectionDataExists) do
|
398
|
+
cache.cas(key) do |current|
|
399
|
+
cache.set key, value2
|
400
|
+
current
|
342
401
|
end
|
343
402
|
end
|
403
|
+
|
404
|
+
cache.destroy
|
344
405
|
end
|
345
406
|
|
346
407
|
# Namespace and key validation
|
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.
|
4
|
+
version: "0.8"
|
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-18 00:00:00 -05:00
|
34
34
|
default_executable:
|
35
35
|
dependencies: []
|
36
36
|
|
metadata.gz.sig
CHANGED
Binary file
|