Command processing

Roy Lyseng Roy.Lyseng at Sun.COM
Tue Mar 11 15:28:31 UTC 2008



Brian Aker wrote:
> 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.

Good idea, will do that. I just replaced the NREAD_ #defines and 
extended with one for every command...

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