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