nutcracker 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. data/README.md +22 -0
  2. data/Rakefile +55 -0
  3. data/bin/nutcracker +2 -0
  4. data/ext/nutcracker/ChangeLog +66 -0
  5. data/ext/nutcracker/LICENSE +177 -0
  6. data/ext/nutcracker/Makefile.am +7 -0
  7. data/ext/nutcracker/Makefile.in +726 -0
  8. data/ext/nutcracker/NOTICE +124 -0
  9. data/ext/nutcracker/README.md +240 -0
  10. data/ext/nutcracker/aclocal.m4 +956 -0
  11. data/ext/nutcracker/conf/nutcracker.leaf.yml +10 -0
  12. data/ext/nutcracker/conf/nutcracker.root.yml +8 -0
  13. data/ext/nutcracker/conf/nutcracker.yml +67 -0
  14. data/ext/nutcracker/config.h.in +316 -0
  15. data/ext/nutcracker/config/config.guess +1561 -0
  16. data/ext/nutcracker/config/config.sub +1686 -0
  17. data/ext/nutcracker/config/depcomp +630 -0
  18. data/ext/nutcracker/config/install-sh +520 -0
  19. data/ext/nutcracker/config/ltmain.sh +8413 -0
  20. data/ext/nutcracker/config/missing +376 -0
  21. data/ext/nutcracker/configure +18862 -0
  22. data/ext/nutcracker/configure.ac +155 -0
  23. data/ext/nutcracker/contrib/Makefile.am +3 -0
  24. data/ext/nutcracker/contrib/Makefile.in +560 -0
  25. data/ext/nutcracker/contrib/yaml-0.1.4.tar.gz +0 -0
  26. data/ext/nutcracker/contrib/yaml-0.1.4/LICENSE +19 -0
  27. data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.am +20 -0
  28. data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.in +736 -0
  29. data/ext/nutcracker/contrib/yaml-0.1.4/README +27 -0
  30. data/ext/nutcracker/contrib/yaml-0.1.4/aclocal.m4 +956 -0
  31. data/ext/nutcracker/contrib/yaml-0.1.4/config.h.in +80 -0
  32. data/ext/nutcracker/contrib/yaml-0.1.4/config/config.guess +1561 -0
  33. data/ext/nutcracker/contrib/yaml-0.1.4/config/config.sub +1686 -0
  34. data/ext/nutcracker/contrib/yaml-0.1.4/config/depcomp +630 -0
  35. data/ext/nutcracker/contrib/yaml-0.1.4/config/install-sh +520 -0
  36. data/ext/nutcracker/contrib/yaml-0.1.4/config/ltmain.sh +8406 -0
  37. data/ext/nutcracker/contrib/yaml-0.1.4/config/missing +376 -0
  38. data/ext/nutcracker/contrib/yaml-0.1.4/configure +13085 -0
  39. data/ext/nutcracker/contrib/yaml-0.1.4/configure.ac +75 -0
  40. data/ext/nutcracker/contrib/yaml-0.1.4/doc/doxygen.cfg +222 -0
  41. data/ext/nutcracker/contrib/yaml-0.1.4/include/yaml.h +1971 -0
  42. data/ext/nutcracker/contrib/yaml-0.1.4/m4/libtool.m4 +7357 -0
  43. data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltoptions.m4 +368 -0
  44. data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltsugar.m4 +123 -0
  45. data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltversion.m4 +23 -0
  46. data/ext/nutcracker/contrib/yaml-0.1.4/m4/lt~obsolete.m4 +92 -0
  47. data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.am +4 -0
  48. data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.in +484 -0
  49. data/ext/nutcracker/contrib/yaml-0.1.4/src/api.c +1392 -0
  50. data/ext/nutcracker/contrib/yaml-0.1.4/src/dumper.c +394 -0
  51. data/ext/nutcracker/contrib/yaml-0.1.4/src/emitter.c +2329 -0
  52. data/ext/nutcracker/contrib/yaml-0.1.4/src/loader.c +432 -0
  53. data/ext/nutcracker/contrib/yaml-0.1.4/src/parser.c +1374 -0
  54. data/ext/nutcracker/contrib/yaml-0.1.4/src/reader.c +465 -0
  55. data/ext/nutcracker/contrib/yaml-0.1.4/src/scanner.c +3570 -0
  56. data/ext/nutcracker/contrib/yaml-0.1.4/src/writer.c +141 -0
  57. data/ext/nutcracker/contrib/yaml-0.1.4/src/yaml_private.h +640 -0
  58. data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.am +8 -0
  59. data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.in +675 -0
  60. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor-alt.c +800 -0
  61. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor.c +1130 -0
  62. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter-alt.c +217 -0
  63. data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter.c +202 -0
  64. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-dumper.c +311 -0
  65. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-emitter.c +327 -0
  66. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-loader.c +63 -0
  67. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-parser.c +63 -0
  68. data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-scanner.c +63 -0
  69. data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-reader.c +354 -0
  70. data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-version.c +29 -0
  71. data/ext/nutcracker/extconf.rb +5 -0
  72. data/ext/nutcracker/m4/libtool.m4 +7376 -0
  73. data/ext/nutcracker/m4/ltoptions.m4 +368 -0
  74. data/ext/nutcracker/m4/ltsugar.m4 +123 -0
  75. data/ext/nutcracker/m4/ltversion.m4 +23 -0
  76. data/ext/nutcracker/m4/lt~obsolete.m4 +92 -0
  77. data/ext/nutcracker/notes/c-styleguide.txt +425 -0
  78. data/ext/nutcracker/notes/debug.txt +96 -0
  79. data/ext/nutcracker/notes/memcache.txt +123 -0
  80. data/ext/nutcracker/notes/recommendation.md +118 -0
  81. data/ext/nutcracker/notes/redis.md +415 -0
  82. data/ext/nutcracker/notes/socket.txt +131 -0
  83. data/ext/nutcracker/scripts/multi_get.sh +26 -0
  84. data/ext/nutcracker/scripts/nutcracker.init +73 -0
  85. data/ext/nutcracker/scripts/nutcracker.spec +52 -0
  86. data/ext/nutcracker/scripts/pipelined_read.sh +23 -0
  87. data/ext/nutcracker/scripts/pipelined_write.sh +29 -0
  88. data/ext/nutcracker/scripts/populate_memcached.sh +24 -0
  89. data/ext/nutcracker/scripts/redis-check.py +23 -0
  90. data/ext/nutcracker/scripts/redis-check.sh +564 -0
  91. data/ext/nutcracker/src/Makefile.am +46 -0
  92. data/ext/nutcracker/src/Makefile.in +726 -0
  93. data/ext/nutcracker/src/hashkit/Makefile.am +22 -0
  94. data/ext/nutcracker/src/hashkit/Makefile.in +501 -0
  95. data/ext/nutcracker/src/hashkit/nc_crc32.c +105 -0
  96. data/ext/nutcracker/src/hashkit/nc_fnv.c +82 -0
  97. data/ext/nutcracker/src/hashkit/nc_hashkit.h +74 -0
  98. data/ext/nutcracker/src/hashkit/nc_hsieh.c +93 -0
  99. data/ext/nutcracker/src/hashkit/nc_jenkins.c +230 -0
  100. data/ext/nutcracker/src/hashkit/nc_ketama.c +240 -0
  101. data/ext/nutcracker/src/hashkit/nc_md5.c +379 -0
  102. data/ext/nutcracker/src/hashkit/nc_modula.c +144 -0
  103. data/ext/nutcracker/src/hashkit/nc_murmur.c +99 -0
  104. data/ext/nutcracker/src/hashkit/nc_one_at_a_time.c +51 -0
  105. data/ext/nutcracker/src/hashkit/nc_random.c +146 -0
  106. data/ext/nutcracker/src/nc.c +573 -0
  107. data/ext/nutcracker/src/nc_array.c +204 -0
  108. data/ext/nutcracker/src/nc_array.h +73 -0
  109. data/ext/nutcracker/src/nc_client.c +189 -0
  110. data/ext/nutcracker/src/nc_client.h +28 -0
  111. data/ext/nutcracker/src/nc_conf.c +1766 -0
  112. data/ext/nutcracker/src/nc_conf.h +134 -0
  113. data/ext/nutcracker/src/nc_connection.c +392 -0
  114. data/ext/nutcracker/src/nc_connection.h +99 -0
  115. data/ext/nutcracker/src/nc_core.c +334 -0
  116. data/ext/nutcracker/src/nc_core.h +131 -0
  117. data/ext/nutcracker/src/nc_event.c +214 -0
  118. data/ext/nutcracker/src/nc_event.h +39 -0
  119. data/ext/nutcracker/src/nc_log.c +254 -0
  120. data/ext/nutcracker/src/nc_log.h +120 -0
  121. data/ext/nutcracker/src/nc_mbuf.c +285 -0
  122. data/ext/nutcracker/src/nc_mbuf.h +67 -0
  123. data/ext/nutcracker/src/nc_message.c +828 -0
  124. data/ext/nutcracker/src/nc_message.h +253 -0
  125. data/ext/nutcracker/src/nc_proxy.c +359 -0
  126. data/ext/nutcracker/src/nc_proxy.h +34 -0
  127. data/ext/nutcracker/src/nc_queue.h +788 -0
  128. data/ext/nutcracker/src/nc_rbtree.c +348 -0
  129. data/ext/nutcracker/src/nc_rbtree.h +47 -0
  130. data/ext/nutcracker/src/nc_request.c +588 -0
  131. data/ext/nutcracker/src/nc_response.c +332 -0
  132. data/ext/nutcracker/src/nc_server.c +841 -0
  133. data/ext/nutcracker/src/nc_server.h +143 -0
  134. data/ext/nutcracker/src/nc_signal.c +131 -0
  135. data/ext/nutcracker/src/nc_signal.h +34 -0
  136. data/ext/nutcracker/src/nc_stats.c +1188 -0
  137. data/ext/nutcracker/src/nc_stats.h +206 -0
  138. data/ext/nutcracker/src/nc_string.c +109 -0
  139. data/ext/nutcracker/src/nc_string.h +112 -0
  140. data/ext/nutcracker/src/nc_util.c +619 -0
  141. data/ext/nutcracker/src/nc_util.h +214 -0
  142. data/ext/nutcracker/src/proto/Makefile.am +14 -0
  143. data/ext/nutcracker/src/proto/Makefile.in +482 -0
  144. data/ext/nutcracker/src/proto/nc_memcache.c +1306 -0
  145. data/ext/nutcracker/src/proto/nc_proto.h +155 -0
  146. data/ext/nutcracker/src/proto/nc_redis.c +2102 -0
  147. data/lib/nutcracker.rb +7 -0
  148. data/lib/nutcracker/version.rb +3 -0
  149. metadata +194 -0
