memcached 0.16.3 → 0.17

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 CHANGED
Binary file
data/BENCHMARKS CHANGED
@@ -7,51 +7,114 @@ You can easily run your own benchmarks, as long as you have memcached itself on
7
7
 
8
8
  == x86-64 OS X
9
9
 
10
- These benchmarks were run on an OS X 10.5 Core 2 Duo machine (10,000 iterations):
10
+ These benchmarks were run on an OS X 10.5 Core 2 Duo machine:
11
11
 
12
12
  Ruby 1.8.7p174
13
- Loaded memcached 0.16.3
14
- Loaded memcache-client 1.7.4
15
-
16
- user system total real
17
- set:plain:noblock:memcached:net 0.260000 0.110000 0.370000 ( 0.941733)
18
- set:plain:noblock:memcached:uds 0.250000 0.060000 0.310000 ( 0.470593)
19
- set:plain:memcached:net 0.640000 1.040000 1.680000 ( 4.352426)
20
- set:plain:memcached:uds 0.500000 0.560000 1.060000 ( 2.130330)
21
- set:plain:memcache-client 7.500000 3.160000 10.660000 ( 11.394051)
22
- set:ruby:noblock:memcached:net 0.430000 0.070000 0.500000 ( 1.393856)
23
- set:ruby:noblock:memcached:uds 0.440000 0.040000 0.480000 ( 0.751106)
24
- set:ruby:memcached:net 0.890000 0.910000 1.800000 ( 5.539385)
25
- set:ruby:memcached:uds 0.790000 0.610000 1.400000 ( 3.257946)
26
- set:ruby:memcache-client 7.710000 3.160000 10.870000 ( 11.494342)
27
- get:plain:memcached:net 0.730000 0.940000 1.670000 ( 4.305591)
28
- get:plain:memcached:uds 0.610000 0.580000 1.190000 ( 2.225602)
29
- get:plain:memcache-client 8.960000 3.110000 12.070000 ( 13.710735)
30
- get:ruby:memcached:net 0.910000 0.980000 1.890000 ( 4.364018)
31
- get:ruby:memcached:uds 0.750000 0.570000 1.320000 ( 2.236862)
32
- get:ruby:memcache-client 9.310000 3.180000 12.490000 ( 13.077060)
33
- multiget:ruby:memcached:net 0.510000 0.350000 0.860000 ( 1.471429)
34
- multiget:ruby:memcached:uds 0.500000 0.260000 0.760000 ( 1.138027)
35
- multiget:ruby:memcache-client 4.840000 1.110000 5.950000 ( 6.511808)
36
- get-miss:ruby:memcached:net 0.960000 1.030000 1.990000 ( 4.510132)
37
- get-miss:ruby:memcached:uds 0.830000 0.640000 1.470000 ( 2.708862)
38
- get-miss:ruby:memcache-client 7.810000 3.190000 11.000000 ( 11.390215)
39
- append-miss:ruby:memcached:net 1.000000 1.030000 2.030000 ( 4.923893)
40
- append-miss:ruby:memcached:uds 0.890000 0.680000 1.570000 ( 3.202743)
41
- append-miss:ruby:memcache-client 7.740000 3.180000 10.920000 ( 11.339136)
42
- mixed:ruby:noblock:memcached:net 1.800000 2.370000 4.170000 ( 8.616549)
43
- mixed:ruby:noblock:memcached:uds 1.410000 1.090000 2.500000 ( 5.035893)
44
- mixed:ruby:memcached:net 1.830000 1.900000 3.730000 ( 9.046367)
45
- mixed:ruby:memcached:uds 1.570000 1.190000 2.760000 ( 6.583020)
46
- mixed:ruby:memcache-client 17.910000 6.440000 24.350000 ( 24.946386)
47
- hash:murmur 0.040000 0.000000 0.040000 ( 0.039152)
48
- hash:default 0.040000 0.000000 0.040000 ( 0.041841)
49
- hash:jenkins 0.050000 0.000000 0.050000 ( 0.052283)
50
- hash:md5 0.090000 0.000000 0.090000 ( 0.092901)
51
- hash:crc 0.040000 0.000000 0.040000 ( 0.037710)
52
- hash:fnv1a_32 0.050000 0.000000 0.050000 ( 0.047746)
53
- hash:hsieh 0.020000 0.000000 0.020000 ( 0.020477)
54
- hash:fnv1_32 0.050000 0.000000 0.050000 ( 0.046204)
55
- hash:fnv1_64 0.100000 0.000000 0.100000 ( 0.106735)
56
- hash:fnv1a_64 0.060000 0.000000 0.060000 ( 0.054646)
13
+ Loaded memcached 0.17
14
+ Loaded binary42-remix-stash 0.9.5
15
+ Loaded memcache-client 1.7.5
16
+ Loops is 40000
17
+ Stack depth is 0
18
+ Small value size is: 13 bytes
19
+ Large value size is: 4158 bytes
20
+
21
+ user system total real
22
+ set:libm 1.360000 2.120000 3.480000 ( 8.952505)
23
+ set:libm:binary 1.180000 2.100000 3.280000 ( 7.692065)
24
+ set:libm:noblock 0.590000 0.240000 0.830000 ( 1.863921)
25
+ set:libm:noblock_binary 0.470000 0.220000 0.690000 ( 1.678243)
26
+ set:libm:udp 1.140000 1.150000 2.290000 ( 4.835305)
27
+ set:ruby 15.440000 6.330000 21.770000 ( 22.136843)
28
+ set:stash 5.780000 2.040000 7.820000 ( 13.748268)
29
+ get:libm 1.600000 2.000000 3.600000 ( 8.112166)
30
+ get:libm:binary 1.360000 2.150000 3.510000 ( 7.829266)
31
+ get:libm:noblock 1.820000 2.630000 4.450000 ( 8.971191)
32
+ get:libm:noblock_binary 1.560000 2.650000 4.210000 ( 8.114088)
33
+ get:libm:udp 1.350000 1.140000 2.490000 ( 4.878485)
34
+ get:ruby 18.640000 6.370000 25.010000 ( 25.925459)
35
+ get:stash 5.120000 1.990000 7.110000 ( 11.850485)
36
+ get-multi:libm 1.770000 1.320000 3.090000 ( 4.790793)
37
+ get-multi:libm:binary 1.730000 1.740000 3.470000 ( 5.655120)
38
+ get-multi:libm:noblock 1.820000 1.330000 3.150000 ( 4.841084)
39
+ get-multi:libm:noblock_binary 1.740000 1.760000 3.500000 ( 5.616970)
40
+ get-multi:libm:udp 1.690000 0.960000 2.650000 ( 3.551923)
41
+ get-multi:ruby 21.380000 4.400000 25.780000 ( 26.017883)
42
+ append:libm 1.500000 2.180000 3.680000 ( 14.658051)
43
+ append:libm:binary 1.300000 2.110000 3.410000 ( 13.626305)
44
+ append:libm:noblock 1.850000 2.870000 4.720000 ( 45.167145)
45
+ append:libm:noblock_binary 1.640000 2.870000 4.510000 ( 44.614596)
46
+ append:libm:udp 1.260000 1.170000 2.430000 ( 11.556293)
47
+ append:ruby 16.770000 7.310000 24.080000 ( 29.525815)
48
+ delete:libm 1.890000 2.080000 3.970000 ( 8.368548)
49
+ delete:libm:binary 1.730000 2.090000 3.820000 ( 7.799952)
50
+ delete:libm:noblock 0.850000 0.890000 1.740000 ( 2.530108)
51
+ delete:libm:noblock_binary 0.710000 0.780000 1.490000 ( 2.390600)
52
+ delete:libm:udp 1.700000 1.310000 3.010000 ( 6.508360)
53
+ delete:ruby 15.670000 6.330000 22.000000 ( 22.226087)
54
+ delete:stash 4.970000 2.010000 6.980000 ( 11.726916)
55
+ get-missing:libm 2.070000 2.060000 4.130000 ( 8.937420)
56
+ get-missing:libm:binary 2.010000 2.090000 4.100000 ( 8.506150)
57
+ get-missing:libm:noblock 2.270000 2.770000 5.040000 ( 9.485592)
58
+ get-missing:libm:noblock_binary 2.220000 2.760000 4.980000 ( 9.226826)
59
+ get-missing:libm:udp 1.830000 1.300000 3.130000 ( 7.135699)
60
+ get-missing:ruby 16.130000 6.380000 22.510000 ( 22.888698)
61
+ get-missing:stash 5.030000 2.030000 7.060000 ( 11.556793)
62
+ append-missing:libm 2.210000 2.070000 4.280000 ( 10.386632)
63
+ append-missing:libm:binary 2.000000 2.060000 4.060000 ( 9.135312)
64
+ append-missing:libm:noblock 2.400000 2.740000 5.140000 ( 10.821778)
65
+ append-missing:libm:noblock_binary 2.200000 2.770000 4.970000 ( 9.699192)
66
+ append-missing:libm:udp 1.970000 1.320000 3.290000 ( 7.668878)
67
+ append-missing:ruby 15.970000 6.470000 22.440000 ( 22.912466)
68
+ set-large:libm 1.460000 2.210000 3.670000 ( 9.517034)
69
+ set-large:libm:binary 1.260000 2.270000 3.530000 ( 9.098769)
70
+ set-large:libm:noblock 0.980000 0.890000 1.870000 ( 3.304075)
71
+ set-large:libm:noblock_binary 0.840000 0.890000 1.730000 ( 3.444305)
72
+ set-large:libm:udp 1.250000 1.330000 2.580000 ( 6.924254)
73
+ set-large:ruby 16.960000 6.490000 23.450000 ( 23.964380)
74
+ get-large:libm 2.280000 2.450000 4.730000 ( 9.908532)
75
+ get-large:libm:binary 2.080000 2.530000 4.610000 ( 8.966637)
76
+ get-large:libm:noblock 2.410000 2.850000 5.260000 ( 11.066391)
77
+ get-large:libm:noblock_binary 2.200000 2.910000 5.110000 ( 10.328922)
78
+ get-large:libm:udp 2.010000 1.430000 3.440000 ( 6.679192)
79
+ get-large:ruby 21.790000 7.370000 29.160000 ( 29.578987)
80
+ get-large:stash 5.430000 2.020000 7.450000 ( 11.967011)
81
+ set-ruby:libm 1.800000 1.990000 3.790000 ( 9.511387)
82
+ set-ruby:libm:binary 1.610000 2.000000 3.610000 ( 8.502297)
83
+ set-ruby:libm:noblock 0.910000 0.200000 1.110000 ( 2.083001)
84
+ set-ruby:libm:noblock_binary 0.750000 0.210000 0.960000 ( 1.895510)
85
+ set-ruby:libm:udp 1.530000 1.170000 2.700000 ( 6.148442)
86
+ set-ruby:ruby 16.290000 6.400000 22.690000 ( 23.672254)
87
+ set-ruby:stash 5.570000 2.020000 7.590000 ( 13.381661)
88
+ get-ruby:libm 1.920000 1.950000 3.870000 ( 9.042716)
89
+ get-ruby:libm:binary 1.640000 1.980000 3.620000 ( 7.987886)
90
+ get-ruby:libm:noblock 2.140000 2.600000 4.740000 ( 10.280036)
91
+ get-ruby:libm:noblock_binary 1.870000 2.590000 4.460000 ( 9.213013)
92
+ get-ruby:libm:udp 1.660000 1.170000 2.830000 ( 5.762381)
93
+ get-ruby:ruby 19.760000 6.500000 26.260000 ( 27.573109)
94
+ get-ruby:stash 5.480000 2.010000 7.490000 ( 12.349059)
95
+ set-ruby-large:libm 33.820000 2.340000 36.160000 ( 43.061537)
96
+ set-ruby-large:libm:binary 33.430000 2.260000 35.690000 ( 41.940845)
97
+ set-ruby-large:libm:noblock 34.170000 0.930000 35.100000 ( 35.632694)
98
+ set-ruby-large:libm:noblock_binary 34.010000 0.930000 34.940000 ( 35.383141)
99
+ set-ruby-large:libm:udp 33.150000 1.430000 34.580000 ( 39.521448)
100
+ set-ruby-large:ruby 48.830000 6.560000 55.390000 ( 55.750071)
101
+ set-ruby-large:stash 38.660000 2.230000 40.890000 ( 46.957838)
102
+ get-ruby-large:libm 23.570000 2.340000 25.910000 ( 32.166590)
103
+ get-ruby-large:libm:binary 23.420000 2.510000 25.930000 ( 31.953854)
104
+ get-ruby-large:libm:noblock 23.840000 3.040000 26.880000 ( 32.919639)
105
+ get-ruby-large:libm:noblock_binary 23.570000 2.970000 26.540000 ( 32.210027)
106
+ get-ruby-large:libm:udp 23.210000 1.460000 24.670000 ( 29.284808)
107
+ get-ruby-large:ruby 41.170000 7.560000 48.730000 ( 49.507358)
108
+ get-ruby-large:stash 25.760000 2.540000 28.300000 ( 33.998493)
109
+ hash:fnv1a_64 0.240000 0.000000 0.240000 ( 0.247813)
110
+ hash:murmur 0.190000 0.000000 0.190000 ( 0.193039)
111
+ hash:default 0.220000 0.000000 0.220000 ( 0.216573)
112
+ hash:jenkins 0.220000 0.000000 0.220000 ( 0.222694)
113
+ hash:md5 0.390000 0.000000 0.390000 ( 0.395159)
114
+ hash:crc 0.210000 0.000000 0.210000 ( 0.216457)
115
+ hash:hsieh 0.100000 0.000000 0.100000 ( 0.104386)
116
+ hash:fnv1_32 0.220000 0.000000 0.220000 ( 0.216769)
117
+ hash:fnv1a_32 0.230000 0.000000 0.230000 ( 0.237016)
118
+ hash:fnv1_64 0.450000 0.010000 0.460000 ( 0.454704)
119
+
57
120
 
