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