diff options
author | dormando <dormando@rydia.net> | 2011-09-27 12:56:59 -0700 |
---|---|---|
committer | dormando <dormando@rydia.net> | 2011-09-27 13:01:49 -0700 |
commit | 648a07f9abe2affb622f03bfddb65271422f7055 (patch) | |
tree | d424efee44709637eaf8e029e64c9d9cab3fbd21 | |
parent | 62434519d31fd7335164bc3a92f8b60ed5a714c8 (diff) | |
download | memcached-648a07f9abe2affb622f03bfddb65271422f7055.tar.gz |
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.
-rw-r--r-- | memcached.c | 46 | ||||
-rwxr-xr-x | t/touch.t | 23 |
2 files changed, 69 insertions, 0 deletions
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"); |