[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