Index: trunk/server/memcached.c
===================================================================
--- trunk/server/memcached.c (revision 615)
+++ trunk/server/memcached.c (revision 619)
@@ -1259,8 +1259,8 @@
 }
 
-static void process_arithmetic_command(conn *c, token_t *tokens, const size_t ntokens, const int incr) {
-    char temp[32];
+static void process_arithmetic_command(conn *c, token_t *tokens, const size_t ntokens, const bool incr) {
+    char temp[sizeof("18446744073709551615")];
     item *it;
-    unsigned int delta;
+    int64_t delta;
     char *key;
     size_t nkey;
@@ -1289,5 +1289,5 @@
     }
 
-    delta = strtoul(tokens[2].value, NULL, 10);
+    delta = strtoll(tokens[2].value, NULL, 10);
 
     if(errno == ERANGE) {
@@ -1316,7 +1316,7 @@
  * returns a response string to send back to the client.
  */
-char *do_add_delta(item *it, const int incr, const unsigned int delta, char *buf) {
+char *do_add_delta(item *it, const bool incr, const int64_t delta, char *buf) {
     char *ptr;
-    uint32_t value;
+    int64_t value;
     int res;
 
@@ -1324,5 +1324,5 @@
     while ((*ptr != '\0') && (*ptr < '0' && *ptr > '9')) ptr++;    // BUG: can't be true
 
-    value = strtoul(ptr, NULL, 10);
+    value = strtoull(ptr, NULL, 10);
 
     if(errno == ERANGE) {
@@ -1330,5 +1330,5 @@
     }
 
-    if (incr != 0)
+    if (incr)
         value += delta;
     else {
@@ -1336,5 +1336,5 @@
         else value -= delta;
     }
-    snprintf(buf, 32, "%u", value);
+    sprintf(buf, "%llu", value);
     res = strlen(buf);
     if (res + 2 > it->nbytes) { /* need to realloc */
Index: trunk/server/ChangeLog
===================================================================
--- trunk/server/ChangeLog (revision 618)
+++ trunk/server/ChangeLog (revision 619)
@@ -12,4 +12,7 @@
 	* Fix for do_item_cachedump() which was returning
 	  an incorrect timestamp.
+	
+	* Switch to unsigned 64-bit increment/decrement counters
+	  from Evan Miller and Dusgtin Sallings.
 
 2007-08-21 Paul Lindner <lindner@inuus.com>
Index: trunk/server/thread.c
===================================================================
--- trunk/server/thread.c (revision 608)
+++ trunk/server/thread.c (revision 619)
@@ -463,5 +463,5 @@
  * Does arithmetic on a numeric item value.
  */
-char *mt_add_delta(item *item, int incr, const unsigned int delta, char *buf) {
+char *mt_add_delta(item *item, int incr, const int64_t delta, char *buf) {
     char *ret;
 
Index: trunk/server/memcached.h
===================================================================
--- trunk/server/memcached.h (revision 603)
+++ trunk/server/memcached.h (revision 619)
@@ -223,5 +223,5 @@
 char *do_defer_delete(item *item, time_t exptime);
 void do_run_deferred_deletes(void);
-char *do_add_delta(item *item, int incr, const unsigned int delta, char *buf);
+char *do_add_delta(item *item, const bool incr, const int64_t delta, char *buf);
 int do_store_item(item *item, int comm);
 conn *conn_new(const int sfd, const int init_state, const int event_flags, const int read_buffer_size, const bool is_udp, struct event_base *base);
@@ -254,5 +254,5 @@
 
 /* Lock wrappers for cache functions that are called from main loop. */
-char *mt_add_delta(item *item, const int incr, const unsigned int delta, char *buf);
+char *mt_add_delta(item *item, const int incr, const int64_t delta, char *buf);
 void mt_assoc_move_next_bucket(void);
 conn *mt_conn_from_freelist(void);
Index: trunk/server/t/incrdecr.t
===================================================================
--- trunk/server/t/incrdecr.t (revision 608)
+++ trunk/server/t/incrdecr.t (revision 619)
@@ -2,5 +2,5 @@
 
 use strict;
-use Test::More tests => 16;
+use Test::More tests => 17;
 use FindBin qw($Bin);
 use lib "$Bin/lib";
@@ -31,12 +31,15 @@
 is(scalar <$sock>, "0\r\n", "- 5 = 0");
 
-print $sock "incr num ".(2**32-2)."\r\n";
-is(scalar <$sock>, (2**32-2)."\r\n", "+ ".(2**32-2)." = ".(2**32-2));
+printf $sock "set num 0 0 10\r\n4294967296\r\n";
+is(scalar <$sock>, "STORED\r\n", "stored 2**32");
 
 print $sock "incr num 1\r\n";
-is(scalar <$sock>, (2**32-1)."\r\n", "+ 1 = ".(2**32-1));
+is(scalar <$sock>, "4294967297\r\n", "4294967296 + 1 = 4294967297");
+
+printf $sock "set num 0 0 %d\r\n18446744073709551615\r\n", length("18446744073709551615");
+is(scalar <$sock>, "STORED\r\n", "stored 2**64-1");
 
 print $sock "incr num 1\r\n";
-is(scalar <$sock>, "0\r\n", "+ 1 = 0");
+is(scalar <$sock>, "0\r\n", "(2**64 - 1) + 1 = 0");
 
 print $sock "decr bogus 5\r\n";
Index: trunk/server/doc/protocol.txt
===================================================================
--- trunk/server/doc/protocol.txt (revision 615)
+++ trunk/server/doc/protocol.txt (revision 619)
@@ -263,5 +263,5 @@
 Commands "incr" and "decr" are used to change data for some item
 in-place, incrementing or decrementing it. The data for the item is
-treated as decimal representation of a 32-bit unsigned integer. If the
+treated as decimal representation of a 64-bit unsigned integer. If the
 current data value does not conform to such a representation, the
 commands behave as if the value were 0. Also, the item must already
@@ -280,5 +280,5 @@
 
 - <value> is the amount by which the client wants to increase/decrease
-the item. It is a decimal representation of a 32-bit unsigned integer.
+the item. It is a decimal representation of a 64-bit unsigned integer.
 
 The response will be one of:
@@ -290,6 +290,6 @@
 
 Note that underflow in the "decr" command is caught: if a client tries
-to decrease the value below 0, the new value will be 0.  Overflow in the
-"incr" command will wrap around the 32 bit mark.
+to decrease the value below 0, the new value will be 0.  Overflow in
+the "incr" command will wrap around the 64 bit mark.
 
 Note also that decrementing a number such that it loses length isn't