data/CHANGELOG CHANGED
@@ -1,4 +1,6 @@
1
1
 
2
+ v0.17. Update to libmemcached 0.32. Update Darwin version string for Snow Leopard final. Improve benchmarks. Add Memcached::Rails#append and #prepend, alias all original Memcached methods to _orig, and add set_servers= accessor for compatibility.
3
+
2
4
  v0.16.3. Optimize append/prepend on miss.
3
5
 
4
6
  v0.16.2. Fix memory leak.
data/Manifest CHANGED
@@ -1,20 +1,21 @@
1
1
  BENCHMARKS
2
2
  CHANGELOG
3
- COMPATIBILITY
3
+ LICENSE
4
+ Manifest
5
+ README
6
+ Rakefile
7
+ TODO
4
8
  ext/extconf.rb
5
- ext/libmemcached-0.31.tar.gz
9
+ ext/libmemcached-0.32.tar.gz
10
+ ext/libmemcached.patch
6
11
  ext/rlibmemcached.i
7
12
  ext/rlibmemcached_wrap.c
13
+ lib/memcached.rb
8
14
  lib/memcached/behaviors.rb
9
15
  lib/memcached/exceptions.rb
10
16
  lib/memcached/integer.rb
11
17
  lib/memcached/memcached.rb
12
18
  lib/memcached/rails.rb
