Show
Ignore:
Timestamp:
10/03/07 23:45:44 (2 years ago)
Author:
plindner
Message:

update for prepend operation, thread safe version from Maxim replacing Filipe's implementation

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/server/memcached.c

    r624 r627  
    720720    int stored = 0; 
    721721 
     722    item *new_it = NULL; 
     723    int flags; 
     724 
    722725    if (old_it != NULL && comm == NREAD_ADD) { 
    723726        /* add only adds a nonexistent item, but promote to head of LRU */ 
    724727        do_item_update(old_it); 
    725     } else if (!old_it && comm == NREAD_REPLACE) { 
     728    } else if (!old_it && (comm == NREAD_REPLACE 
     729        || comm == NREAD_APPEND || comm == NREAD_PREPEND)) 
     730    { 
    726731        /* replace only replaces an existing value; don't store */ 
    727     } else if (delete_locked && (comm == NREAD_REPLACE || comm == NREAD_ADD)) { 
     732    } else if (delete_locked && (comm == NREAD_REPLACE || comm == NREAD_ADD 
     733        || comm == NREAD_APPEND || comm == NREAD_PREPEND)) 
     734    { 
    728735        /* replace and add can't override delete locks; don't store */ 
    729736    } else { 
     737 
     738        /* 
     739         * Append - combine new and old record into single one. Here it's 
     740         * atomic and thread-safe. 
     741         */ 
     742 
     743        if (comm == NREAD_APPEND || comm == NREAD_PREPEND) { 
     744 
     745            /* we have it and old_it here - alloc memory to hold both */ 
     746            /* flags was already lost - so recover them from ITEM_suffix(it) */ 
     747 
     748            flags = (int) strtol(ITEM_suffix(it), (char **) NULL, 10); 
     749 
     750            new_it = do_item_alloc(key, it->nkey, flags, it->exptime, it->nbytes + old_it->nbytes - 2 /* CRLF */); 
     751 
     752            if (new_it == NULL) { 
     753                /* SERVER_ERROR out of memory */ 
     754                return 0; 
     755            } 
     756 
     757            /* copy data from it and old_it to new_it */ 
     758 
     759            if (comm == NREAD_APPEND) { 
     760                memcpy(ITEM_data(new_it), ITEM_data(old_it), old_it->nbytes); 
     761                memcpy(ITEM_data(new_it) + old_it->nbytes - 2 /* CRLF */, ITEM_data(it), it->nbytes); 
     762            } else { 
     763                /* NREAD_PREPEND */  
     764                memcpy(ITEM_data(new_it), ITEM_data(it), it->nbytes); 
     765                memcpy(ITEM_data(new_it) + it->nbytes - 2 /* CRLF */, ITEM_data(old_it), old_it->nbytes); 
     766            } 
     767 
     768            it = new_it; 
     769        } 
     770 
    730771        /* "set" commands can override the delete lock 
    731772           window... in which case we have to find the old hidden item 
     
    743784    } 
    744785 
    745     if (old_it) 
     786    if (old_it != NULL) 
    746787        do_item_remove(old_it);         /* release our reference */ 
     788    if (new_it != NULL) 
     789        do_item_remove(new_it); 
     790 
    747791    return stored; 
    748792} 
     
    12091253    } 
    12101254 
    1211     /* Check if append -- if yes, search for previous entry, and allocate memory for both */ 
    1212     if( comm == NREAD_APPEND ){ 
    1213        old_it = assoc_find(key,nkey); 
    1214  
    1215        if( old_it && (old_it->nbytes)>2 ){ // previous must be more than \r\n 
    1216           old_vlen = old_it->nbytes - 2; 
    1217           vlen += old_vlen;                // append the length of old data 
    1218        } else { 
    1219           comm = NREAD_REPLACE;            // no old entry: treat as replace 
    1220        } 
    1221     } 
    1222  
    12231255    it = item_alloc(key, nkey, flags, realtime(exptime), vlen+2); 
    12241256 
     
    12691301    c->ritem = ITEM_data(it); 
    12701302    c->rlbytes = it->nbytes; 
    1271  
    1272  
    1273     /* If append, prepend old data before new - adjust item, rlbytes variables too 
    1274      * Now that data has been merged, treat simply as a replace command 
    1275      */ 
    1276     if (comm == NREAD_APPEND ){ 
    1277        memcpy( c->ritem, ITEM_data(old_it), old_vlen ); 
    1278        c->ritem += old_vlen; 
    1279        c->rlbytes -= old_vlen; 
    1280        comm = NREAD_REPLACE; 
    1281     } 
    1282  
    12831303    c->item_comm = comm; 
    12841304    conn_set_state(c, conn_nread); 
     
    15151535                (strcmp(tokens[COMMAND_TOKEN].value, "set") == 0 && (comm = NREAD_SET)) || 
    15161536                (strcmp(tokens[COMMAND_TOKEN].value, "replace") == 0 && (comm = NREAD_REPLACE)) || 
     1537                (strcmp(tokens[COMMAND_TOKEN].value, "prepend") == 0 && (comm = NREAD_PREPEND)) || 
    15171538                (strcmp(tokens[COMMAND_TOKEN].value, "append") == 0 && (comm = NREAD_APPEND)) )) { 
    15181539