vinted-memcached 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. checksums.yaml +7 -0
  2. data/BENCHMARKS +142 -0
  3. data/CHANGELOG +176 -0
  4. data/Gemfile +11 -0
  5. data/Gemfile.lock +45 -0
  6. data/LICENSE +184 -0
  7. data/Manifest +209 -0
  8. data/README.rdoc +124 -0
  9. data/Rakefile +134 -0
  10. data/TODO +1 -0
  11. data/ext/extconf-make.rb +25 -0
  12. data/ext/extconf.rb +78 -0
  13. data/ext/libmemcached-0.32/AUTHORS +7 -0
  14. data/ext/libmemcached-0.32/COPYING +32 -0
  15. data/ext/libmemcached-0.32/ChangeLog +303 -0
  16. data/ext/libmemcached-0.32/INSTALL +302 -0
  17. data/ext/libmemcached-0.32/Makefile.am +36 -0
  18. data/ext/libmemcached-0.32/Makefile.in +911 -0
  19. data/ext/libmemcached-0.32/NEWS +1 -0
  20. data/ext/libmemcached-0.32/README +33 -0
  21. data/ext/libmemcached-0.32/THANKS +14 -0
  22. data/ext/libmemcached-0.32/TODO +11 -0
  23. data/ext/libmemcached-0.32/aclocal.m4 +2108 -0
  24. data/ext/libmemcached-0.32/clients/Makefile.am +80 -0
  25. data/ext/libmemcached-0.32/clients/Makefile.in +773 -0
  26. data/ext/libmemcached-0.32/clients/client_options.h +32 -0
  27. data/ext/libmemcached-0.32/clients/execute.c +64 -0
  28. data/ext/libmemcached-0.32/clients/execute.h +5 -0
  29. data/ext/libmemcached-0.32/clients/generator.c +74 -0
  30. data/ext/libmemcached-0.32/clients/generator.h +20 -0
  31. data/ext/libmemcached-0.32/clients/memcat.c +178 -0
  32. data/ext/libmemcached-0.32/clients/memcp.c +251 -0
  33. data/ext/libmemcached-0.32/clients/memdump.c +170 -0
  34. data/ext/libmemcached-0.32/clients/memerror.c +80 -0
  35. data/ext/libmemcached-0.32/clients/memflush.c +143 -0
  36. data/ext/libmemcached-0.32/clients/memrm.c +160 -0
  37. data/ext/libmemcached-0.32/clients/memslap.c +441 -0
  38. data/ext/libmemcached-0.32/clients/memstat.c +326 -0
  39. data/ext/libmemcached-0.32/clients/utilities.c +207 -0
  40. data/ext/libmemcached-0.32/clients/utilities.h +41 -0
  41. data/ext/libmemcached-0.32/config/compile +143 -0
  42. data/ext/libmemcached-0.32/config/config.guess +1561 -0
  43. data/ext/libmemcached-0.32/config/config.rpath +666 -0
  44. data/ext/libmemcached-0.32/config/config.sub +1686 -0
  45. data/ext/libmemcached-0.32/config/depcomp +630 -0
  46. data/ext/libmemcached-0.32/config/install-sh +520 -0
  47. data/ext/libmemcached-0.32/config/ltmain.sh +9636 -0
  48. data/ext/libmemcached-0.32/config/missing +376 -0
  49. data/ext/libmemcached-0.32/config.h.in +254 -0
  50. data/ext/libmemcached-0.32/configure +23843 -0
  51. data/ext/libmemcached-0.32/configure.ac +120 -0
  52. data/ext/libmemcached-0.32/libmemcached/Makefile.am +111 -0
  53. data/ext/libmemcached-0.32/libmemcached/Makefile.in +1069 -0
  54. data/ext/libmemcached-0.32/libmemcached/byteorder.c +31 -0
  55. data/ext/libmemcached-0.32/libmemcached/common.h +189 -0
  56. data/ext/libmemcached-0.32/libmemcached/crc.c +86 -0
  57. data/ext/libmemcached-0.32/libmemcached/hsieh_hash.c +68 -0
  58. data/ext/libmemcached-0.32/libmemcached/jenkins_hash.c +213 -0
  59. data/ext/libmemcached-0.32/libmemcached/libmemcached.ver +1 -0
  60. data/ext/libmemcached-0.32/libmemcached/libmemcached_probes.d +30 -0
  61. data/ext/libmemcached-0.32/libmemcached/libmemcached_probes.h +82 -0
  62. data/ext/libmemcached-0.32/libmemcached/md5.c +354 -0
  63. data/ext/libmemcached-0.32/libmemcached/memcached/README.txt +7 -0
  64. data/ext/libmemcached-0.32/libmemcached/memcached/protocol_binary.h +385 -0
  65. data/ext/libmemcached-0.32/libmemcached/memcached.c +153 -0
  66. data/ext/libmemcached-0.32/libmemcached/memcached.h +305 -0
  67. data/ext/libmemcached-0.32/libmemcached/memcached.hpp +799 -0
  68. data/ext/libmemcached-0.32/libmemcached/memcached_allocators.c +72 -0
  69. data/ext/libmemcached-0.32/libmemcached/memcached_analyze.c +100 -0
  70. data/ext/libmemcached-0.32/libmemcached/memcached_auto.c +207 -0
  71. data/ext/libmemcached-0.32/libmemcached/memcached_behavior.c +290 -0
  72. data/ext/libmemcached-0.32/libmemcached/memcached_callback.c +175 -0
  73. data/ext/libmemcached-0.32/libmemcached/memcached_configure.h.in +23 -0
  74. data/ext/libmemcached-0.32/libmemcached/memcached_connect.c +371 -0
  75. data/ext/libmemcached-0.32/libmemcached/memcached_constants.h +146 -0
  76. data/ext/libmemcached-0.32/libmemcached/memcached_delete.c +0 -0
  77. data/ext/libmemcached-0.32/libmemcached/memcached_do.c +72 -0
  78. data/ext/libmemcached-0.32/libmemcached/memcached_dump.c +79 -0
  79. data/ext/libmemcached-0.32/libmemcached/memcached_exist.c +114 -0
  80. data/ext/libmemcached-0.32/libmemcached/memcached_exist.h +20 -0
  81. data/ext/libmemcached-0.32/libmemcached/memcached_fetch.c +102 -0
  82. data/ext/libmemcached-0.32/libmemcached/memcached_flush.c +89 -0
  83. data/ext/libmemcached-0.32/libmemcached/memcached_flush_buffers.c +23 -0
  84. data/ext/libmemcached-0.32/libmemcached/memcached_get.c +494 -0
  85. data/ext/libmemcached-0.32/libmemcached/memcached_get.h +87 -0
  86. data/ext/libmemcached-0.32/libmemcached/memcached_hash.c +252 -0
  87. data/ext/libmemcached-0.32/libmemcached/memcached_hosts.c +510 -0
  88. data/ext/libmemcached-0.32/libmemcached/memcached_internal.h +31 -0
  89. data/ext/libmemcached-0.32/libmemcached/memcached_io.c +594 -0
  90. data/ext/libmemcached-0.32/libmemcached/memcached_io.h +72 -0
  91. data/ext/libmemcached-0.32/libmemcached/memcached_key.c +28 -0
  92. data/ext/libmemcached-0.32/libmemcached/memcached_parse.c +74 -0
  93. data/ext/libmemcached-0.32/libmemcached/memcached_pool.h +38 -0
  94. data/ext/libmemcached-0.32/libmemcached/memcached_purge.c +76 -0
  95. data/ext/libmemcached-0.32/libmemcached/memcached_quit.c +75 -0
  96. data/ext/libmemcached-0.32/libmemcached/memcached_response.c +529 -0
  97. data/ext/libmemcached-0.32/libmemcached/memcached_result.c +57 -0
  98. data/ext/libmemcached-0.32/libmemcached/memcached_result.h +59 -0
  99. data/ext/libmemcached-0.32/libmemcached/memcached_sasl.c +225 -0
  100. data/ext/libmemcached-0.32/libmemcached/memcached_sasl.h +44 -0
  101. data/ext/libmemcached-0.32/libmemcached/memcached_server.c +159 -0
  102. data/ext/libmemcached-0.32/libmemcached/memcached_server.h +93 -0
  103. data/ext/libmemcached-0.32/libmemcached/memcached_stats.c +437 -0
  104. data/ext/libmemcached-0.32/libmemcached/memcached_storage.c +514 -0
  105. data/ext/libmemcached-0.32/libmemcached/memcached_storage.h +107 -0
  106. data/ext/libmemcached-0.32/libmemcached/memcached_strerror.c +92 -0
  107. data/ext/libmemcached-0.32/libmemcached/memcached_string.c +138 -0
  108. data/ext/libmemcached-0.32/libmemcached/memcached_string.h +53 -0
  109. data/ext/libmemcached-0.32/libmemcached/memcached_touch.c +60 -0
  110. data/ext/libmemcached-0.32/libmemcached/memcached_touch.h +31 -0
  111. data/ext/libmemcached-0.32/libmemcached/memcached_types.h +44 -0
  112. data/ext/libmemcached-0.32/libmemcached/memcached_util.h +15 -0
  113. data/ext/libmemcached-0.32/libmemcached/memcached_verbosity.c +36 -0
  114. data/ext/libmemcached-0.32/libmemcached/memcached_version.c +112 -0
  115. data/ext/libmemcached-0.32/libmemcached/memcached_watchpoint.h +38 -0
  116. data/ext/libmemcached-0.32/libmemcached/murmur_hash.c +76 -0
  117. data/ext/libmemcached-0.32/libmemcached/visibility.h +51 -0
  118. data/ext/libmemcached-0.32/libmemcachedutil/Makefile.am +11 -0
  119. data/ext/libmemcached-0.32/libmemcachedutil/Makefile.in +604 -0
  120. data/ext/libmemcached-0.32/libmemcachedutil/libmemcachedutil.ver +1 -0
  121. data/ext/libmemcached-0.32/libmemcachedutil/memcached_pool.c +170 -0
  122. data/ext/libmemcached-0.32/m4/ac_cxx_compile_stdcxx_0x.m4 +103 -0
  123. data/ext/libmemcached-0.32/m4/ac_cxx_header_stdcxx_98.m4 +67 -0
  124. data/ext/libmemcached-0.32/m4/acx_pthread.m4 +276 -0
  125. data/ext/libmemcached-0.32/m4/byteorder.m4 +40 -0
  126. data/ext/libmemcached-0.32/m4/deprecated.m4 +17 -0
  127. data/ext/libmemcached-0.32/m4/enable_utillib.m4 +16 -0
  128. data/ext/libmemcached-0.32/m4/extensions.m4 +94 -0
  129. data/ext/libmemcached-0.32/m4/hsieh.m4 +18 -0
  130. data/ext/libmemcached-0.32/m4/lib-prefix.m4 +221 -0
  131. data/ext/libmemcached-0.32/m4/libtool.m4 +7831 -0
  132. data/ext/libmemcached-0.32/m4/ltoptions.m4 +369 -0
  133. data/ext/libmemcached-0.32/m4/ltsugar.m4 +123 -0
  134. data/ext/libmemcached-0.32/m4/ltversion.m4 +23 -0
  135. data/ext/libmemcached-0.32/m4/lt~obsolete.m4 +98 -0
  136. data/ext/libmemcached-0.32/m4/memcached.m4 +30 -0
  137. data/ext/libmemcached-0.32/m4/pandora_64bit.m4 +55 -0
  138. data/ext/libmemcached-0.32/m4/pandora_canonical.m4 +151 -0
  139. data/ext/libmemcached-0.32/m4/pandora_check_compiler_version.m4 +37 -0
  140. data/ext/libmemcached-0.32/m4/pandora_check_cxx_standard.m4 +16 -0
  141. data/ext/libmemcached-0.32/m4/pandora_enable_dtrace.m4 +41 -0
  142. data/ext/libmemcached-0.32/m4/pandora_ensure_gcc_version.m4 +36 -0
  143. data/ext/libmemcached-0.32/m4/pandora_have_better_malloc.m4 +54 -0
  144. data/ext/libmemcached-0.32/m4/pandora_have_sasl.m4 +133 -0
  145. data/ext/libmemcached-0.32/m4/pandora_header_assert.m4 +23 -0
  146. data/ext/libmemcached-0.32/m4/pandora_libtool.m4 +15 -0
  147. data/ext/libmemcached-0.32/m4/pandora_optimize.m4 +79 -0
  148. data/ext/libmemcached-0.32/m4/pandora_shared_ptr.m4 +56 -0
  149. data/ext/libmemcached-0.32/m4/pandora_vc_build.m4 +32 -0
  150. data/ext/libmemcached-0.32/m4/pandora_warnings.m4 +262 -0
  151. data/ext/libmemcached-0.32/m4/pod2man.m4 +7 -0
  152. data/ext/libmemcached-0.32/m4/protocol_binary.m4 +23 -0
  153. data/ext/libmemcached-0.32/m4/setsockopt.m4 +57 -0
  154. data/ext/libmemcached-0.32/m4/visibility.m4 +52 -0
  155. data/ext/libmemcached-0.32/support/Makefile.am +4 -0
  156. data/ext/libmemcached-0.32/support/Makefile.in +487 -0
  157. data/ext/libmemcached-0.32/support/libmemcached-fc.spec.in +105 -0
  158. data/ext/libmemcached-0.32/support/libmemcached.pc.in +10 -0
  159. data/ext/libmemcached-0.32/support/libmemcached.spec +105 -0
  160. data/ext/libmemcached-0.32/support/libmemcached.spec.in +105 -0
  161. data/ext/libmemcached-0.32/support/set_benchmark.sh +5 -0
  162. data/ext/libmemcached-0.32/tests/Makefile.am +113 -0
  163. data/ext/libmemcached-0.32/tests/Makefile.in +762 -0
  164. data/ext/libmemcached-0.32/tests/atomsmasher.c +245 -0
  165. data/ext/libmemcached-0.32/tests/function.c +4904 -0
  166. data/ext/libmemcached-0.32/tests/ketama_test_cases.h +108 -0
  167. data/ext/libmemcached-0.32/tests/output.cmp +7 -0
  168. data/ext/libmemcached-0.32/tests/output.res +7 -0
  169. data/ext/libmemcached-0.32/tests/output2.res +46 -0
  170. data/ext/libmemcached-0.32/tests/plus.cpp +293 -0
  171. data/ext/libmemcached-0.32/tests/r/memcat.res +19 -0
  172. data/ext/libmemcached-0.32/tests/r/memcp.res +27 -0
  173. data/ext/libmemcached-0.32/tests/r/memrm.res +19 -0
  174. data/ext/libmemcached-0.32/tests/r/memslap.res +33 -0
  175. data/ext/libmemcached-0.32/tests/r/memstat.res +33 -0
  176. data/ext/libmemcached-0.32/tests/server.c +118 -0
  177. data/ext/libmemcached-0.32/tests/server.h +25 -0
  178. data/ext/libmemcached-0.32/tests/start.c +16 -0
  179. data/ext/libmemcached-0.32/tests/t/memcat.test +4 -0
  180. data/ext/libmemcached-0.32/tests/t/memcp.test +3 -0
  181. data/ext/libmemcached-0.32/tests/t/memrm.test +3 -0
  182. data/ext/libmemcached-0.32/tests/t/memslap.test +5 -0
  183. data/ext/libmemcached-0.32/tests/t/memstat.test +3 -0
  184. data/ext/libmemcached-0.32/tests/test.c +137 -0
  185. data/ext/libmemcached-0.32/tests/test.h +46 -0
  186. data/ext/libmemcached-0.32/tests/udp.c +76 -0
  187. data/ext/rlibmemcached.i +258 -0
  188. data/ext/rlibmemcached_wrap.c +13917 -0
  189. data/lib/memcached/auth.rb +16 -0
  190. data/lib/memcached/behaviors.rb +78 -0
  191. data/lib/memcached/exceptions.rb +84 -0
  192. data/lib/memcached/experimental.rb +48 -0
  193. data/lib/memcached/marshal_codec.rb +10 -0
  194. data/lib/memcached/memcached.rb +732 -0
  195. data/lib/memcached/rails.rb +250 -0
  196. data/lib/memcached.rb +33 -0
  197. data/memcached.gemspec +0 -0
  198. data/test/profile/benchmark.rb +280 -0
  199. data/test/profile/c_profiler.rb +14 -0
  200. data/test/profile/exercise.rb +185 -0
  201. data/test/profile/rb_profiler.rb +21 -0
  202. data/test/profile/valgrind.rb +10 -0
  203. data/test/setup.rb +30 -0
  204. data/test/teardown.rb +0 -0
  205. data/test/test_helper.rb +18 -0
  206. data/test/unit/binding_test.rb +8 -0
  207. data/test/unit/memcached_experimental_test.rb +272 -0
  208. data/test/unit/memcached_test.rb +1487 -0
  209. data/test/unit/rails_test.rb +330 -0
  210. metadata +336 -0
