Anybody can have a try:
-----------------------------------------------
# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1 (127.0.0.1).
Escape character is '^]'.
get test
END
add test 0 0 4
9999
STORED
incr test 1
10000
get test
VALUE test 0 5
10000
END
decr test 1
9999
get test
VALUE test 0 5
9999
END
--------------
The vlen does not shrink when *decr* from 10000 to 9999, it is still 5!!
This bug does not affect most dynamic language client(php .etc), but
for clients that
use this vlen, they don't work, for example, libmemcache.
Also it does not follow the memcache protocol.
Here comes the pacth(for trunk code):
===========================================================
--- memcached-trunk/memcached.c 2007-10-18 15:57:28.000000000 +0800
+++ memcached-new/memcached.c   2007-10-18 15:54:49.000000000 +0800
@@ -1366,6 +1366,7 @@ char *do_add_delta(item *it, const bool
    char *ptr;
    int64_t value;
    int res;
+    item *new_it;

    ptr = ITEM_data(it);
    while ((*ptr != '\0') && (*ptr < '0' && *ptr > '9')) ptr++;    //
BUG: can't be true
@@ -1384,20 +1385,17 @@ char *do_add_delta(item *it, const bool
    }
    sprintf(buf, "%llu", value);
    res = strlen(buf);
-    if (res + 2 > it->nbytes) { /* need to realloc */
-        item *new_it;
-        new_it = do_item_alloc(ITEM_key(it), it->nkey,
atoi(ITEM_suffix(it) + 1), it->exptime, res + 2 );
-        if (new_it == 0) {
-            return "SERVER_ERROR out of memory";
-        }
-        memcpy(ITEM_data(new_it), buf, res);
-        memcpy(ITEM_data(new_it) + res, "\r\n", 3);
-        do_item_replace(it, new_it);
-        do_item_remove(new_it);       /* release our reference */
-    } else { /* replace in-place */
-        memcpy(ITEM_data(it), buf, res);
-        memset(ITEM_data(it) + res, ' ', it->nbytes - res - 2);
+
+    /* just alloc one, not plan to new one only when res + 2 > it->nbytes */
+    new_it = do_item_alloc(ITEM_key(it), it->nkey,
atoi(ITEM_suffix(it) + 1), it->exptime, res + 2 );
+
+    if (new_it == 0) {
+        return "SERVER_ERROR out of memory";
    }
+    memcpy(ITEM_data(new_it), buf, res);
+    memcpy(ITEM_data(new_it) + res, "\r\n", 3);
+    do_item_replace(it, new_it);
+    do_item_remove(new_it);       /* release our reference */

    return buf;
 }

========================================================

--
Steve Chu
http://www.sina.com

Attachment: decr-vlen-bug.patch
Description: Binary data

Reply via email to