13
- lib/memcached.rb
14
- LICENSE
15
- Manifest
16
- Rakefile
17
- README
18
19
  test/profile/benchmark.rb
19
20
  test/profile/profile.rb
20
21
  test/profile/valgrind.rb
@@ -24,4 +25,3 @@ test/test_helper.rb
24
25
  test/unit/binding_test.rb
25
26
  test/unit/memcached_test.rb
26
27
  test/unit/rails_test.rb
27
- TODO
@@ -9,7 +9,7 @@ DARWIN = `uname -sp` == "Darwin i386\n"
9
9
  # is there a better way to do this?
10
10
  archflags = if ENV['ARCHFLAGS']
11
11
  ENV['ARCHFLAGS']
12
- elsif Config::CONFIG['host_os'] == 'darwin10.0'
12
+ elsif Config::CONFIG['host_os'] =~ /darwin10\.0\.*/
13
13
  "-arch i386 -arch x86_64"
14
14
  elsif Config::CONFIG['host_os'] =~ /darwin/
15
15
  "-arch i386 -arch ppc"
@@ -35,6 +35,10 @@ if !ENV["EXTERNAL_LIB"]
35
35
  puts "Building libmemcached."
36
36
  puts(cmd = "tar xzf #{BUNDLE} 2>&1")
