Command processing

Håkan Waara hakan.waara at travelocitynordic.com
Mon Mar 10 15:07:18 UTC 2008


I haven't hacked this code myself, so forgive me if I'm totally wrong, 
but couldn't you use a hash table instead below to avoid any string 
comparison at all?

/Håkan

Roy Lyseng wrote:
> Hi,
>
> I have been looking at structuring the command processing in memcached 
> slightly.
>
> I am thinking about creating an array with info about available commands:
>
> static struct {
>     char *cmdword;    /* Command word string */
>     int   cmd;        /* Command shorthand */
>     int   mintokens;  /* Minimum number of tokens (required) */
>     int   maxtokens;  /* Maximum number of tokens (zero means no 
> limit) */
> } cmds[] = {
>    {"get",        CMD_GET,       3, 0},
>    {"delete",     CMD_DELETE,    3, 5},
>    {"add",        CMD_ADD,       6, 7},
>    {"set",        CMD_SET,       6, 7},
>    {"replace",    CMD_REPLACE,   6, 7},
>    {"prepend",    CMD_PREPEND,   6, 7},
>    {"append",     CMD_APPEND,    6, 7},
>    {"gets",       CMD_GETS,      3, 0},
>    {"cas",        CMD_CAS,       7, 8},
>    {"incr",       CMD_INCR,      4, 5},
>    {"decr",       CMD_DECR,      4, 5},
>    {"bget",       CMD_BGET,      3, 0},
>    {"own",        CMD_OWN,       3, 3},
>    {"disown",     CMD_DISOWN,    3, 3},
>    {"bg",         CMD_BG,        3, 3},
>    {"stats",      CMD_STATS,     2, 0},
>    {"flush_all",  CMD_FLUSH,     2, 4},
>    {"version",    CMD_VERSION,   2, 2},
>    {"quit",       CMD_QUIT,      2, 2},
>    {"slabs",      CMD_SLABS,     5, 5},  /* Next token should be 
> "reassign" */
>    {"verbosity",  CMD_VERBOSITY, 3, 4},
>    {NULL,         -1,            0, 0}   /* Terminate with a NULL 
> string pointer */
> };
>
> I have tried to sort the presumably most frequent commands first.
>
> process_commands() will then do:
>
>     ntokens = tokenize_command(command, tokens, MAX_TOKENS);
>
>     for (i = 0; cmds[i].cmdword != NULL; i++) {
>         if (strcmp(tokens[COMMAND_TOKEN].value, cmds[i].cmdword) == 0) {
>            cmd = cmds[i].cmd;
>            break;
>         }
>     }
>
>     if (cmd < 0) {
>         out_string(c, "ERROR");              /* Token not matched */
>         return;
>     }
>     if (ntokens < cmds[i].mintokens ||
>        (cmds[i].maxtokens > 0 && ntokens > cmds[i].maxtokens)) {
>         out_string(c, "ERROR");              /* Invalid number of 
> tokens for this cmd */
>         return;
>     }
>
>     c->item_comm = cmd;                      /* Command being 
> processed on connection */
>
>     switch (cmd) {
>     case CMD_GET:
>     case CMD_BGET:
>         process_get_command(c, tokens, ntokens, false);
>         break;
> ...
>
> Does this look interesting to you guys?
>
> Before I go any further with this, is there any other information that 
> should be used to characterize commands?
>
> Are there commands that are not in use (BGET?)
>
> More?
>
> Thanks,
> Roy


More information about the memcached mailing list