Show
Ignore:
Timestamp:
10/03/07 19:59:11 (2 years ago)
Author:
plindner
Message:

Incorporate "cas" operation developed by Dustin Sallings
<dustin@…> and implemented by Chris Goffinet
<goffinet@…>. This change allows you to do
atomic changes to an existing key.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/server/memcached.c

    r608 r615  
    10261026 
    10271027/* ntokens is overwritten here... shrug.. */ 
    1028 static inline void process_get_command(conn *c, token_t *tokens, size_t ntokens) { 
     1028static inline void process_get_command(conn *c, token_t *tokens, size_t ntokens, bool return_key_ptr) { 
    10291029    char *key; 
    10301030    size_t nkey; 
     
    10321032    item *it; 
    10331033    token_t *key_token = &tokens[KEY_TOKEN]; 
    1034  
     1034    char suffix[255]; 
     1035    uint32_t in_memory_ptr; 
    10351036    assert(c != NULL); 
    10361037 
     
    10821083                 *   " " + flags + " " + data length + "\r\n" + data (with \r\n) 
    10831084                 */ 
    1084                 if (add_iov(c, "VALUE ", 6) != 0 || 
    1085                     add_iov(c, ITEM_key(it), it->nkey) != 0 || 
    1086                     add_iov(c, ITEM_suffix(it), it->nsuffix + it->nbytes) != 0) 
    1087                     { 
    1088                         break; 
    1089                     } 
     1085 
     1086                if(return_key_ptr == true) 
     1087                { 
     1088                  in_memory_ptr = (uint32_t)item_get(key, nkey); 
     1089                  sprintf(suffix," %d %d %lu\r\n", atoi(ITEM_suffix(it) + 1), it->nbytes - 2, in_memory_ptr); 
     1090                  if (add_iov(c, "VALUE ", 6) != 0 || 
     1091                      add_iov(c, ITEM_key(it), it->nkey) != 0 || 
     1092                      add_iov(c, suffix, strlen(suffix)) != 0 || 
     1093                      add_iov(c, ITEM_data(it), it->nbytes) != 0) 
     1094                      { 
     1095                          break; 
     1096                      } 
     1097                } 
     1098                else 
     1099                { 
     1100                  if (add_iov(c, "VALUE ", 6) != 0 || 
     1101                      add_iov(c, ITEM_key(it), it->nkey) != 0 || 
     1102                      add_iov(c, ITEM_suffix(it), it->nsuffix + it->nbytes) != 0) 
     1103                      { 
     1104                          break; 
     1105                      } 
     1106                } 
     1107 
     1108 
    10901109                if (settings.verbose > 1) 
    10911110                    fprintf(stderr, ">%d sending key %s\n", c->sfd, ITEM_key(it)); 
     
    11361155} 
    11371156 
    1138 static void process_update_command(conn *c, token_t *tokens, const size_t ntokens, int comm) { 
     1157static void process_update_command(conn *c, token_t *tokens, const size_t ntokens, int comm, bool handle_cas) { 
    11391158    char *key; 
    11401159    size_t nkey; 
     
    11421161    time_t exptime; 
    11431162    int vlen; 
     1163    uint32_t req_memory_ptr, in_memory_ptr; 
     1164 
    11441165    item *it; 
    11451166 
     
    11571178    exptime = strtol(tokens[3].value, NULL, 10); 
    11581179    vlen = strtol(tokens[4].value, NULL, 10); 
     1180 
     1181    // does cas value exist? 
     1182    if(tokens[5].value) 
     1183    { 
     1184      req_memory_ptr = strtoull(tokens[5].value, NULL, 10); 
     1185    } 
    11591186 
    11601187    if(errno == ERANGE || ((flags == 0 || exptime == 0) && errno == EINVAL)) { 
     
    11811208 
    11821209    it = item_alloc(key, nkey, flags, realtime(exptime), vlen+2); 
     1210 
     1211    /* HANDLE_CAS VALIDATION */ 
     1212    if(handle_cas == true) 
     1213    { 
     1214      item *itmp=item_get(key, it->nkey); 
     1215      /* Release the reference */ 
     1216      if(itmp) { 
     1217        item_remove(itmp); 
     1218      } 
     1219      in_memory_ptr = (uint32_t)itmp; 
     1220      if(in_memory_ptr == req_memory_ptr) 
     1221      { 
     1222        // validates allow the set 
     1223      } 
     1224      else if(in_memory_ptr) 
     1225      { 
     1226        out_string(c, "EXISTS"); 
     1227 
     1228        /* swallow the data line */ 
     1229        c->write_and_go = conn_swallow; 
     1230        c->sbytes = vlen + 2; 
     1231        return; 
     1232      } 
     1233      else 
     1234      { 
     1235        out_string(c, "NOT FOUND"); 
     1236        /* swallow the data line */ 
     1237        c->write_and_go = conn_swallow; 
     1238        c->sbytes = vlen + 2; 
     1239        return; 
     1240      } 
     1241    } 
    11831242 
    11841243    if (it == 0) { 
     
    14201479 
    14211480    ntokens = tokenize_command(command, tokens, MAX_TOKENS); 
    1422  
    14231481    if (ntokens >= 3 && 
    14241482        ((strcmp(tokens[COMMAND_TOKEN].value, "get") == 0) || 
    14251483         (strcmp(tokens[COMMAND_TOKEN].value, "bget") == 0))) { 
    14261484 
    1427         process_get_command(c, tokens, ntokens); 
     1485        process_get_command(c, tokens, ntokens, false); 
    14281486 
    14291487    } else if (ntokens == 6 && 
     
    14321490                (strcmp(tokens[COMMAND_TOKEN].value, "replace") == 0 && (comm = NREAD_REPLACE)))) { 
    14331491 
    1434         process_update_command(c, tokens, ntokens, comm); 
     1492        process_update_command(c, tokens, ntokens, comm, false); 
     1493 
     1494    } else if (ntokens == 6 && (strcmp(tokens[COMMAND_TOKEN].value, "cas") == 0)) { 
     1495 
     1496        process_update_command(c, tokens, ntokens, comm, true); 
    14351497 
    14361498    } else if (ntokens == 4 && (strcmp(tokens[COMMAND_TOKEN].value, "incr") == 0)) { 
    14371499 
    14381500        process_arithmetic_command(c, tokens, ntokens, 1); 
     1501 
     1502    } else if (ntokens >= 3 && (strcmp(tokens[COMMAND_TOKEN].value, "gets") == 0)) { 
     1503 
     1504        process_get_command(c, tokens, ntokens, true); 
    14391505 
    14401506    } else if (ntokens == 4 && (strcmp(tokens[COMMAND_TOKEN].value, "decr") == 0)) {