Command processing

Brian Aker brian at tangent.org
Tue Mar 11 14:16:07 UTC 2008


Hi!

On Mar 10, 2008, at 8:07 AM, Håkan Waara wrote:

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

With so few tokens, and a few which are primarily hot, it is better to  
use string comparisons then a hash. A hash is relatively more  
expensive for this sort of operation.

Cheers,
	-Brian

BTW Roy, it would be nice to see some of this becomes enums.

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

--
_______________________________________________________
Brian "Krow" Aker, brian at tangent.org
Seattle, Washington
http://krow.net/                     <-- Me
http://tangent.org/                <-- Software
_______________________________________________________
You can't grep a dead tree.





More information about the memcached mailing list