Command processing
Roy Lyseng
Roy.Lyseng at Sun.COM
Mon Mar 10 15:09:51 UTC 2008
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?
I certainly could, but I do not think this is a performance pain point.
But the array of command strings would be a great start for another
optimization.
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
More information about the memcached
mailing list