@@ -0,0 +1,510 @@
1
+ #include "common.h"
2
+ #include <math.h>
3
+
4
+ /* Protoypes (static) */
5
+ static memcached_return server_add(memcached_st *ptr, const char *hostname,
6
+ unsigned int port,
7
+ uint32_t weight,
8
+ memcached_connection type);
9
+ memcached_return update_continuum(memcached_st *ptr);
10
+ memcached_return update_live_host_indices(memcached_st *ptr);
11
+
12
+ static int compare_servers(const void *p1, const void *p2)
13
+ {
14
+ int return_value;
15
+ memcached_server_st *a= (memcached_server_st *)p1;
16
+ memcached_server_st *b= (memcached_server_st *)p2;
17
+
18
+ return_value= strcmp(a->hostname, b->hostname);
19
+
20
+ if (return_value == 0)
21
+ {
22
+ return_value= (int) (a->port - b->port);
23
+ }
24
+
25
+ return return_value;
26
+ }
27
+
28
+ static void sort_hosts(memcached_st *ptr)
29
+ {
30
+ if (ptr->number_of_hosts)
31
+ {
32
+ qsort(ptr->hosts, ptr->number_of_hosts, sizeof(memcached_server_st), compare_servers);
33
+ ptr->hosts[0].count= (uint16_t) ptr->number_of_hosts;
34
+ }
35
+ }
36
+
37
+
38
+ memcached_return run_distribution(memcached_st *ptr)
39
+ {
40
+ switch (ptr->distribution)
41
+ {
42
+ case MEMCACHED_DISTRIBUTION_CONSISTENT:
43
+ case MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA:
44
+ return update_continuum(ptr);
45
+ case MEMCACHED_DISTRIBUTION_MODULA:
46
+ if (ptr->flags & MEM_USE_SORT_HOSTS)
47
+ sort_hosts(ptr);
48
+ if (memcached_behavior_get(ptr, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS))
49
+ update_live_host_indices(ptr);
50
+ break;
51
+ case MEMCACHED_DISTRIBUTION_RANDOM:
52
+ if (memcached_behavior_get(ptr, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS))
53
+ update_live_host_indices(ptr);
54
+ break;
55
+ default:
56
+ WATCHPOINT_ASSERT(0); /* We have added a distribution without extending the logic */
57
+ }
58
+
59
+ return MEMCACHED_SUCCESS;
60
+ }
61
+
62
+ void server_list_free(memcached_st *ptr, memcached_server_st *servers)
63
+ {
64
+ unsigned int x;
65
+
66
+ if (servers == NULL)
67
+ return;
68
+
69
+ for (x= 0; x < servers->count; x++)
70
+ if (servers[x].address_info)
71
+ {
72
+ freeaddrinfo(servers[x].address_info);
73
+ servers[x].address_info= NULL;
74
+ }
75
+
76
+ if (ptr)
77
+ ptr->call_free(ptr, servers);
78
+ else
79
+ free(servers);
80
+ }
81
+
82
+ static uint32_t ketama_server_hash(const char *key, unsigned int key_length, int alignment)
83
+ {
84
+ unsigned char results[16];
85
+
86
+ md5_signature((unsigned char*)key, key_length, results);
87
+ return ((uint32_t) (results[3 + alignment * 4] & 0xFF) << 24)
88
+ | ((uint32_t) (results[2 + alignment * 4] & 0xFF) << 16)
89
+ | ((uint32_t) (results[1 + alignment * 4] & 0xFF) << 8)
90
+ | (results[0 + alignment * 4] & 0xFF);
91
+ }
92
+
93
+ memcached_return update_live_host_indices(memcached_st *ptr)
94
+ {
95
+ uint32_t host_index;
96
+ struct timeval now;
97
+ uint32_t i = 0;
98
+ memcached_server_st *list;
99
+
100
+ if (gettimeofday(&now, NULL) != 0)
101
+ {
102
+ ptr->cached_errno = errno;
103
+ return MEMCACHED_ERRNO;
104
+ }
105
+
106
+ if (ptr->live_host_indices == NULL) {
107
+ ptr->live_host_indices = (uint32_t *)ptr->call_malloc(ptr, sizeof(uint32_t) * ptr->number_of_hosts);
108
+ ptr->live_host_indices_size = ptr->number_of_live_hosts;
109
+ }
110
+
111
+ /* somehow we added some hosts. Shouldn't get here much, if at all. */
112
+ if (ptr->live_host_indices_size < ptr->number_of_hosts ) {
113
+ ptr->live_host_indices = (uint32_t *)ptr->call_realloc(ptr, ptr->live_host_indices, sizeof(uint32_t) * ptr->number_of_hosts);
114
+ ptr->live_host_indices_size = ptr->number_of_live_hosts;
115
+ }
116
+
117
+ if (ptr->live_host_indices == NULL)
118
+ return MEMCACHED_FAILURE;
119
+
120
+ list = ptr->hosts;
121
+ for (host_index= 0; host_index < ptr->number_of_hosts; ++host_index)
122
+ {
123
+ if (list[host_index].next_retry <= now.tv_sec) {
124
+ ptr->live_host_indices[i++] = host_index;
125
+ } else if (ptr->next_distribution_rebuild == 0 || list[host_index].next_retry < ptr->next_distribution_rebuild) {
126
+ ptr->next_distribution_rebuild= list[host_index].next_retry;
127
+ }
128
+ }
129
+ ptr->number_of_live_hosts = i;
130
+ return MEMCACHED_SUCCESS;
131
+ }
132
+
133
+ static int continuum_item_cmp(const void *t1, const void *t2)
134
+ {
135
+ memcached_continuum_item_st *ct1= (memcached_continuum_item_st *)t1;
136
+ memcached_continuum_item_st *ct2= (memcached_continuum_item_st *)t2;
137
+
138
+ /* Why 153? Hmmm... */
139
+ WATCHPOINT_ASSERT(ct1->value != 153);
140
+ if (ct1->value == ct2->value)
141
+ return 0;
142
+ else if (ct1->value > ct2->value)
143
+ return 1;
144
+ else
145
+ return -1;
146
+ }
147
+
148
+ memcached_return update_continuum(memcached_st *ptr)
149
+ {
150
+ uint32_t host_index;
151
+ uint32_t continuum_index= 0;
152
+ uint32_t value;
153
+ memcached_server_st *list;
154
+ uint32_t pointer_index;
155
+ uint32_t pointer_counter= 0;
156
+ uint32_t pointer_per_server= MEMCACHED_POINTS_PER_SERVER;
157
+ uint32_t pointer_per_hash= 1;
158
+ uint64_t total_weight= 0;
159
+ uint64_t is_ketama_weighted= 0;
160
+ uint64_t is_auto_ejecting= 0;
161
+ uint32_t points_per_server= 0;
162
+ uint32_t live_servers= 0;
163
+ struct timeval now;
164
+
165
+ if (gettimeofday(&now, NULL) != 0)
166
+ {
167
+ ptr->cached_errno = errno;
168
+ return MEMCACHED_ERRNO;
169
+ }
170
+
171
+ list = ptr->hosts;
172
+
173
+ /* count live servers (those without a retry delay set) */
174
+ is_auto_ejecting= memcached_behavior_get(ptr, MEMCACHED_BEHAVIOR_AUTO_EJECT_HOSTS);
175
+ if (is_auto_ejecting)
176
+ {
177
+ live_servers= 0;
178
+ ptr->next_distribution_rebuild= 0;
179
+ for (host_index= 0; host_index < ptr->number_of_hosts; ++host_index)
180
+ {
181
+ if (list[host_index].next_retry <= now.tv_sec)
182
+ live_servers++;
183
+ else
184
+ {
185
+ if (ptr->next_distribution_rebuild == 0 || list[host_index].next_retry < ptr->next_distribution_rebuild)
186
+ ptr->next_distribution_rebuild= list[host_index].next_retry;
187
+ }
188
+ }
189
+ }
190
+ else
191
+ live_servers= ptr->number_of_hosts;
192
+
193
+ is_ketama_weighted= memcached_behavior_get(ptr, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED);
194
+ points_per_server= (uint32_t) (is_ketama_weighted ? MEMCACHED_POINTS_PER_SERVER_KETAMA : MEMCACHED_POINTS_PER_SERVER);
195
+
196
+ if (live_servers == 0)
197
+ return MEMCACHED_SUCCESS;
198
+
199
+ if (live_servers > ptr->continuum_count)
200
+ {
201
+ memcached_continuum_item_st *new_ptr;
202
+
203
+ new_ptr= ptr->call_realloc(ptr, ptr->continuum,
204
+ sizeof(memcached_continuum_item_st) * (live_servers + MEMCACHED_CONTINUUM_ADDITION) * points_per_server);
205
+
206
+ if (new_ptr == 0)
207
+ return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
208
+
209
+ ptr->continuum= new_ptr;
210
+ ptr->continuum_count= live_servers + MEMCACHED_CONTINUUM_ADDITION;
211
+ }
212
+
213
+ if (is_ketama_weighted)
214
+ {
215
+ for (host_index = 0; host_index < ptr->number_of_hosts; ++host_index)
216
+ {
217
+ if (list[host_index].weight == 0)
218
+ {
219
+ list[host_index].weight = 1;
220
+ }
221
+ if (!is_auto_ejecting || list[host_index].next_retry <= now.tv_sec)
222
+ total_weight += list[host_index].weight;
223
+ }
224
+ }
225
+
226
+ for (host_index = 0; host_index < ptr->number_of_hosts; ++host_index)
227
+ {
228
+ if (is_auto_ejecting && list[host_index].next_retry > now.tv_sec)
229
+ continue;
230
+
231
+ if (is_ketama_weighted)
232
+ {
233
+ float pct = (float)list[host_index].weight / (float)total_weight;
234
+ pointer_per_server= (uint32_t) ((floorf((float) (pct * MEMCACHED_POINTS_PER_SERVER_KETAMA / 4 * (float)live_servers + 0.0000000001))) * 4);
235
+ pointer_per_hash= 4;
236
+ #ifdef DEBUG
237
+ printf("ketama_weighted:%s|%d|%llu|%u\n",
238
+ list[host_index].hostname,
239
+ list[host_index].port,
240
+ (unsigned long long)list[host_index].weight,
241
+ pointer_per_server);
242
+ #endif
243
+ }
244
+ for (pointer_index= 1;
245
+ pointer_index <= pointer_per_server / pointer_per_hash;
246
+ ++pointer_index)
247
+ {
248
+ char sort_host[MEMCACHED_MAX_HOST_SORT_LENGTH]= "";
249
+ size_t sort_host_length;
250
+
251
+ if (list[host_index].port == MEMCACHED_DEFAULT_PORT)
252
+ {
253
+ sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH,
254
+ "%s-%d",
255
+ list[host_index].hostname,
256
+ pointer_index - 1);
257
+
258
+ }
259
+ else
260
+ {
261
+ sort_host_length= (size_t) snprintf(sort_host, MEMCACHED_MAX_HOST_SORT_LENGTH,
262
+ "%s:%d-%d",
263
+ list[host_index].hostname,
264
+ list[host_index].port, pointer_index - 1);
265
+ }
266
+ WATCHPOINT_ASSERT(sort_host_length);
267
+
268
+ if (is_ketama_weighted)
269
+ {
270
+ unsigned int i;
271
+ for (i = 0; i < pointer_per_hash; i++)
272
+ {
273
+ value= ketama_server_hash(sort_host, (uint32_t) sort_host_length, (int) i);
274
+ ptr->continuum[continuum_index].index= host_index;
275
+ ptr->continuum[continuum_index++].value= value;
276
+ }
277
+ }
278
+ else
279
+ {
280
+ value= memcached_generate_hash_value(sort_host, sort_host_length, ptr->hash_continuum);
281
+ ptr->continuum[continuum_index].index= host_index;
282
+ ptr->continuum[continuum_index++].value= value;
283
+ }
284
+ }
285
+ pointer_counter+= pointer_per_server;
286
+ }
287
+
288
+ WATCHPOINT_ASSERT(ptr);
289
+ WATCHPOINT_ASSERT(ptr->continuum);
290
+ WATCHPOINT_ASSERT(ptr->number_of_hosts * MEMCACHED_POINTS_PER_SERVER <= MEMCACHED_CONTINUUM_SIZE);
291
+ ptr->continuum_points_counter= pointer_counter;
292
+ qsort(ptr->continuum, ptr->continuum_points_counter, sizeof(memcached_continuum_item_st), continuum_item_cmp);
293
+
294
+ #ifdef DEBUG
295
+ for (pointer_index= 0; ptr->number_of_hosts && pointer_index < ((live_servers * MEMCACHED_POINTS_PER_SERVER) - 1); pointer_index++)
296
+ {
297
+ WATCHPOINT_ASSERT(ptr->continuum[pointer_index].value <= ptr->continuum[pointer_index + 1].value);
298
+ }
299
+ #endif
300
+
301
+ return MEMCACHED_SUCCESS;
302
+ }
303
+
304
+
305
+ memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *list)
306
+ {
307
+ unsigned int x;
308
+ uint16_t count;
309
+ memcached_server_st *new_host_list;
310
+
311
+ if (!list)
312
+ return MEMCACHED_SUCCESS;
313
+
314
+ count= list[0].count;
315
+ new_host_list= ptr->call_realloc(ptr, ptr->hosts,
316
+ sizeof(memcached_server_st) * (count + ptr->number_of_hosts));
317
+
318
+ if (!new_host_list)
319
+ return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
320
+
321
+ ptr->hosts= new_host_list;
322
+
323
+ for (x= 0; x < count; x++)
324
+ {
325
+ if ((ptr->flags & MEM_USE_UDP && list[x].type != MEMCACHED_CONNECTION_UDP)
326
+ || ((list[x].type == MEMCACHED_CONNECTION_UDP)
327
+ && ! (ptr->flags & MEM_USE_UDP)) )
328
+ return MEMCACHED_INVALID_HOST_PROTOCOL;
329
+
330
+ WATCHPOINT_ASSERT(list[x].hostname[0] != 0);
331
+ memcached_server_create(ptr, &ptr->hosts[ptr->number_of_hosts]);
332
+ /* TODO check return type */
333
+ (void)memcached_server_create_with(ptr, &ptr->hosts[ptr->number_of_hosts], list[x].hostname,
334
+ list[x].port, list[x].weight, list[x].type);
335
+ ptr->number_of_hosts++;
336
+ }
337
+ ptr->hosts[0].count= (uint16_t) ptr->number_of_hosts;
338
+
339
+ return run_distribution(ptr);
340
+ }
341
+
342
+ memcached_return memcached_server_add_unix_socket(memcached_st *ptr,
343
+ const char *filename)
344
+ {
345
+ return memcached_server_add_unix_socket_with_weight(ptr, filename, 0);
346
+ }
347
+
348
+ memcached_return memcached_server_add_unix_socket_with_weight(memcached_st *ptr,
349
+ const char *filename,
350
+ uint32_t weight)
351
+ {
352
+ if (!filename)
353
+ return MEMCACHED_FAILURE;
354
+
355
+ return server_add(ptr, filename, 0, weight, MEMCACHED_CONNECTION_UNIX_SOCKET);
356
+ }
357
+
358
+ memcached_return memcached_server_add_udp(memcached_st *ptr,
359
+ const char *hostname,
360
+ unsigned int port)
361
+ {
362
+ return memcached_server_add_udp_with_weight(ptr, hostname, port, 0);
363
+ }
364
+
365
+ memcached_return memcached_server_add_udp_with_weight(memcached_st *ptr,
366
+ const char *hostname,
367
+ unsigned int port,
368
+ uint32_t weight)
369
+ {
370
+ if (!port)
371
+ port= MEMCACHED_DEFAULT_PORT;
372
+
373
+ if (!hostname)
374
+ hostname= "localhost";
375
+
376
+ return server_add(ptr, hostname, port, weight, MEMCACHED_CONNECTION_UDP);
377
+ }
378
+
379
+ memcached_return memcached_server_add(memcached_st *ptr,
380
+ const char *hostname,
381
+ unsigned int port)
382
+ {
383
+ return memcached_server_add_with_weight(ptr, hostname, port, 0);
384
+ }
385
+
386
+ memcached_return memcached_server_add_with_weight(memcached_st *ptr,
387
+ const char *hostname,
388
+ unsigned int port,
389
+ uint32_t weight)
390
+ {
391
+ if (!port)
392
+ port= MEMCACHED_DEFAULT_PORT;
393
+
394
+ if (!hostname)
395
+ hostname= "localhost";
396
+
397
+ return server_add(ptr, hostname, port, weight, MEMCACHED_CONNECTION_TCP);
398
+ }
399
+
400
+ static memcached_return server_add(memcached_st *ptr, const char *hostname,
401
+ unsigned int port,
402
+ uint32_t weight,
403
+ memcached_connection type)
404
+ {
405
+ memcached_server_st *new_host_list;
406
+
407
+ if ( (ptr->flags & MEM_USE_UDP && type != MEMCACHED_CONNECTION_UDP)
408
+ || ( (type == MEMCACHED_CONNECTION_UDP) && !(ptr->flags & MEM_USE_UDP) ) )
409
+ return MEMCACHED_INVALID_HOST_PROTOCOL;
410
+
411
+ new_host_list= ptr->call_realloc(ptr, ptr->hosts,
412
+ sizeof(memcached_server_st) * (ptr->number_of_hosts+1));
413
+
414
+ if (new_host_list == NULL)
415
+ return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
416
+
417
+ ptr->hosts= new_host_list;
418
+
419
+ /* TODO: Check return type */
420
+ (void)memcached_server_create_with(ptr, &ptr->hosts[ptr->number_of_hosts], hostname, port, weight, type);
421
+ ptr->number_of_hosts++;
422
+ ptr->hosts[0].count= (uint16_t) ptr->number_of_hosts;
423
+
424
+ return run_distribution(ptr);
425
+ }
426
+
427
+ memcached_return memcached_server_remove(memcached_server_st *st_ptr)
428
+ {
429
+ uint32_t x, host_index;
430
+ memcached_st *ptr= st_ptr->root;
431
+ memcached_server_st *list= ptr->hosts;
432
+
433
+ for (x= 0, host_index= 0; x < ptr->number_of_hosts; x++)
434
+ {
435
+ if (strncmp(list[x].hostname, st_ptr->hostname, MEMCACHED_MAX_HOST_LENGTH) != 0 || list[x].port != st_ptr->port)
436
+ {
437
+ if (host_index != x)
438
+ memcpy(list+host_index, list+x, sizeof(memcached_server_st));
439
+ host_index++;
440
+ }
441
+ }
442
+ ptr->number_of_hosts= host_index;
443
+
444
+ if (st_ptr->address_info)
445
+ {
446
+ freeaddrinfo(st_ptr->address_info);
447
+ st_ptr->address_info= NULL;
448
+ }
449
+ run_distribution(ptr);
450
+
451
+ return MEMCACHED_SUCCESS;
452
+ }
453
+
454
+ memcached_server_st *memcached_server_list_append(memcached_server_st *ptr,
455
+ const char *hostname, unsigned int port,
456
+ memcached_return *error)
457
+ {
458
+ return memcached_server_list_append_with_weight(ptr, hostname, port, 0, error);
459
+ }
460
+
461
+ memcached_server_st *memcached_server_list_append_with_weight(memcached_server_st *ptr,
462
+ const char *hostname, unsigned int port,
463
+ uint32_t weight,
464
+ memcached_return *error)
465
+ {
466
+ unsigned int count;
467
+ memcached_server_st *new_host_list;
468
+
469
+ if (hostname == NULL || error == NULL)
470
+ return NULL;
471
+
472
+ if (!port)
473
+ port= MEMCACHED_DEFAULT_PORT;
474
+
475
+ /* Increment count for hosts */
476
+ count= 1;
477
+ if (ptr != NULL)
478
+ {
479
+ count+= ptr[0].count;
480
+ }
481
+
482
+ new_host_list= (memcached_server_st *)realloc(ptr, sizeof(memcached_server_st) * count);
483
+ if (!new_host_list)
484
+ {
485
+ *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
486
+ return NULL;
487
+ }
488
+
489
+ /* TODO: Check return type */
490
+ memcached_server_create_with(NULL, &new_host_list[count-1], hostname, port, weight, MEMCACHED_CONNECTION_TCP);
491
+
492
+ /* Backwards compatibility hack */
493
+ new_host_list[0].count= (uint16_t) count;
494
+
495
+ *error= MEMCACHED_SUCCESS;
496
+ return new_host_list;
497
+ }
498
+
499
+ unsigned int memcached_server_list_count(memcached_server_st *ptr)
500
+ {
501
+ if (ptr == NULL)
502
+ return 0;
503
+
504
+ return ptr[0].count;
505
+ }
506
+
507
+ void memcached_server_list_free(memcached_server_st *ptr)
508
+ {
509
+ server_list_free(NULL, ptr);
510
+ }
@@ -0,0 +1,31 @@
1
+ /*
2
+ * Summary: Internal functions used by the library. Not for public use!
3
+ * Copy: See Copyright for the status of this software.
4
+ *
5
+ * Author: Trond Norbye
6
+ */
7
+
8
+ #ifndef LIBMEMCACHED_MEMCACHED_INTERNAL_H
9
+ #define LIBMEMCACHED_MEMCACHED_INTERNAL_H
10
+
11
+ #if defined(BUILDING_LIBMEMCACHED)
12
+
13
+ #ifdef __cplusplus
14
+ extern "C" {
15
+ #endif
16
+
17
+ LIBMEMCACHED_LOCAL
18
+ void libmemcached_free(memcached_st *ptr, void *mem);
19
+ LIBMEMCACHED_LOCAL
20
+ void *libmemcached_malloc(memcached_st *ptr, const size_t size);
21
+ LIBMEMCACHED_LOCAL
22
+ void *libmemcached_realloc(memcached_st *ptr, void *mem, const size_t size);
23
+ LIBMEMCACHED_LOCAL
24
+ void *libmemcached_calloc(memcached_st *ptr, size_t nelem, size_t size);
25
+
26
+ #ifdef __cplusplus
27
+ }
28
+ #endif
29
+
30
+ #endif /* BUILDING_LIBMEMCACHED */
31
+ #endif /* LIBMEMCACHED_MEMCACHED_INTERNAL_H */