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.



Reply via email to