37
37
  raise "'#{cmd}' failed" unless system(cmd)
38
+
39
+ puts "Patching libmemcached."
40
+ puts(cmd = "patch -p1 < libmemcached.patch")
41
+ raise "'#{cmd}' failed" unless system(cmd)
38
42
 
39
43
  Dir.chdir(BUNDLE_PATH) do
40
44
 
@@ -0,0 +1,270 @@
1
+
2
+ diff --git a/libmemcached-0.32/libmemcached/memcached_response.c b/libmemcached/libmemcached/memcached_response.c
3
+ --- a/libmemcached-0.32/libmemcached/memcached_response.c
4
+ +++ b/libmemcached/libmemcached/memcached_response.c
5
+ @@ -496,6 +496,8 @@
6
+ case PROTOCOL_BINARY_RESPONSE_E2BIG:
7
+ case PROTOCOL_BINARY_RESPONSE_EINVAL:
8
+ case PROTOCOL_BINARY_RESPONSE_NOT_STORED:
9
+ + rc= MEMCACHED_NOTSTORED;
10
+ + break;
11
+ case PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND:
12
+ case PROTOCOL_BINARY_RESPONSE_ENOMEM:
13
+ default:
14
+ diff --git a/libmemcached-0.32/libmemcached/memcached.c b/libmemcached/libmemcached/memcached.c
15
+ --- a/libmemcached-0.32/libmemcached/memcached.c
16
+ +++ b/libmemcached/libmemcached/memcached.c
17
+ @@ -50,6 +50,9 @@ void memcached_free(memcached_st *ptr)
18
+ if (ptr->continuum)
19
+ ptr->call_free(ptr, ptr->continuum);
20
+
21
+ + if (ptr->live_host_indices)
22
+ + ptr->call_free(ptr, ptr->live_host_indices);
23
+ +
24
+ if (ptr->is_allocated)
25
+ ptr->call_free(ptr, ptr);
26
+ else
27
+ diff --git a/libmemcached-0.32/libmemcached/memcached.h b/libmemcached/libmemcached/memcached.h
28
+ --- a/libmemcached-0.32/libmemcached/memcached.h
29
+ +++ b/libmemcached/libmemcached/memcached.h
30
+ @@ -112,6 +112,9 @@ struct memcached_st {
31
+ memcached_trigger_delete_key delete_trigger;
32
+ char prefix_key[MEMCACHED_PREFIX_KEY_MAX_SIZE];
33
+ uint32_t number_of_replicas;
34
+ + uint32_t number_of_live_hosts;
35
+ + uint32_t *live_host_indices;
36
+ + uint32_t live_host_indices_size;
37
+ };
38
+
39
+ LIBMEMCACHED_API
40
+ diff --git a/libmemcached-0.32/libmemcached/memcached_connect.c b/libmemcached/libmemcached/memcached_connect.c
41
+ --- a/libmemcached-0.32/libmemcached/memcached_connect.c
42
+ +++ b/libmemcached/libmemcached/memcached_connect.c
43
+ @@ -273,7 +272,6 @@ static memcached_return network_connect(memcached_server_st *ptr)
44
+ (void)fcntl(ptr->fd, F_SETFL, flags & ~O_NONBLOCK);
45
+
46
+ WATCHPOINT_ASSERT(ptr->cursor_active == 0);
47
+ - ptr->server_failure_counter= 0;
48
+ return MEMCACHED_SUCCESS;
49
+ }
50
+ use = use->ai_next;
51
+ @@ -282,21 +280,13 @@ static memcached_return network_connect(memcached_server_st *ptr)
52
+
53
+ if (ptr->fd == -1)
54
+ {
55
+ - /* Failed to connect. schedule next retry */
56
+ - if (ptr->root->retry_timeout)
57
+ - {
58
+ - struct timeval next_time;
59
+ -
60
+ - if (gettimeofday(&next_time, NULL) == 0)
61
+ - ptr->next_retry= next_time.tv_sec + ptr->root->retry_timeout;
62
+ - }
63
+ - ptr->server_failure_counter+= 1;
64
+ + ptr->server_failure_counter ++;
65
+ if (ptr->cached_errno == 0)
66
+ return MEMCACHED_TIMEOUT;
67
+ +
68
+ return MEMCACHED_ERRNO; /* The last error should be from connect() */
69
+ }
70
+
71
+ - ptr->server_failure_counter= 0;
72
+ return MEMCACHED_SUCCESS; /* The last error should be from connect() */
73
+ }
74
+
75
+ @@ -315,7 +305,7 @@ memcached_return memcached_connect(memcached_server_st *ptr)
76
+ gettimeofday(&next_time, NULL);
77
+
78
+ /* if we've had too many consecutive errors on this server, mark it dead. */
79
+ - if (ptr->server_failure_counter > ptr->root->server_failure_limit)
80
+ + if (ptr->server_failure_counter >= ptr->root->server_failure_limit)
81
+ {
82
+ ptr->next_retry= next_time.tv_sec + ptr->root->retry_timeout;
83
+ ptr->server_failure_counter= 0;
84
+ diff --git a/libmemcached-0.32/libmemcached/memcached_get.h b/libmemcached/libmemcached/memcached_get.h
85
+ diff --git a/libmemcached-0.32/libmemcached/memcached_hash.c b/libmemcached/libmemcached/memcached_hash.c
86
+ index 129d761..3a7fa55 100644
87
+ --- a/libmemcached-0.32/libmemcached/memcached_hash.c
88
+ +++ b/libmemcached/libmemcached/memcached_hash.c
89
+ @@ -11,6 +11,7 @@ static uint32_t FNV_32_PRIME= 16777619;
90
+ /* Prototypes */
91
+ static uint32_t internal_generate_hash(const char *key, size_t key_length);
92
+ static uint32_t internal_generate_md5(const char *key, size_t key_length);
93
+ +uint32_t memcached_live_host_index(memcached_st *ptr, uint32_t num);
94
+
95
+ uint32_t memcached_generate_hash_value(const char *key, size_t key_length, memcached_hash hash_algorithm)
96
+ {
97
+ @@ -146,10 +144,10 @@ static uint32_t dispatch_host(memcached_st *ptr, uint32_t hash)
98
+ right= begin;
99
+ return right->index;
100
+ }
101
+ - case MEMCACHED_DISTRIBUTION_MODULA:
102
+ - return hash % ptr->number_of_hosts;
103
+ + case MEMCACHED_DISTRIBUTION_MODULA:
104
+ + return memcached_live_host_index(ptr, hash);
105
+ case MEMCACHED_DISTRIBUTION_RANDOM:
106
+ - return (uint32_t) random() % ptr->number_of_hosts;
107
+ + return memcached_live_host_index(ptr, (int)random());
108
+ default:
109
+ WATCHPOINT_ASSERT(0); /* We have added a distribution without extending the logic */
110
+ return hash % ptr->number_of_hosts;
111
+ @@ -201,6 +199,19 @@ uint32_t memcached_generate_hash(memcached_st *ptr, const char *key, size_t key_
112
+ return dispatch_host(ptr, hash);
113
+ }
114
+
115
+ +uint32_t memcached_live_host_index(memcached_st *ptr, uint32_t num)
116
+ +{
117
+ + if (memcached_behavior_get(ptr, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS)) {
118
+ + if (ptr->number_of_live_hosts > 0) {
119
+ + return ptr->live_host_indices[num % ptr->number_of_live_hosts];
120
+ + } else {
121
+ + return 0; /* FIXME: we should do something different if every server's dead, but I dunno what. */
122
+ + }
123
+ + } else {
124
+ + return num % ptr->number_of_hosts;
125
+ + }
126
+ +}
127
+ +
128
+ static uint32_t internal_generate_hash(const char *key, size_t key_length)
129
+ {
130
+ const char *ptr= key;
131
+ diff --git a/libmemcached-0.32/libmemcached/memcached_hosts.c b/libmemcached/libmemcached/memcached_hosts.c
132
+ --- a/libmemcached-0.32/libmemcached/memcached_hosts.c
133
+ +++ b/libmemcached/libmemcached/memcached_hosts.c
134
+ @@ -7,6 +7,7 @@ static memcached_return server_add(memcached_st *ptr, const char *hostname,
135
+ uint32_t weight,
136
+ memcached_connection type);
137
+ memcached_return update_continuum(memcached_st *ptr);
138
+ +memcached_return update_live_host_indices(memcached_st *ptr);
139
+
140
+ static int compare_servers(const void *p1, const void *p2)
141
+ {
142
+ @@ -44,8 +45,12 @@ memcached_return run_distribution(memcached_st *ptr)
143
+ case MEMCACHED_DISTRIBUTION_MODULA:
144
+ if (ptr->flags & MEM_USE_SORT_HOSTS)
145
+ sort_hosts(ptr);
146
+ + if (memcached_behavior_get(ptr, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS))
147
+ + update_live_host_indices(ptr);
148
+ break;
149
+ case MEMCACHED_DISTRIBUTION_RANDOM:
150
+ + if (memcached_behavior_get(ptr, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS))
151
+ + update_live_host_indices(ptr);
152
+ break;
153
+ default:
154
+ WATCHPOINT_ASSERT(0); /* We have added a distribution without extending the logic */
155
+ @@ -85,6 +90,46 @@ static uint32_t ketama_server_hash(const char *key, unsigned int key_length, int
156
+ | (results[0 + alignment * 4] & 0xFF);
157
+ }
158
+
159
+ +memcached_return update_live_host_indices(memcached_st *ptr)
160
+ +{
161
+ + uint32_t host_index;
162
+ + struct timeval now;
163
+ + uint32_t i = 0;
164
+ + memcached_server_st *list;
165
+ +
166
+ + if (gettimeofday(&now, NULL) != 0)
167
+ + {
168
+ + ptr->cached_errno = errno;
169
+ + return MEMCACHED_ERRNO;
170
+ + }
171
+ +
172
+ + if (ptr->live_host_indices == NULL) {
173
+ + ptr->live_host_indices = (uint32_t *)ptr->call_malloc(ptr, sizeof(uint32_t) * ptr->number_of_live_hosts);
174
+ + ptr->live_host_indices_size = ptr->number_of_live_hosts;
175
+ + }
176
+ +
177
+ + /* somehow we added some hosts. Shouldn't get here much, if at all. */
178
+ + if (ptr->live_host_indices_size < ptr->number_of_hosts ) {
179
+ + ptr->live_host_indices = (uint32_t *)ptr->call_realloc(ptr, ptr->live_host_indices, sizeof(uint32_t) * ptr->number_of_live_hosts);
180
+ + ptr->live_host_indices_size = ptr->number_of_live_hosts;
181
+ + }
182
+ +
183
+ + if (ptr->live_host_indices == NULL)
184
+ + return MEMCACHED_FAILURE;
185
+ +
186
+ + list = ptr->hosts;
187
+ + for (host_index= 0; host_index < ptr->number_of_hosts; ++host_index)
188
+ + {
189
+ + if (list[host_index].next_retry <= now.tv_sec) {
190
+ + ptr->live_host_indices[i++] = host_index;
191
+ + } else if (ptr->next_distribution_rebuild == 0 || list[host_index].next_retry < ptr->next_distribution_rebuild) {
192
+ + ptr->next_distribution_rebuild= list[host_index].next_retry;
193
+ + }
194
+ + }
195
+ + ptr->number_of_live_hosts = i;
196
+ + return MEMCACHED_SUCCESS;
197
+ +}
198
+ +
199
+ static int continuum_item_cmp(const void *t1, const void *t2)
200
+ {
201
+ memcached_continuum_item_st *ct1= (memcached_continuum_item_st *)t1;
202
+ @@ -111,8 +156,8 @@ memcached_return update_continuum(memcached_st *ptr)
203
+ uint32_t pointer_per_server= MEMCACHED_POINTS_PER_SERVER;
204
+ uint32_t pointer_per_hash= 1;
205
+ uint64_t total_weight= 0;
206
+ - uint64_t is_ketama_weighted= 0;
207
+ - uint64_t is_auto_ejecting= 0;
208
+ + uint32_t is_ketama_weighted= 0;
209
+ + uint32_t is_auto_ejecting= 0;
210
+ uint32_t points_per_server= 0;
211
+ uint32_t live_servers= 0;
212
+ struct timeval now;
213
+ diff --git a/libmemcached-0.32/libmemcached/memcached_storage.c b/libmemcached/libmemcached/memcached_storage.c
214
+ index ecefc56..ee79a7e 100644
215
+ --- a/libmemcached-0.32/libmemcached/memcached_storage.c
216
+ +++ b/libmemcached/libmemcached/memcached_storage.c
217
+ @@ -135,22 +135,16 @@ static inline memcached_return memcached_send(memcached_st *ptr,
218
+ }
219
+
220
+ if (write_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
221
+ - {
222
+ - rc= MEMCACHED_WRITE_FAILURE;
223
+ - goto error;
224
+ - }
225
+ + return MEMCACHED_WRITE_FAILURE;
226
+
227
+ /* Send command header */
228
+ rc= memcached_do(&ptr->hosts[server_key], buffer, write_length, 0);
229
+ if (rc != MEMCACHED_SUCCESS)
230
+ - goto error;
231
+ + return rc;
232
+
233
+ /* Send command body */
234
+ if ((sent_length= memcached_io_write(&ptr->hosts[server_key], value, value_length, 0)) == -1)
235
+ - {
236
+ - rc= MEMCACHED_WRITE_FAILURE;
237
+ - goto error;
238
+ - }
239
+ + return MEMCACHED_WRITE_FAILURE;
240
+
241
+ if ((ptr->flags & MEM_BUFFER_REQUESTS) && verb == SET_OP)
242
+ to_write= 0;
243
+ @@ -158,10 +152,7 @@ static inline memcached_return memcached_send(memcached_st *ptr,
244
+ to_write= 1;
245
+
246
+ if ((sent_length= memcached_io_write(&ptr->hosts[server_key], "\r\n", 2, to_write)) == -1)
247
+ - {
248
+ - rc= MEMCACHED_WRITE_FAILURE;
249
+ - goto error;
250
+ - }
251
+ + return MEMCACHED_WRITE_FAILURE;
252
+
253
+ if (ptr->flags & MEM_NOREPLY)
254
+ return (to_write == 0) ? MEMCACHED_BUFFERED : MEMCACHED_SUCCESS;
255
+ @@ -170,15 +161,8 @@ static inline memcached_return memcached_send(memcached_st *ptr,
256
+ return MEMCACHED_BUFFERED;
257
+
258
+ rc= memcached_response(&ptr->hosts[server_key], buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
259
+ -
260
+ if (rc == MEMCACHED_STORED)
261
+ - return MEMCACHED_SUCCESS;
262
+ - else
263
+ - return rc;
264
+ -
265
+ -error:
266
+ - memcached_io_reset(&ptr->hosts[server_key]);
267
+ -
268
+ + return MEMCACHED_SUCCESS;
269
+ return rc;
270
+ }