Revision
14461
Author
rupa
Date
2009-08-07 15:59:23 -0500 (Fri, 07 Aug 2009)

Log Message

make increment/decrement work if the key hasn't been set yet

Modified Paths

Diff

Modified: freeswitch/trunk/src/mod/applications/mod_memcache/mod_memcache.c (14460 => 14461)


--- freeswitch/trunk/src/mod/applications/mod_memcache/mod_memcache.c	2009-08-06 21:40:50 UTC (rev 14460)
+++ freeswitch/trunk/src/mod/applications/mod_memcache/mod_memcache.c	2009-08-07 20:59:23 UTC (rev 14461)
@@ -230,14 +230,40 @@
 			key = argv[1];
 			uint64_t ivalue;
 			unsigned int offset = 1;
+			switch_bool_t increment = SWITCH_TRUE;
+			char *svalue = NULL;
 			if(argc > 2) {
 				offset = (unsigned int)strtol(argv[2], NULL, 10);
+				svalue = argv[2];
+			} else {
+				svalue = "1";
 			}
+			
 			if (!strcasecmp(subcmd, "increment")) {
+				increment = SWITCH_TRUE;
 				rc = memcached_increment(memcached, key, strlen(key), offset, &ivalue);
 			} else if (!strcasecmp(subcmd, "decrement")) {
+				increment = SWITCH_FALSE;
 				rc = memcached_decrement(memcached, key, strlen(key), offset, &ivalue);
 			}
+			if (rc == MEMCACHED_NOTFOUND) {
+				/* ok, trying to incr / decr a value that doesn't exist yet.
+				   Try to add an appropriate initial value.  If someone else beat
+				   us to it, then redo incr/decr.  Otherwise we're good.
+				*/
+				rc = memcached_add(memcached, key, strlen(key), (increment) ? svalue : "0", strlen(svalue), 0, 0);
+				if (rc == MEMCACHED_SUCCESS) {
+					ivalue = (increment) ? offset : 0;
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Initialized inc/dec memcache key: %s to value %d\n", key, offset);
+				} else {
+					if (increment) {
+						rc = memcached_increment(memcached, key, strlen(key), offset, &ivalue);
+					} else {
+						rc = memcached_decrement(memcached, key, strlen(key), offset, &ivalue);
+					}
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Someone else created incr/dec memcache key, resubmitting inc/dec request.\n");
+				}
+			}
 			if (rc == MEMCACHED_SUCCESS) {
 				stream->write_function(stream, "%ld", ivalue);
 			} else {