nutcracker 0.2.3

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 (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