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.
- data/README.md +22 -0
- data/Rakefile +55 -0
- data/bin/nutcracker +2 -0
- data/ext/nutcracker/ChangeLog +66 -0
- data/ext/nutcracker/LICENSE +177 -0
- data/ext/nutcracker/Makefile.am +7 -0
- data/ext/nutcracker/Makefile.in +726 -0
- data/ext/nutcracker/NOTICE +124 -0
- data/ext/nutcracker/README.md +240 -0
- data/ext/nutcracker/aclocal.m4 +956 -0
- data/ext/nutcracker/conf/nutcracker.leaf.yml +10 -0
- data/ext/nutcracker/conf/nutcracker.root.yml +8 -0
- data/ext/nutcracker/conf/nutcracker.yml +67 -0
- data/ext/nutcracker/config.h.in +316 -0
- data/ext/nutcracker/config/config.guess +1561 -0
- data/ext/nutcracker/config/config.sub +1686 -0
- data/ext/nutcracker/config/depcomp +630 -0
- data/ext/nutcracker/config/install-sh +520 -0
- data/ext/nutcracker/config/ltmain.sh +8413 -0
- data/ext/nutcracker/config/missing +376 -0
- data/ext/nutcracker/configure +18862 -0
- data/ext/nutcracker/configure.ac +155 -0
- data/ext/nutcracker/contrib/Makefile.am +3 -0
- data/ext/nutcracker/contrib/Makefile.in +560 -0
- data/ext/nutcracker/contrib/yaml-0.1.4.tar.gz +0 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/LICENSE +19 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.am +20 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/Makefile.in +736 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/README +27 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/aclocal.m4 +956 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config.h.in +80 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/config.guess +1561 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/config.sub +1686 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/depcomp +630 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/install-sh +520 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/ltmain.sh +8406 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/config/missing +376 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/configure +13085 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/configure.ac +75 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/doc/doxygen.cfg +222 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/include/yaml.h +1971 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/libtool.m4 +7357 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltoptions.m4 +368 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltsugar.m4 +123 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/ltversion.m4 +23 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/m4/lt~obsolete.m4 +92 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.am +4 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/Makefile.in +484 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/api.c +1392 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/dumper.c +394 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/emitter.c +2329 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/loader.c +432 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/parser.c +1374 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/reader.c +465 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/scanner.c +3570 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/writer.c +141 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/src/yaml_private.h +640 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.am +8 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/Makefile.in +675 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor-alt.c +800 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-deconstructor.c +1130 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter-alt.c +217 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/example-reformatter.c +202 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-dumper.c +311 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-emitter.c +327 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-loader.c +63 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-parser.c +63 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/run-scanner.c +63 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-reader.c +354 -0
- data/ext/nutcracker/contrib/yaml-0.1.4/tests/test-version.c +29 -0
- data/ext/nutcracker/extconf.rb +5 -0
- data/ext/nutcracker/m4/libtool.m4 +7376 -0
- data/ext/nutcracker/m4/ltoptions.m4 +368 -0
- data/ext/nutcracker/m4/ltsugar.m4 +123 -0
- data/ext/nutcracker/m4/ltversion.m4 +23 -0
- data/ext/nutcracker/m4/lt~obsolete.m4 +92 -0
- data/ext/nutcracker/notes/c-styleguide.txt +425 -0
- data/ext/nutcracker/notes/debug.txt +96 -0
- data/ext/nutcracker/notes/memcache.txt +123 -0
- data/ext/nutcracker/notes/recommendation.md +118 -0
- data/ext/nutcracker/notes/redis.md +415 -0
- data/ext/nutcracker/notes/socket.txt +131 -0
- data/ext/nutcracker/scripts/multi_get.sh +26 -0
- data/ext/nutcracker/scripts/nutcracker.init +73 -0
- data/ext/nutcracker/scripts/nutcracker.spec +52 -0
- data/ext/nutcracker/scripts/pipelined_read.sh +23 -0
- data/ext/nutcracker/scripts/pipelined_write.sh +29 -0
- data/ext/nutcracker/scripts/populate_memcached.sh +24 -0
- data/ext/nutcracker/scripts/redis-check.py +23 -0
- data/ext/nutcracker/scripts/redis-check.sh +564 -0
- data/ext/nutcracker/src/Makefile.am +46 -0
- data/ext/nutcracker/src/Makefile.in +726 -0
- data/ext/nutcracker/src/hashkit/Makefile.am +22 -0
- data/ext/nutcracker/src/hashkit/Makefile.in +501 -0
- data/ext/nutcracker/src/hashkit/nc_crc32.c +105 -0
- data/ext/nutcracker/src/hashkit/nc_fnv.c +82 -0
- data/ext/nutcracker/src/hashkit/nc_hashkit.h +74 -0
- data/ext/nutcracker/src/hashkit/nc_hsieh.c +93 -0
- data/ext/nutcracker/src/hashkit/nc_jenkins.c +230 -0
- data/ext/nutcracker/src/hashkit/nc_ketama.c +240 -0
- data/ext/nutcracker/src/hashkit/nc_md5.c +379 -0
- data/ext/nutcracker/src/hashkit/nc_modula.c +144 -0
- data/ext/nutcracker/src/hashkit/nc_murmur.c +99 -0
- data/ext/nutcracker/src/hashkit/nc_one_at_a_time.c +51 -0
- data/ext/nutcracker/src/hashkit/nc_random.c +146 -0
- data/ext/nutcracker/src/nc.c +573 -0
- data/ext/nutcracker/src/nc_array.c +204 -0
- data/ext/nutcracker/src/nc_array.h +73 -0
- data/ext/nutcracker/src/nc_client.c +189 -0
- data/ext/nutcracker/src/nc_client.h +28 -0
- data/ext/nutcracker/src/nc_conf.c +1766 -0
- data/ext/nutcracker/src/nc_conf.h +134 -0
- data/ext/nutcracker/src/nc_connection.c +392 -0
- data/ext/nutcracker/src/nc_connection.h +99 -0
- data/ext/nutcracker/src/nc_core.c +334 -0
- data/ext/nutcracker/src/nc_core.h +131 -0
- data/ext/nutcracker/src/nc_event.c +214 -0
- data/ext/nutcracker/src/nc_event.h +39 -0
- data/ext/nutcracker/src/nc_log.c +254 -0
- data/ext/nutcracker/src/nc_log.h +120 -0
- data/ext/nutcracker/src/nc_mbuf.c +285 -0
- data/ext/nutcracker/src/nc_mbuf.h +67 -0
- data/ext/nutcracker/src/nc_message.c +828 -0
- data/ext/nutcracker/src/nc_message.h +253 -0
- data/ext/nutcracker/src/nc_proxy.c +359 -0
- data/ext/nutcracker/src/nc_proxy.h +34 -0
- data/ext/nutcracker/src/nc_queue.h +788 -0
- data/ext/nutcracker/src/nc_rbtree.c +348 -0
- data/ext/nutcracker/src/nc_rbtree.h +47 -0
- data/ext/nutcracker/src/nc_request.c +588 -0
- data/ext/nutcracker/src/nc_response.c +332 -0
- data/ext/nutcracker/src/nc_server.c +841 -0
- data/ext/nutcracker/src/nc_server.h +143 -0
- data/ext/nutcracker/src/nc_signal.c +131 -0
- data/ext/nutcracker/src/nc_signal.h +34 -0
- data/ext/nutcracker/src/nc_stats.c +1188 -0
- data/ext/nutcracker/src/nc_stats.h +206 -0
- data/ext/nutcracker/src/nc_string.c +109 -0
- data/ext/nutcracker/src/nc_string.h +112 -0
- data/ext/nutcracker/src/nc_util.c +619 -0
- data/ext/nutcracker/src/nc_util.h +214 -0
- data/ext/nutcracker/src/proto/Makefile.am +14 -0
- data/ext/nutcracker/src/proto/Makefile.in +482 -0
- data/ext/nutcracker/src/proto/nc_memcache.c +1306 -0
- data/ext/nutcracker/src/proto/nc_proto.h +155 -0
- data/ext/nutcracker/src/proto/nc_redis.c +2102 -0
- data/lib/nutcracker.rb +7 -0
- data/lib/nutcracker/version.rb +3 -0
- 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
|