summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDustin Sallings <dustin@spy.net>2009-03-07 00:05:34 -0800
committerDustin Sallings <dustin@spy.net>2009-03-07 00:05:34 -0800
commit3e0307821d0bb937ef76258a2cc9a8abbde717cb (patch)
tree74b63d99c943fb029ef14f042dcf46ccf4250009
parenta77d12b0d8f6a49f33e6a5e0a7e420173750f0e6 (diff)
downloadmemcached-3e0307821d0bb937ef76258a2cc9a8abbde717cb.tar.gz
incr/decr stats
-rw-r--r--memcached.c50
-rw-r--r--memcached.h4
-rw-r--r--slabs.c14
-rwxr-xr-xt/stats.t45
-rw-r--r--thread.c16
5 files changed, 124 insertions, 5 deletions
diff --git a/memcached.c b/memcached.c
index 7c5bce9..18d2078 100644
--- a/memcached.c
+++ b/memcached.c
@@ -1096,6 +1096,15 @@ static void complete_incr_bin(conn *c) {
item_remove(it); /* release our reference */
write_bin_error(c, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS, 0);
} else {
+
+ pthread_mutex_lock(&c->thread->stats.mutex);
+ if (c->cmd == PROTOCOL_BINARY_CMD_INCREMENT) {
+ c->thread->stats.incr_misses++;
+ } else {
+ c->thread->stats.decr_misses++;
+ }
+ pthread_mutex_unlock(&c->thread->stats.mutex);
+
write_bin_error(c, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT, 0);
}
#undef INCR_MAX_STORAGE_LEN
@@ -2178,6 +2187,30 @@ static char *server_stats(uint32_t (*add_stats)(char *buf, const char *key,
pos += nbytes;
*buflen += nbytes;
+ vlen = sprintf(val, "%llu", (unsigned long long)thread_stats.incr_misses);
+ nbytes = add_stats(pos, "incr_misses", strlen("incr_misses"), val, vlen,
+ (void *)c);
+ pos += nbytes;
+ *buflen += nbytes;
+
+ vlen = sprintf(val, "%llu", (unsigned long long)slab_stats.incr_hits);
+ nbytes = add_stats(pos, "incr_hits", strlen("incr_hits"), val, vlen,
+ (void *)c);
+ pos += nbytes;
+ *buflen += nbytes;
+
+ vlen = sprintf(val, "%llu", (unsigned long long)thread_stats.decr_misses);
+ nbytes = add_stats(pos, "decr_misses", strlen("decr_misses"), val, vlen,
+ (void *)c);
+ pos += nbytes;
+ *buflen += nbytes;
+
+ vlen = sprintf(val, "%llu", (unsigned long long)slab_stats.decr_hits);
+ nbytes = add_stats(pos, "decr_hits", strlen("decr_hits"), val, vlen,
+ (void *)c);
+ pos += nbytes;
+ *buflen += nbytes;
+
vlen = sprintf(val, "%llu", (unsigned long long)thread_stats.bytes_read);
nbytes = add_stats(pos, "bytes_read", strlen("bytes_read"), val, vlen,
(void *)c);
@@ -2620,6 +2653,14 @@ static void process_arithmetic_command(conn *c, token_t *tokens, const size_t nt
it = item_get(key, nkey);
if (!it) {
+ pthread_mutex_lock(&c->thread->stats.mutex);
+ if (incr) {
+ c->thread->stats.incr_misses++;
+ } else {
+ c->thread->stats.decr_misses++;
+ }
+ pthread_mutex_unlock(&c->thread->stats.mutex);
+
out_string(c, "NOT_FOUND");
return;
}
@@ -2664,6 +2705,15 @@ char *do_add_delta(conn *c, item *it, const bool incr, const int64_t delta, char
}
MEMCACHED_COMMAND_DECR(c->sfd, ITEM_key(it), it->nkey, value);
}
+
+ pthread_mutex_lock(&c->thread->stats.mutex);
+ if (incr) {
+ c->thread->stats.slab_stats[it->slabs_clsid].incr_hits++;
+ } else {
+ c->thread->stats.slab_stats[it->slabs_clsid].decr_hits++;
+ }
+ pthread_mutex_unlock(&c->thread->stats.mutex);
+
sprintf(buf, "%llu", (unsigned long long)value);
res = strlen(buf);
if (res + 2 > it->nbytes) { /* need to realloc */
diff --git a/memcached.h b/memcached.h
index d16d52f..8ccf980 100644
--- a/memcached.h
+++ b/memcached.h
@@ -71,6 +71,8 @@ struct slab_stats {
uint64_t set_cmds;
uint64_t get_hits;
uint64_t delete_hits;
+ uint64_t incr_hits;
+ uint64_t decr_hits;
};
struct thread_stats {
@@ -78,6 +80,8 @@ struct thread_stats {
uint64_t get_cmds;
uint64_t get_misses;
uint64_t delete_misses;
+ uint64_t incr_misses;
+ uint64_t decr_misses;
uint64_t bytes_read;
uint64_t bytes_written;
struct slab_stats slab_stats[MAX_NUMBER_OF_SLAB_CLASSES];
diff --git a/slabs.c b/slabs.c
index 360f285..2c3bde2 100644
--- a/slabs.c
+++ b/slabs.c
@@ -462,6 +462,20 @@ static char *do_slabs_stats(uint32_t (*add_stats)(char *buf, const char *key,
linelen += nbytes;
bufcurr += nbytes;
+ sprintf(key, "%d:incr_hits", i);
+ sprintf(val, "%llu",
+ (unsigned long long)thread_stats.slab_stats[i].incr_hits);
+ nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c);
+ linelen += nbytes;
+ bufcurr += nbytes;
+
+ sprintf(key, "%d:decr_hits", i);
+ sprintf(val, "%llu",
+ (unsigned long long)thread_stats.slab_stats[i].decr_hits);
+ nbytes = add_stats(bufcurr, key, strlen(key), val, strlen(val), c);
+ linelen += nbytes;
+ bufcurr += nbytes;
+
total++;
}
}
diff --git a/t/stats.t b/t/stats.t
index 1cbc788..cdbfa1a 100755
--- a/t/stats.t
+++ b/t/stats.t
@@ -1,7 +1,7 @@
#!/usr/bin/perl
use strict;
-use Test::More tests => 26;
+use Test::More tests => 51;
use FindBin qw($Bin);
use lib "$Bin/lib";
use MemcachedTest;
@@ -31,6 +31,10 @@ my $sock = $server->sock;
## STAT get_misses 0
## STAT delete_misses 0
## STAT delete_hits 4
+## STAT incr_misses 1
+## STAT incr_hits 2
+## STAT decr_misses 1
+## STAT decr_hits 1
## STAT evictions 0
## STAT bytes_read 7
## STAT bytes_written 0
@@ -39,10 +43,10 @@ my $sock = $server->sock;
my $stats = mem_stats($sock);
# Test number of keys
-is(scalar(keys(%$stats)), 24, "24 stats values");
+is(scalar(keys(%$stats)), 28, "28 stats values");
# Test initial state
-foreach my $key (qw(curr_items total_items bytes cmd_get cmd_set get_hits evictions get_misses bytes_written)) {
+foreach my $key (qw(curr_items total_items bytes cmd_get cmd_set get_hits evictions get_misses bytes_written delete_hits delete_misses incr_hits incr_misses decr_hits decr_misses)) {
is($stats->{$key}, 0, "initial $key is zero");
}
@@ -57,8 +61,6 @@ my $stats = mem_stats($sock);
foreach my $key (qw(total_items curr_items cmd_get cmd_set get_hits)) {
is($stats->{$key}, 1, "after one set/one get $key is 1");
}
-is($stats->{delete_hits}, 0);
-is($stats->{delete_misses}, 0);
my $cache_dump = mem_stats($sock, " cachedump 1 100");
ok(defined $cache_dump->{'foo'}, "got foo from cachedump");
@@ -76,3 +78,36 @@ is(scalar <$sock>, "NOT_FOUND\r\n", "shouldn't delete foo again");
my $stats = mem_stats($sock);
is($stats->{delete_hits}, 1);
is($stats->{delete_misses}, 1);
+
+# incr stats
+
+sub check_incr_stats {
+ my ($ih, $im, $dh, $dm) = @_;
+ my $stats = mem_stats($sock);
+
+ is($stats->{incr_hits}, $ih);
+ is($stats->{incr_misses}, $im);
+ is($stats->{decr_hits}, $dh);
+ is($stats->{decr_misses}, $dm);
+}
+
+print $sock "incr i 1\r\n";
+is(scalar <$sock>, "NOT_FOUND\r\n", "shouldn't incr a missing thing");
+check_incr_stats(0, 1, 0, 0);
+
+print $sock "decr d 1\r\n";
+is(scalar <$sock>, "NOT_FOUND\r\n", "shouldn't decr a missing thing");
+check_incr_stats(0, 1, 0, 1);
+
+print $sock "set n 0 0 1\r\n0\r\n";
+is(scalar <$sock>, "STORED\r\n", "stored n");
+
+print $sock "incr n 3\r\n";
+is(scalar <$sock>, "3\r\n", "incr works");
+check_incr_stats(1, 1, 0, 1);
+
+print $sock "decr n 1\r\n";
+is(scalar <$sock>, "2\r\n", "decr works");
+check_incr_stats(1, 1, 1, 1);
+
+
diff --git a/thread.c b/thread.c
index 7d49784..8ff5a59 100644
--- a/thread.c
+++ b/thread.c
@@ -537,6 +537,8 @@ void threadlocal_stats_reset(void) {
threads[ii].stats.get_cmds = 0;
threads[ii].stats.get_misses = 0;
threads[ii].stats.delete_misses = 0;
+ threads[ii].stats.incr_misses = 0;
+ threads[ii].stats.decr_misses = 0;
threads[ii].stats.bytes_read = 0;
threads[ii].stats.bytes_written = 0;
@@ -544,6 +546,8 @@ void threadlocal_stats_reset(void) {
threads[ii].stats.slab_stats[sid].set_cmds = 0;
threads[ii].stats.slab_stats[sid].get_hits = 0;
threads[ii].stats.slab_stats[sid].delete_hits = 0;
+ threads[ii].stats.slab_stats[sid].incr_hits = 0;
+ threads[ii].stats.slab_stats[sid].decr_hits = 0;
}
pthread_mutex_unlock(&threads[ii].stats.mutex);
@@ -556,6 +560,8 @@ void threadlocal_stats_aggregate(struct thread_stats *stats) {
stats->get_cmds = 0;
stats->get_misses = 0;
stats->delete_misses = 0;
+ stats->incr_misses = 0;
+ stats->decr_misses = 0;
stats->bytes_written = 0;
stats->bytes_read = 0;
@@ -568,6 +574,8 @@ void threadlocal_stats_aggregate(struct thread_stats *stats) {
stats->get_cmds += threads[ii].stats.get_cmds;
stats->get_misses += threads[ii].stats.get_misses;
stats->delete_misses += threads[ii].stats.delete_misses;
+ stats->decr_misses += threads[ii].stats.decr_misses;
+ stats->incr_misses += threads[ii].stats.incr_misses;
stats->bytes_read += threads[ii].stats.bytes_read;
stats->bytes_written += threads[ii].stats.bytes_written;
@@ -578,6 +586,10 @@ void threadlocal_stats_aggregate(struct thread_stats *stats) {
threads[ii].stats.slab_stats[sid].get_hits;
stats->slab_stats[sid].delete_hits +=
threads[ii].stats.slab_stats[sid].delete_hits;
+ stats->slab_stats[sid].decr_hits +=
+ threads[ii].stats.slab_stats[sid].decr_hits;
+ stats->slab_stats[sid].incr_hits +=
+ threads[ii].stats.slab_stats[sid].incr_hits;
}
pthread_mutex_unlock(&threads[ii].stats.mutex);
@@ -590,11 +602,15 @@ void slab_stats_aggregate(struct thread_stats *stats, struct slab_stats *out) {
out->set_cmds = 0;
out->get_hits = 0;
out->delete_hits = 0;
+ out->incr_hits = 0;
+ out->decr_hits = 0;
for (sid = 0; sid < MAX_NUMBER_OF_SLAB_CLASSES; sid++) {
out->set_cmds += stats->slab_stats[sid].set_cmds;
out->get_hits += stats->slab_stats[sid].get_hits;
out->delete_hits += stats->slab_stats[sid].delete_hits;
+ out->decr_hits += stats->slab_stats[sid].decr_hits;
+ out->incr_hits += stats->slab_stats[sid].incr_hits;
}
}