@@ -0,0 +1,120 @@
1
+ /*
2
+ * twemproxy - A fast and lightweight proxy for memcached protocol.
3
+ * Copyright (C) 2011 Twitter, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #ifndef _NC_LOG_H_
19
+ #define _NC_LOG_H_
20
+
21
+ struct logger {
22
+ char *name; /* log file name */
23
+ int level; /* log level */
24
+ int fd; /* log file descriptor */
25
+ int nerror; /* # log error */
26
+ };
27
+
28
+ #define LOG_EMERG 0 /* system in unusable */
29
+ #define LOG_ALERT 1 /* action must be taken immediately */
30
+ #define LOG_CRIT 2 /* critical conditions */
31
+ #define LOG_ERR 3 /* error conditions */
32
+ #define LOG_WARN 4 /* warning conditions */
33
+ #define LOG_NOTICE 5 /* normal but significant condition (default) */
34
+ #define LOG_INFO 6 /* informational */
35
+ #define LOG_DEBUG 7 /* debug messages */
36
+ #define LOG_VERB 8 /* verbose messages */
37
+ #define LOG_VVERB 9 /* verbose messages on crack */
38
+ #define LOG_VVVERB 10 /* verbose messages on ganga */
39
+ #define LOG_PVERB 11 /* periodic verbose messages on crack */
40
+
41
+ #define LOG_MAX_LEN 256 /* max length of log message */
42
+
43
+ /*
44
+ * log_stderr - log to stderr
45
+ * loga - log always
46
+ * loga_hexdump - log hexdump always
47
+ * log_error - error log messages
48
+ * log_warn - warning log messages
49
+ * log_panic - log messages followed by a panic
50
+ * ...
51
+ * log_debug - debug log messages based on a log level
52
+ * log_hexdump - hexadump -C of a log buffer
53
+ */
54
+ #ifdef NC_DEBUG_LOG
55
+
56
+ #define log_debug(_level, ...) do { \
57
+ if (log_loggable(_level) != 0) { \
58
+ _log(__FILE__, __LINE__, 0, __VA_ARGS__); \
59
+ } \
60
+ } while (0)
61
+
62
+ #define log_hexdump(_level, _data, _datalen, ...) do { \
63
+ if (log_loggable(_level) != 0) { \
64
+ _log(__FILE__, __LINE__, 0, __VA_ARGS__); \
65
+ _log_hexdump(__FILE__, __LINE__, (char *)(_data), (int)(_datalen), \
66
+ __VA_ARGS__); \
67
+ } \
68
+ } while (0)
69
+
70
+ #else
71
+
72
+ #define log_debug(_level, ...)
73
+ #define log_hexdump(_level, _data, _datalen, ...)
74
+
75
+ #endif
76
+
77
+ #define log_stderr(...) do { \
78
+ _log_stderr(__VA_ARGS__); \
79
+ } while (0)
80
+
81
+ #define loga(...) do { \
82
+ _log(__FILE__, __LINE__, 0, __VA_ARGS__); \
83
+ } while (0)
84
+
85
+ #define loga_hexdump(_data, _datalen, ...) do { \
86
+ _log(__FILE__, __LINE__, 0, __VA_ARGS__); \
87
+ _log_hexdump(__FILE__, __LINE__, (char *)(_data), (int)(_datalen), \
88
+ __VA_ARGS__); \
89
+ } while (0) \
90
+
91
+ #define log_error(...) do { \
92
+ if (log_loggable(LOG_ALERT) != 0) { \
93
+ _log(__FILE__, __LINE__, 0, __VA_ARGS__); \
94
+ } \
95
+ } while (0)
96
+
97
+ #define log_warn(...) do { \
98
+ if (log_loggable(LOG_WARN) != 0) { \
99
+ _log(__FILE__, __LINE__, 0, __VA_ARGS__); \
100
+ } \
101
+ } while (0)
102
+
103
+ #define log_panic(...) do { \
104
+ if (log_loggable(LOG_EMERG) != 0) { \
105
+ _log(__FILE__, __LINE__, 1, __VA_ARGS__); \
106
+ } \
107
+ } while (0)
108
+
109
+ int log_init(int level, char *filename);
110
+ void log_deinit(void);
111
+ void log_level_up(void);
112
+ void log_level_down(void);
113
+ void log_level_set(int level);
114
+ void log_reopen(void);
115
+ int log_loggable(int level);
116
+ void _log(const char *file, int line, int panic, const char *fmt, ...);
117
+ void _log_stderr(const char *fmt, ...);
118
+ void _log_hexdump(const char *file, int line, char *data, int datalen, const char *fmt, ...);
119
+
120
+ #endif
@@ -0,0 +1,285 @@
1
+ /*
2
+ * twemproxy - A fast and lightweight proxy for memcached protocol.
3
+ * Copyright (C) 2011 Twitter, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #include <stdlib.h>
19
+ #include <string.h>
20
+
21
+ #include <nc_core.h>
22
+
23
+ static uint32_t nfree_mbufq; /* # free mbuf */
24
+ static struct mhdr free_mbufq; /* free mbuf q */
25
+
26
+ static size_t mbuf_chunk_size; /* mbuf chunk size - header + data (const) */
27
+ static size_t mbuf_offset; /* mbuf offset in chunk (const) */
28
+
29
+ static struct mbuf *
30
+ _mbuf_get(void)
31
+ {
32
+ struct mbuf *mbuf;
33
+ uint8_t *buf;
34
+
35
+ if (!STAILQ_EMPTY(&free_mbufq)) {
36
+ ASSERT(nfree_mbufq > 0);
37
+
38
+ mbuf = STAILQ_FIRST(&free_mbufq);
39
+ nfree_mbufq--;
40
+ STAILQ_REMOVE_HEAD(&free_mbufq, next);
41
+
42
+ ASSERT(mbuf->magic == MBUF_MAGIC);
43
+ goto done;
44
+ }
45
+
46
+ buf = nc_alloc(mbuf_chunk_size);
47
+ if (buf == NULL) {
48
+ return NULL;
49
+ }
50
+
51
+ /*
52
+ * mbuf header is at the tail end of the mbuf. This enables us to catch
53
+ * buffer overrun early by asserting on the magic value during get or
54
+ * put operations
55
+ *
56
+ * <------------- mbuf_chunk_size ------------->
57
+ * +-------------------------------------------+
58
+ * | mbuf data | mbuf header |
59
+ * | (mbuf_offset) | (struct mbuf) |
60
+ * +-------------------------------------------+
61
+ * ^ ^ ^ ^^
62
+ * | | | ||
63
+ * \ | | |\
64
+ * mbuf->start \ | | mbuf->end (one byte past valid bound)
65
+ * mbuf->pos \
66
+ * \ mbuf
67
+ * mbuf->last (one byte past valid byte)
68
+ *
69
+ */
70
+ mbuf = (struct mbuf *)(buf + mbuf_offset);
71
+ mbuf->magic = MBUF_MAGIC;
72
+
73
+ done:
74
+ STAILQ_NEXT(mbuf, next) = NULL;
75
+ return mbuf;
76
+ }
77
+
78
+ struct mbuf *
79
+ mbuf_get(void)
80
+ {
81
+ struct mbuf *mbuf;
82
+ uint8_t *buf;
83
+
84
+ mbuf = _mbuf_get();
85
+ if (mbuf == NULL) {
86
+ return NULL;
87
+ }
88
+
89
+ buf = (uint8_t *)mbuf - mbuf_offset;
90
+ mbuf->start = buf;
91
+ mbuf->end = buf + mbuf_offset;
92
+
93
+ ASSERT(mbuf->end - mbuf->start == (int)mbuf_offset);
94
+ ASSERT(mbuf->start < mbuf->end);
95
+
96
+ mbuf->pos = mbuf->start;
97
+ mbuf->last = mbuf->start;
98
+
99
+ log_debug(LOG_VVERB, "get mbuf %p", mbuf);
100
+
101
+ return mbuf;
102
+ }
103
+
104
+ static void
105
+ mbuf_free(struct mbuf *mbuf)
106
+ {
107
+ uint8_t *buf;
108
+
109
+ log_debug(LOG_VVERB, "put mbuf %p len %d", mbuf, mbuf->last - mbuf->pos);
110
+
111
+ ASSERT(STAILQ_NEXT(mbuf, next) == NULL);
112
+ ASSERT(mbuf->magic == MBUF_MAGIC);
113
+
114
+ buf = (uint8_t *)mbuf - mbuf_offset;
115
+ nc_free(buf);
116
+ }
117
+
118
+ void
119
+ mbuf_put(struct mbuf *mbuf)
120
+ {
121
+ log_debug(LOG_VVERB, "put mbuf %p len %d", mbuf, mbuf->last - mbuf->pos);
122
+
123
+ ASSERT(STAILQ_NEXT(mbuf, next) == NULL);
124
+ ASSERT(mbuf->magic == MBUF_MAGIC);
125
+
126
+ nfree_mbufq++;
127
+ STAILQ_INSERT_HEAD(&free_mbufq, mbuf, next);
128
+ }
129
+
130
+ /*
131
+ * Rewind the mbuf by discarding any of the read or unread data that it
132
+ * might hold.
133
+ */
134
+ void
135
+ mbuf_rewind(struct mbuf *mbuf)
136
+ {
137
+ mbuf->pos = mbuf->start;
138
+ mbuf->last = mbuf->start;
139
+ }
140
+
141
+ /*
142
+ * Return the length of data in mbuf. Mbuf cannot contain more than
143
+ * 2^32 bytes (4G).
144
+ */
145
+ uint32_t
146
+ mbuf_length(struct mbuf *mbuf)
147
+ {
148
+ ASSERT(mbuf->last >= mbuf->pos);
149
+
150
+ return (uint32_t)(mbuf->last - mbuf->pos);
151
+ }
152
+
153
+ /*
154
+ * Return the remaining space size for any new data in mbuf. Mbuf cannot
155
+ * contain more than 2^32 bytes (4G).
156
+ */
157
+ uint32_t
158
+ mbuf_size(struct mbuf *mbuf)
159
+ {
160
+ ASSERT(mbuf->end >= mbuf->last);
161
+
162
+ return (uint32_t)(mbuf->end - mbuf->last);
163
+ }
164
+
165
+ /*
166
+ * Return the maximum available space size for data in any mbuf. Mbuf cannot
167
+ * contain more than 2^32 bytes (4G).
168
+ */
169
+ size_t
170
+ mbuf_data_size(void)
171
+ {
172
+ return mbuf_offset;
173
+ }
174
+
175
+ /*
176
+ * Insert mbuf at the tail of the mhdr Q
177
+ */
178
+ void
179
+ mbuf_insert(struct mhdr *mhdr, struct mbuf *mbuf)
180
+ {
181
+ STAILQ_INSERT_TAIL(mhdr, mbuf, next);
182
+ log_debug(LOG_VVERB, "insert mbuf %p len %d", mbuf, mbuf->last - mbuf->pos);
183
+ }
184
+
185
+ /*
186
+ * Remove mbuf from the mhdr Q
187
+ */
188
+ void
189
+ mbuf_remove(struct mhdr *mhdr, struct mbuf *mbuf)
190
+ {
191
+ log_debug(LOG_VVERB, "remove mbuf %p len %d", mbuf, mbuf->last - mbuf->pos);
192
+
193
+ STAILQ_REMOVE(mhdr, mbuf, mbuf, next);
194
+ STAILQ_NEXT(mbuf, next) = NULL;
195
+ }
196
+
197
+ /*
198
+ * Copy n bytes from memory area pos to mbuf.
199
+ *
200
+ * The memory areas should not overlap and the mbuf should have
201
+ * enough space for n bytes.
202
+ */
203
+ void
204
+ mbuf_copy(struct mbuf *mbuf, uint8_t *pos, size_t n)
205
+ {
206
+ if (n == 0) {
207
+ return;
208
+ }
209
+
210
+ /* mbuf has space for n bytes */
211
+ ASSERT(!mbuf_full(mbuf) && n <= mbuf_size(mbuf));
212
+
213
+ /* no overlapping copy */
214
+ ASSERT(pos < mbuf->start || pos >= mbuf->end);
215
+
216
+ nc_memcpy(mbuf->last, pos, n);
217
+ mbuf->last += n;
218
+ }
219
+
220
+ /*
221
+ * Split mbuf h into h and t by copying data from h to t. Before
222
+ * the copy, we invoke a precopy handler cb that will copy a predefined
223
+ * string to the head of t.
224
+ *
225
+ * Return new mbuf t, if the split was successful.
226
+ */
227
+ struct mbuf *
228
+ mbuf_split(struct mhdr *h, uint8_t *pos, mbuf_copy_t cb, void *cbarg)
229
+ {
230
+ struct mbuf *mbuf, *nbuf;
231
+ size_t size;
232
+
233
+ ASSERT(!STAILQ_EMPTY(h));
234
+
235
+ mbuf = STAILQ_LAST(h, mbuf, next);
236
+ ASSERT(pos >= mbuf->pos && pos <= mbuf->last);
237
+
238
+ nbuf = mbuf_get();
239
+ if (nbuf == NULL) {
240
+ return NULL;
241
+ }
242
+
243
+ if (cb != NULL) {
244
+ /* precopy nbuf */
245
+ cb(nbuf, cbarg);
246
+ }
247
+
248
+ /* copy data from mbuf to nbuf */
249
+ size = (size_t)(mbuf->last - pos);
250
+ mbuf_copy(nbuf, pos, size);
251
+
252
+ /* adjust mbuf */
253
+ mbuf->last = pos;
254
+
255
+ log_debug(LOG_VVERB, "split into mbuf %p len %"PRIu32" and nbuf %p len "
256
+ "%"PRIu32" copied %zu bytes", mbuf, mbuf_length(mbuf), nbuf,
257
+ mbuf_length(nbuf), size);
258
+
259
+ return nbuf;
260
+ }
261
+
262
+ void
263
+ mbuf_init(struct instance *nci)
264
+ {
265
+ nfree_mbufq = 0;
266
+ STAILQ_INIT(&free_mbufq);
267
+
268
+ mbuf_chunk_size = nci->mbuf_chunk_size;
269
+ mbuf_offset = mbuf_chunk_size - MBUF_HSIZE;
270
+
271
+ log_debug(LOG_DEBUG, "mbuf hsize %d chunk size %zu offset %zu length %zu",
272
+ MBUF_HSIZE, mbuf_chunk_size, mbuf_offset, mbuf_offset);
273
+ }
274
+
275
+ void
276
+ mbuf_deinit(void)
277
+ {
278
+ while (!STAILQ_EMPTY(&free_mbufq)) {
279
+ struct mbuf *mbuf = STAILQ_FIRST(&free_mbufq);
280
+ mbuf_remove(&free_mbufq, mbuf);
281
+ mbuf_free(mbuf);
282
+ nfree_mbufq--;
283
+ }
284
+ ASSERT(nfree_mbufq == 0);
285
+ }
@@ -0,0 +1,67 @@
1
+ /*
2
+ * twemproxy - A fast and lightweight proxy for memcached protocol.
3
+ * Copyright (C) 2011 Twitter, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #ifndef _NC_MBUF_H_
19
+ #define _NC_MBUF_H_
20
+
21
+ #include <nc_core.h>
22
+
23
+ typedef void (*mbuf_copy_t)(struct mbuf *, void *);
24
+
25
+ struct mbuf {
26
+ uint32_t magic; /* mbuf magic (const) */
27
+ STAILQ_ENTRY(mbuf) next; /* next mbuf */
28
+ uint8_t *pos; /* read marker */
29
+ uint8_t *last; /* write marker */
30
+ uint8_t *start; /* start of buffer (const) */
31
+ uint8_t *end; /* end of buffer (const) */
32
+ };
33
+
34
+ STAILQ_HEAD(mhdr, mbuf);
35
+
36
+ #define MBUF_MAGIC 0xdeadbeef
37
+ #define MBUF_MIN_SIZE 512
38
+ #define MBUF_MAX_SIZE 65536
39
+ #define MBUF_SIZE 16384
40
+ #define MBUF_HSIZE sizeof(struct mbuf)
41
+
42
+ static inline bool
43
+ mbuf_empty(struct mbuf *mbuf)
44
+ {
45
+ return mbuf->pos == mbuf->last ? true : false;
46
+ }
47
+
48
+ static inline bool
49
+ mbuf_full(struct mbuf *mbuf)
50
+ {
51
+ return mbuf->last == mbuf->end ? true : false;
52
+ }
53
+
54
+ void mbuf_init(struct instance *nci);
55
+ void mbuf_deinit(void);
56
+ struct mbuf *mbuf_get(void);
57
+ void mbuf_put(struct mbuf *mbuf);
58
+ void mbuf_rewind(struct mbuf *mbuf);
59
+ uint32_t mbuf_length(struct mbuf *mbuf);
60
+ uint32_t mbuf_size(struct mbuf *mbuf);
61
+ size_t mbuf_data_size(void);
62
+ void mbuf_insert(struct mhdr *mhdr, struct mbuf *mbuf);
63
+ void mbuf_remove(struct mhdr *mhdr, struct mbuf *mbuf);
64
+ void mbuf_copy(struct mbuf *mbuf, uint8_t *pos, size_t n);
65
+ struct mbuf *mbuf_split(struct mhdr *h, uint8_t *pos, mbuf_copy_t cb, void *cbarg);
66
+
67
+ #endif