[PATCH 1/3] Use GPerf for command parameter names.
Tomash Brechko
tomash.brechko at gmail.com
Wed Nov 7 19:51:09 UTC 2007
diff --git a/trunk/server/Makefile.am b/trunk/server/Makefile.am
index 91db1a2..612641a 100644
--- a/trunk/server/Makefile.am
+++ b/trunk/server/Makefile.am
@@ -2,7 +2,7 @@ bin_PROGRAMS = memcached memcached-debug
memcached_SOURCES = memcached.c slabs.c slabs.h items.c items.h \
assoc.c assoc.h memcached.h thread.c stats.c stats.h \
- command.c command.h
+ command.c command.h param.c
memcached_debug_SOURCES = $(memcached_SOURCES)
memcached_CPPFLAGS = -DNDEBUG
memcached_LDADD = @LIBOBJS@
@@ -10,11 +10,12 @@ memcached_debug_LDADD = $(memcached_LDADD)
SUBDIRS = doc
DIST_DIRS = scripts
-EXTRA_DIST = doc scripts TODO t memcached.spec command.gperf command.c
+EXTRA_DIST = doc scripts TODO t memcached.spec \
+ command.gperf command.c param.gperf param.c
-$(srcdir)/command.c: $(srcdir)/command.gperf
- $(GPERF) --output-file="$@" $^
+$(srcdir)/command.c $(srcdir)/param.c: %.c: %.gperf
+ $(GPERF) --output-file="$@" $*.gperf
test: memcached-debug
prove $(srcdir)/t
diff --git a/trunk/server/command.h b/trunk/server/command.h
index dadb6d8..4d46a3a 100644
--- a/trunk/server/command.h
+++ b/trunk/server/command.h
@@ -40,4 +40,32 @@ const struct command *
get_command(const char *str, unsigned int len);
+enum param_code
+{
+ PARAM_CACHEDUMP,
+ PARAM_DETAIL,
+ PARAM_DUMP,
+ PARAM_ITEMS,
+ PARAM_MALLOC,
+ PARAM_MAPS,
+ PARAM_OFF,
+ PARAM_ON,
+ PARAM_REASSIGN,
+ PARAM_RESET,
+ PARAM_SIZES,
+ PARAM_SLABS
+};
+
+struct param
+{
+ const char *name;
+ enum param_code code;
+};
+
+
+extern
+const struct param *
+get_param(const char *str, unsigned int len);
+
+
#endif /* ! COMMAND_H */
diff --git a/trunk/server/memcached.c b/trunk/server/memcached.c
index b3c5eb4..4d464f1 100644
--- a/trunk/server/memcached.c
+++ b/trunk/server/memcached.c
@@ -873,31 +873,42 @@ static void write_and_free(conn *c, char *buf, int bytes) {
}
}
-inline static void process_stats_detail(conn *c, const char *command) {
+inline static void process_stats_detail(conn *c, token_t *tokens) {
+ struct param *param;
+
assert(c != NULL);
- if (strcmp(command, "on") == 0) {
+ param = get_param(tokens[2].value, tokens[2].length);
+ if (!param) {
+ out_string(c, "CLIENT_ERROR usage: stats detail on|off|dump");
+ return;
+ }
+
+ switch (param->code) {
+ case PARAM_ON:
settings.detail_enabled = 1;
out_string(c, "OK");
- }
- else if (strcmp(command, "off") == 0) {
+ break;
+ case PARAM_OFF:
settings.detail_enabled = 0;
out_string(c, "OK");
- }
- else if (strcmp(command, "dump") == 0) {
- int len;
- char *stats = stats_prefix_dump(&len);
- write_and_free(c, stats, len);
- }
- else {
+ break;
+ case PARAM_DUMP:
+ {
+ int len;
+ char *stats = stats_prefix_dump(&len);
+ write_and_free(c, stats, len);
+ }
+ break;
+ default:
out_string(c, "CLIENT_ERROR usage: stats detail on|off|dump");
+ break;
}
}
static void process_stat(conn *c, token_t *tokens, const size_t ntokens) {
rel_time_t now = current_time;
- char *command;
- char *subcommand;
+ struct param *param;
assert(c != NULL);
@@ -906,9 +917,7 @@ static void process_stat(conn *c, token_t *tokens, const size_t ntokens) {
return;
}
- command = tokens[COMMAND_TOKEN].value;
-
- if (ntokens == 2 && strcmp(command, "stats") == 0) {
+ if (ntokens == 2) {
char temp[1024];
pid_t pid = getpid();
char *pos = temp;
@@ -949,125 +958,139 @@ static void process_stat(conn *c, token_t *tokens, const size_t ntokens) {
return;
}
- subcommand = tokens[SUBCOMMAND_TOKEN].value;
+ param = get_param(tokens[SUBCOMMAND_TOKEN].value,
+ tokens[SUBCOMMAND_TOKEN].length);
+ if (!param) {
+ out_string(c, "ERROR");
+ return;
+ }
- if (strcmp(subcommand, "reset") == 0) {
+ switch (param->code) {
+ case PARAM_RESET:
stats_reset();
out_string(c, "RESET");
return;
- }
#ifdef HAVE_MALLOC_H
#ifdef HAVE_STRUCT_MALLINFO
- if (strcmp(subcommand, "malloc") == 0) {
- char temp[512];
- struct mallinfo info;
- char *pos = temp;
-
- info = mallinfo();
- pos += sprintf(pos, "STAT arena_size %d\r\n", info.arena);
- pos += sprintf(pos, "STAT free_chunks %d\r\n", info.ordblks);
- pos += sprintf(pos, "STAT fastbin_blocks %d\r\n", info.smblks);
- pos += sprintf(pos, "STAT mmapped_regions %d\r\n", info.hblks);
- pos += sprintf(pos, "STAT mmapped_space %d\r\n", info.hblkhd);
- pos += sprintf(pos, "STAT max_total_alloc %d\r\n", info.usmblks);
- pos += sprintf(pos, "STAT fastbin_space %d\r\n", info.fsmblks);
- pos += sprintf(pos, "STAT total_alloc %d\r\n", info.uordblks);
- pos += sprintf(pos, "STAT total_free %d\r\n", info.fordblks);
- pos += sprintf(pos, "STAT releasable_space %d\r\nEND", info.keepcost);
- out_string(c, temp);
+ case PARAM_MALLOC:
+ {
+ char temp[512];
+ struct mallinfo info;
+ char *pos = temp;
+
+ info = mallinfo();
+ pos += sprintf(pos, "STAT arena_size %d\r\n", info.arena);
+ pos += sprintf(pos, "STAT free_chunks %d\r\n", info.ordblks);
+ pos += sprintf(pos, "STAT fastbin_blocks %d\r\n", info.smblks);
+ pos += sprintf(pos, "STAT mmapped_regions %d\r\n", info.hblks);
+ pos += sprintf(pos, "STAT mmapped_space %d\r\n", info.hblkhd);
+ pos += sprintf(pos, "STAT max_total_alloc %d\r\n", info.usmblks);
+ pos += sprintf(pos, "STAT fastbin_space %d\r\n", info.fsmblks);
+ pos += sprintf(pos, "STAT total_alloc %d\r\n", info.uordblks);
+ pos += sprintf(pos, "STAT total_free %d\r\n", info.fordblks);
+ pos += sprintf(pos, "STAT releasable_space %d\r\nEND",
+ info.keepcost);
+ out_string(c, temp);
+ }
return;
- }
#endif /* HAVE_STRUCT_MALLINFO */
#endif /* HAVE_MALLOC_H */
#if !defined(WIN32) || !defined(__APPLE__)
- if (strcmp(subcommand, "maps") == 0) {
- char *wbuf;
- int wsize = 8192; /* should be enough */
- int fd;
- int res;
+ case PARAM_MAPS:
+ {
+ char *wbuf;
+ int wsize = 8192; /* should be enough */
+ int fd;
+ int res;
- if ((wbuf = (char *)malloc(wsize)) == NULL) {
- out_string(c, "SERVER_ERROR out of memory");
- return;
- }
+ if ((wbuf = (char *)malloc(wsize)) == NULL) {
+ out_string(c, "SERVER_ERROR out of memory");
+ return;
+ }
- fd = open("/proc/self/maps", O_RDONLY);
- if (fd == -1) {
- out_string(c, "SERVER_ERROR cannot open the maps file");
- free(wbuf);
- return;
- }
+ fd = open("/proc/self/maps", O_RDONLY);
+ if (fd == -1) {
+ out_string(c, "SERVER_ERROR cannot open the maps file");
+ free(wbuf);
+ return;
+ }
- res = read(fd, wbuf, wsize - 6); /* 6 = END\r\n\0 */
- if (res == wsize - 6) {
- out_string(c, "SERVER_ERROR buffer overflow");
- free(wbuf); close(fd);
- return;
- }
- if (res == 0 || res == -1) {
- out_string(c, "SERVER_ERROR can't read the maps file");
- free(wbuf); close(fd);
- return;
+ res = read(fd, wbuf, wsize - 6); /* 6 = END\r\n\0 */
+ if (res == wsize - 6) {
+ out_string(c, "SERVER_ERROR buffer overflow");
+ free(wbuf); close(fd);
+ return;
+ }
+ if (res == 0 || res == -1) {
+ out_string(c, "SERVER_ERROR can't read the maps file");
+ free(wbuf); close(fd);
+ return;
+ }
+ memcpy(wbuf + res, "END\r\n", 5);
+ write_and_free(c, wbuf, res + 5);
+ close(fd);
}
- memcpy(wbuf + res, "END\r\n", 5);
- write_and_free(c, wbuf, res + 5);
- close(fd);
return;
- }
#endif
- if (strcmp(subcommand, "cachedump") == 0) {
+ case PARAM_CACHEDUMP:
+ {
+ char *buf;
+ unsigned int bytes, id, limit = 0;
- char *buf;
- unsigned int bytes, id, limit = 0;
+ if(ntokens < 5) {
+ out_string(c, "CLIENT_ERROR bad command line");
+ return;
+ }
- if(ntokens < 5) {
- out_string(c, "CLIENT_ERROR bad command line");
- return;
- }
+ id = strtoul(tokens[2].value, NULL, 10);
+ limit = strtoul(tokens[3].value, NULL, 10);
- id = strtoul(tokens[2].value, NULL, 10);
- limit = strtoul(tokens[3].value, NULL, 10);
+ if(errno == ERANGE) {
+ out_string(c, "CLIENT_ERROR bad command line format");
+ return;
+ }
- if(errno == ERANGE) {
- out_string(c, "CLIENT_ERROR bad command line format");
- return;
+ buf = item_cachedump(id, limit, &bytes);
+ write_and_free(c, buf, bytes);
}
-
- buf = item_cachedump(id, limit, &bytes);
- write_and_free(c, buf, bytes);
return;
- }
- if (strcmp(subcommand, "slabs") == 0) {
- int bytes = 0;
- char *buf = slabs_stats(&bytes);
- write_and_free(c, buf, bytes);
+ case PARAM_SLABS:
+ {
+ int bytes = 0;
+ char *buf = slabs_stats(&bytes);
+ write_and_free(c, buf, bytes);
+ }
return;
- }
- if (strcmp(subcommand, "items") == 0) {
- int bytes = 0;
- char *buf = item_stats(&bytes);
- write_and_free(c, buf, bytes);
+ case PARAM_ITEMS:
+ {
+ int bytes = 0;
+ char *buf = item_stats(&bytes);
+ write_and_free(c, buf, bytes);
+ }
return;
- }
- if (strcmp(subcommand, "detail") == 0) {
+ case PARAM_DETAIL:
if (ntokens < 4)
- process_stats_detail(c, ""); /* outputs the error message */
+ out_string(c, "CLIENT_ERROR usage: stats detail on|off|dump");
else
- process_stats_detail(c, tokens[2].value);
+ process_stats_detail(c, tokens);
return;
- }
- if (strcmp(subcommand, "sizes") == 0) {
- int bytes = 0;
- char *buf = item_stats_sizes(&bytes);
- write_and_free(c, buf, bytes);
+ case PARAM_SIZES:
+ {
+ int bytes = 0;
+ char *buf = item_stats_sizes(&bytes);
+ write_and_free(c, buf, bytes);
+ }
return;
+
+ default:
+ break;
}
out_string(c, "ERROR");
@@ -1676,7 +1699,7 @@ static void process_command(conn *c, char *command) {
conn_set_state(c, conn_closing);
break;
case CMD_SLABS:
- if (strcmp(tokens[COMMAND_TOKEN + 1].value, "reassign") == 0) {
+ if (strcmp(tokens[SUBCOMMAND_TOKEN].value, "reassign") == 0) {
#ifdef ALLOW_SLABS_REASSIGN
int src, dst, rv;
diff --git a/trunk/server/param.gperf b/trunk/server/param.gperf
new file mode 100644
index 0000000..cc1db38
--- /dev/null
+++ b/trunk/server/param.gperf
@@ -0,0 +1,30 @@
+%language=ANSI-C
+%define lookup-function-name get_param
+%compare-lengths
+%compare-strncmp
+%readonly-tables
+%enum
+%includes
+%switch=1
+%struct-type
+%define slot-name name
+%{
+#include "command.h"
+%}
+struct param;
+%%
+#
+# keyword param code
+#
+cachedump, PARAM_CACHEDUMP
+detail, PARAM_DETAIL
+dump, PARAM_DUMP
+items, PARAM_ITEMS
+malloc, PARAM_MALLOC
+maps, PARAM_MAPS
+off, PARAM_OFF
+on, PARAM_ON
+reassign, PARAM_REASSIGN
+reset, PARAM_RESET
+sizes, PARAM_SIZES
+slabs, PARAM_SLABS
--
1.5.3.5.529.ge3d6d
More information about the memcached
mailing list