From 648a07f9abe2affb622f03bfddb65271422f7055 Mon Sep 17 00:00:00 2001 From: dormando Date: Tue, 27 Sep 2011 12:56:59 -0700 Subject: Add an ASCII touch command. Not doing GAT for now since I'd have to iterate through gat/gats/multigat/etc. If there's demand, we can add it. --- memcached.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ t/touch.t | 23 +++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100755 t/touch.t diff --git a/memcached.c b/memcached.c index 54d4eb1..f8316c7 100644 --- a/memcached.c +++ b/memcached.c @@ -2899,6 +2899,48 @@ static void process_update_command(conn *c, token_t *tokens, const size_t ntoken conn_set_state(c, conn_nread); } +static void process_touch_command(conn *c, token_t *tokens, const size_t ntokens) { + char *key; + size_t nkey; + int32_t exptime_int = 0; + item *it; + + assert(c != NULL); + + set_noreply_maybe(c, tokens, ntokens); + + if (tokens[KEY_TOKEN].length > KEY_MAX_LENGTH) { + out_string(c, "CLIENT_ERROR bad command line format"); + return; + } + + key = tokens[KEY_TOKEN].value; + nkey = tokens[KEY_TOKEN].length; + + if (!safe_strtol(tokens[2].value, &exptime_int)) { + out_string(c, "CLIENT_ERROR invalid exptime argument"); + return; + } + + it = item_touch(key, nkey, realtime(exptime_int)); + if (it) { + pthread_mutex_lock(&c->thread->stats.mutex); + c->thread->stats.touch_cmds++; + c->thread->stats.slab_stats[it->slabs_clsid].touch_hits++; + pthread_mutex_unlock(&c->thread->stats.mutex); + + out_string(c, "TOUCHED"); + item_remove(it); + } else { + pthread_mutex_lock(&c->thread->stats.mutex); + c->thread->stats.touch_cmds++; + c->thread->stats.touch_misses++; + pthread_mutex_unlock(&c->thread->stats.mutex); + + out_string(c, "NOT_FOUND"); + } +} + static void process_arithmetic_command(conn *c, token_t *tokens, const size_t ntokens, const bool incr) { char temp[INCR_MAX_STORAGE_LEN]; uint64_t delta; @@ -3160,6 +3202,10 @@ static void process_command(conn *c, char *command) { process_delete_command(c, tokens, ntokens); + } else if ((ntokens == 4 || ntokens == 5) && (strcmp(tokens[COMMAND_TOKEN].value, "touch") == 0)) { + + process_touch_command(c, tokens, ntokens); + } else if (ntokens >= 2 && (strcmp(tokens[COMMAND_TOKEN].value, "stats") == 0)) { process_stat(c, tokens, ntokens); diff --git a/t/touch.t b/t/touch.t new file mode 100755 index 0000000..dd2eba1 --- /dev/null +++ b/t/touch.t @@ -0,0 +1,23 @@ +#!/usr/bin/perl + +use strict; +use Test::More tests => 4; +use FindBin qw($Bin); +use lib "$Bin/lib"; +use MemcachedTest; + + +my $server = new_memcached(); +my $sock = $server->sock; + +# set foo (and should get it) +print $sock "set foo 0 2 6\r\nfooval\r\n"; +is(scalar <$sock>, "STORED\r\n", "stored foo"); +mem_get_is($sock, "foo", "fooval"); + +# touch it +print $sock "touch foo 10\r\n"; +is(scalar <$sock>, "TOUCHED\r\n", "touched foo"); + +sleep 2; +mem_get_is($sock, "foo", "fooval"); -- cgit v1.2.1