summaryrefslogtreecommitdiff
path: root/daemon
diff options
context:
space:
mode:
Diffstat (limited to 'daemon')
-rw-r--r--daemon/memcached.c119
-rw-r--r--daemon/memcached.h10
-rw-r--r--daemon/topkeys.c180
-rw-r--r--daemon/topkeys.h56
4 files changed, 42 insertions, 323 deletions
diff --git a/daemon/memcached.c b/daemon/memcached.c
index 226fa1c..cd7ec33 100644
--- a/daemon/memcached.c
+++ b/daemon/memcached.c
@@ -51,15 +51,12 @@ static inline void item_set_cas(const void *cookie, item *it, uint64_t cas) {
SLAB_GUTS(conn, thread_stats, slab_op, thread_op) \
THREAD_GUTS(conn, thread_stats, slab_op, thread_op)
-#define STATS_INCR1(GUTS, conn, slab_op, thread_op, key, nkey) { \
- struct independent_stats *independent_stats = get_independent_stats(conn); \
- struct thread_stats *thread_stats = \
- &independent_stats->thread_stats[conn->thread->index]; \
- topkeys_t *topkeys = independent_stats->topkeys; \
+#define STATS_INCR1(GUTS, conn, slab_op, thread_op, key, nkey) \
+{ \
+ struct thread_stats *thread_stats = get_thread_stats(conn); \
pthread_mutex_lock(&thread_stats->mutex); \
GUTS(conn, thread_stats, slab_op, thread_op); \
pthread_mutex_unlock(&thread_stats->mutex); \
- TK(topkeys, slab_op, key, nkey, current_time); \
}
#define STATS_INCR(conn, op, key, nkey) \
@@ -122,7 +119,6 @@ volatile rel_time_t current_time;
*/
static SOCKET new_socket(struct addrinfo *ai);
static int try_read_command(conn *c);
-static inline struct independent_stats *get_independent_stats(conn *c);
static inline struct thread_stats *get_thread_stats(conn *c);
static void register_callback(ENGINE_HANDLE *eh,
ENGINE_EVENT_TYPE type,
@@ -165,7 +161,7 @@ static time_t process_started; /* when the process was started */
/** file scope variables **/
static conn *listen_conn = NULL;
static struct event_base *main_base;
-static struct independent_stats *default_independent_stats;
+static struct thread_stats *default_thread_stats;
static struct engine_event_handler *engine_event_handlers[MAX_ENGINE_EVENT_TYPE + 1];
@@ -238,7 +234,7 @@ static void stats_reset(const void *cookie) {
stats.total_conns = 0;
stats_prefix_clear();
STATS_UNLOCK();
- threadlocal_stats_reset(get_independent_stats(conn)->thread_stats);
+ threadlocal_stats_reset(get_thread_stats(conn));
settings.engine.v1->reset_stats(settings.engine.v0, cookie);
}
@@ -266,7 +262,6 @@ static void settings_init(void) {
settings.backlog = 1024;
settings.binding_protocol = negotiating_prot;
settings.item_size_max = 1024 * 1024; /* The famous 1MB upper limit. */
- settings.topkeys = 0;
settings.require_sasl = false;
settings.extensions.logger = get_stderr_logger();
}
@@ -1950,14 +1945,6 @@ static void process_bin_stat(conn *c) {
}
} else if (strncmp(subcommand, "aggregate", 9) == 0) {
server_stats(&append_stats, c, true);
- } else if (strncmp(subcommand, "topkeys", 7) == 0) {
- topkeys_t *tk = get_independent_stats(c)->topkeys;
- if (tk != NULL) {
- topkeys_stats(tk, c, current_time, append_stats);
- } else {
- write_bin_packet(c, PROTOCOL_BINARY_RESPONSE_KEY_ENOENT, 0);
- return;
- }
} else {
ret = settings.engine.v1->get_stats(settings.engine.v0, c,
subcommand, nkey,
@@ -3676,10 +3663,7 @@ inline static void process_stats_detail(conn *c, const char *command) {
}
static void aggregate_callback(void *in, void *out) {
- struct thread_stats *out_thread_stats = out;
- struct independent_stats *in_independent_stats = in;
- threadlocal_stats_aggregate(in_independent_stats->thread_stats,
- out_thread_stats);
+ threadlocal_stats_aggregate(in, out);
}
/* return server specific stats only */
@@ -3696,7 +3680,7 @@ static void server_stats(ADD_STAT add_stats, conn *c, bool aggregate) {
aggregate_callback,
&thread_stats);
} else {
- threadlocal_stats_aggregate(get_independent_stats(c)->thread_stats,
+ threadlocal_stats_aggregate(get_thread_stats(c),
&thread_stats);
}
@@ -3859,7 +3843,6 @@ static void process_stat_settings(ADD_STAT add_stats, void *c) {
#endif
APPEND_STAT("auth_required_sasl", "%s", settings.require_sasl ? "yes" : "no");
APPEND_STAT("item_size_max", "%d", settings.item_size_max);
- APPEND_STAT("topkeys", "%d", settings.topkeys);
for (EXTENSION_DAEMON_DESCRIPTOR *ptr = settings.extensions.daemons;
ptr != NULL;
@@ -3941,14 +3924,6 @@ static char *process_stat(conn *c, token_t *tokens, const size_t ntokens) {
return NULL;
} else if (strcmp(subcommand, "aggregate") == 0) {
server_stats(&append_stats, c, true);
- } else if (strcmp(subcommand, "topkeys") == 0) {
- topkeys_t *tk = get_independent_stats(c)->topkeys;
- if (tk != NULL) {
- topkeys_stats(tk, c, current_time, append_stats);
- } else {
- out_string(c, "ERROR");
- return NULL;
- }
} else {
/* getting here means that the subcommand is either engine specific or
is invalid. query the engine and see. */
@@ -6154,7 +6129,6 @@ static void usage(void) {
printf("-e config Pass config as configuration options to the storage engine\n");
printf("\nEnvironment variables:\n"
"MEMCACHED_PORT_FILENAME File to write port information to\n"
- "MEMCACHED_TOP_KEYS Number of top keys to keep track of\n"
"MEMCACHED_REQS_TAP_EVENT Similar to -R but for tap_ship_log\n");
}
@@ -6373,48 +6347,46 @@ static ENGINE_ERROR_CODE release_cookie(const void *cookie) {
return ENGINE_SUCCESS;
}
-static int num_independent_stats(void) {
+static inline int num_thread_stats(void) {
return settings.num_threads + 1;
}
-static void *new_independent_stats(void) {
- int ii;
- int nrecords = num_independent_stats();
- struct independent_stats *independent_stats = calloc(sizeof(independent_stats) + sizeof(struct thread_stats) * nrecords, 1);
- if (settings.topkeys > 0)
- independent_stats->topkeys = topkeys_init(settings.topkeys);
- for (ii = 0; ii < nrecords; ii++)
- pthread_mutex_init(&independent_stats->thread_stats[ii].mutex, NULL);
- return independent_stats;
+static void *new_thread_stats(void) {
+ int nrecords = num_thread_stats();
+
+ struct thread_stats *ts = calloc(nrecords, sizeof(*ts));
+ if (ts != NULL) {
+ for (int ii = 0; ii < nrecords; ii++) {
+ pthread_mutex_init(&ts[ii].mutex, NULL);
+ }
+ }
+ return ts;
}
-static void release_independent_stats(void *stats) {
- int ii;
- int nrecords = num_independent_stats();
- struct independent_stats *independent_stats = stats;
- if (independent_stats->topkeys)
- topkeys_free(independent_stats->topkeys);
- for (ii = 0; ii < nrecords; ii++)
- pthread_mutex_destroy(&independent_stats->thread_stats[ii].mutex);
- free(independent_stats);
+static void release_thread_stats(void *stats) {
+ struct thread_stats *ts = stats;
+ if (ts != NULL) {
+ int nrecords = num_thread_stats();
+ for (int ii = 0; ii < nrecords; ii++) {
+ pthread_mutex_destroy(&ts[ii].mutex);
+ }
+ free(ts);
+ }
}
-static inline struct independent_stats *get_independent_stats(conn *c) {
- struct independent_stats *independent_stats;
+static inline struct thread_stats *get_thread_stats(conn *c) {
+ struct thread_stats *ts;
if (settings.engine.v1->get_stats_struct != NULL) {
- independent_stats = settings.engine.v1->get_stats_struct(settings.engine.v0, (const void *)c);
- if (independent_stats == NULL)
- independent_stats = default_independent_stats;
+ ts = settings.engine.v1->get_stats_struct(settings.engine.v0, c);
+ if (ts == NULL) {
+ ts = default_thread_stats;
+ }
} else {
- independent_stats = default_independent_stats;
+ ts = default_thread_stats;
}
- return independent_stats;
-}
-static inline struct thread_stats *get_thread_stats(conn *c) {
- struct independent_stats *independent_stats = get_independent_stats(c);
- assert(c->thread->index < num_independent_stats());
- return &independent_stats->thread_stats[c->thread->index];
+ assert(c->thread->index < num_thread_stats());
+ return &ts[c->thread->index];
}
static void register_callback(ENGINE_HANDLE *eh,
@@ -6436,8 +6408,9 @@ static rel_time_t get_current_time(void)
}
static void count_eviction(const void *cookie, const void *key, const int nkey) {
- topkeys_t *tk = get_independent_stats((conn*)cookie)->topkeys;
- TK(tk, evictions, key, nkey, get_current_time());
+ (void)cookie;
+ (void)key;
+ (void)nkey;
}
/**
@@ -6814,8 +6787,8 @@ static SERVER_HANDLE_V1 *get_server_api(void)
};
static SERVER_STAT_API server_stat_api = {
- .new_stats = new_independent_stats,
- .release_stats = release_independent_stats,
+ .new_stats = new_thread_stats,
+ .release_stats = release_thread_stats,
.evicting = count_eviction
};
@@ -7261,14 +7234,6 @@ int main (int argc, char **argv) {
exit(EXIT_FAILURE);
}
- char *topkeys_env = getenv("MEMCACHED_TOP_KEYS");
- if (topkeys_env != NULL) {
- settings.topkeys = atoi(topkeys_env);
- if (settings.topkeys < 0) {
- settings.topkeys = 0;
- }
- }
-
if (settings.require_sasl) {
if (!protocol_specified) {
settings.binding_protocol = binary_prot;
@@ -7469,7 +7434,7 @@ int main (int argc, char **argv) {
exit(EXIT_FAILURE);
}
- default_independent_stats = new_independent_stats();
+ default_thread_stats = new_thread_stats();
#ifndef __WIN32__
/*
diff --git a/daemon/memcached.h b/daemon/memcached.h
index 9b1e184..625b841 100644
--- a/daemon/memcached.h
+++ b/daemon/memcached.h
@@ -14,7 +14,6 @@
#include <memcached/extension.h>
#include "cache.h"
-#include "topkeys.h"
#include "sasl_defs.h"
@@ -143,15 +142,6 @@ struct thread_stats {
struct slab_stats slab_stats[MAX_NUMBER_OF_SLAB_CLASSES];
};
-
-/**
- * The stats structure the engine keeps track of
- */
-struct independent_stats {
- topkeys_t *topkeys;
- struct thread_stats thread_stats[];
-};
-
/**
* Global stats.
*/
diff --git a/daemon/topkeys.c b/daemon/topkeys.c
deleted file mode 100644
index 3dc3e1d..0000000
--- a/daemon/topkeys.c
+++ /dev/null
@@ -1,180 +0,0 @@
-#include <sys/types.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <inttypes.h>
-#include <string.h>
-#include <pthread.h>
-#include <memcached/genhash.h>
-#include "topkeys.h"
-
-static topkey_item_t *topkey_item_init(const void *key, int nkey, rel_time_t ctime) {
- topkey_item_t *item = calloc(sizeof(topkey_item_t) + nkey, 1);
- assert(item);
- assert(key);
- assert(nkey > 0);
- item->nkey = nkey;
- item->ctime = ctime;
- item->atime = ctime;
- /* Copy the key into the part trailing the struct */
- memcpy(item->key, key, nkey);
- return item;
-}
-
-static inline size_t topkey_item_size(const topkey_item_t *item) {
- return sizeof(topkey_item_t) + item->nkey;
-}
-
-static inline topkey_item_t* topkeys_tail(topkeys_t *tk) {
- return (topkey_item_t*)(tk->list.prev);
-}
-
-static int my_hash_eq(const void *k1, size_t nkey1,
- const void *k2, size_t nkey2) {
- return nkey1 == nkey2 && memcmp(k1, k2, nkey1) == 0;
-}
-
-topkeys_t *topkeys_init(int max_keys) {
- topkeys_t *tk = calloc(sizeof(topkeys_t), 1);
- if (tk == NULL) {
- return NULL;
- }
-
- pthread_mutex_init(&tk->mutex, NULL);
- tk->max_keys = max_keys;
- tk->list.next = &tk->list;
- tk->list.prev = &tk->list;
-
- static struct hash_ops my_hash_ops = {
- .hashfunc = genhash_string_hash,
- .hasheq = my_hash_eq,
- .dupKey = NULL,
- .dupValue = NULL,
- .freeKey = NULL,
- .freeValue = NULL,
- };
-
- tk->hash = genhash_init(max_keys, my_hash_ops);
- if (tk->hash == NULL) {
- return NULL;
- }
- return tk;
-}
-
-void topkeys_free(topkeys_t *tk) {
- pthread_mutex_destroy(&tk->mutex);
- genhash_free(tk->hash);
- dlist_t *p = tk->list.next;
- while (p != &tk->list) {
- dlist_t *tmp = p->next;
- free(p);
- p = tmp;
- }
-}
-
-static inline void dlist_remove(dlist_t *list) {
- assert(list->prev->next == list);
- assert(list->next->prev == list);
- list->prev->next = list->next;
- list->next->prev = list->prev;
-}
-
-static inline void dlist_insert_after(dlist_t *list, dlist_t *new) {
- new->next = list->next;
- new->prev = list;
- list->next->prev = new;
- list->next = new;
-}
-
-static inline void dlist_iter(dlist_t *list,
- void (*iterfunc)(dlist_t *item, void *arg),
- void *arg)
-{
- dlist_t *p = list;
- while ((p = p->next) != list) {
- iterfunc(p, arg);
- }
-}
-
-static inline void topkeys_item_delete(topkeys_t *tk, topkey_item_t *item) {
- genhash_delete(tk->hash, item->key, item->nkey);
- dlist_remove(&item->list);
- --tk->nkeys;
- free(item);
-}
-
-topkey_item_t *topkeys_item_get_or_create(topkeys_t *tk, const void *key, size_t nkey, const rel_time_t ctime) {
- topkey_item_t *item = genhash_find(tk->hash, key, nkey);
- if (item == NULL) {
- item = topkey_item_init(key, nkey, ctime);
- if (item != NULL) {
- if (++tk->nkeys > tk->max_keys) {
- topkeys_item_delete(tk, topkeys_tail(tk));
- }
- genhash_update(tk->hash, item->key, item->nkey,
- item, topkey_item_size(item));
- } else {
- return NULL;
- }
- } else {
- dlist_remove(&item->list);
- }
- dlist_insert_after(&tk->list, &item->list);
- return item;
-}
-
-static inline void append_stat(const void *cookie,
- const char *name,
- size_t namelen,
- const char *key,
- size_t nkey,
- int value,
- ADD_STAT add_stats) {
- char key_str[128];
- char val_str[128];
- int klen, vlen;
-
- klen = sizeof(key_str) - namelen - 2;
- if (nkey < klen) {
- klen = nkey;
- }
- memcpy(key_str, key, klen);
- key_str[klen] = '.';
- memcpy(&key_str[klen+1], name, namelen + 1);
- klen += namelen + 1;
- vlen = snprintf(val_str, sizeof(val_str) - 1, "%d", value);
- add_stats(key_str, klen, val_str, vlen, cookie);
-}
-
-struct tk_context {
- const void *cookie;
- ADD_STAT add_stat;
- rel_time_t current_time;
-};
-
-#define TK_FMT(name) #name "=%d,"
-#define TK_ARGS(name) item->name,
-
-static void tk_iterfunc(dlist_t *list, void *arg) {
- struct tk_context *c = arg;
- topkey_item_t *item = (topkey_item_t*)list;
- char val_str[TK_MAX_VAL_LEN];
- /* This line is magical. The missing comma before item->ctime is because the TK_ARGS macro ends with a comma. */
- int vlen = snprintf(val_str, sizeof(val_str) - 1, TK_OPS(TK_FMT)"ctime=%"PRIu32",atime=%"PRIu32, TK_OPS(TK_ARGS)
- c->current_time - item->ctime, c->current_time - item->atime);
- c->add_stat(item->key, item->nkey, val_str, vlen, c->cookie);
-}
-
-ENGINE_ERROR_CODE topkeys_stats(topkeys_t *tk,
- const void *cookie,
- const rel_time_t current_time,
- ADD_STAT add_stat) {
- struct tk_context context;
- context.cookie = cookie;
- context.add_stat = add_stat;
- context.current_time = current_time;
- assert(tk);
- pthread_mutex_lock(&tk->mutex);
- dlist_iter(&tk->list, tk_iterfunc, &context);
- pthread_mutex_unlock(&tk->mutex);
- return ENGINE_SUCCESS;
-}
diff --git a/daemon/topkeys.h b/daemon/topkeys.h
deleted file mode 100644
index 35102ca..0000000
--- a/daemon/topkeys.h
+++ /dev/null
@@ -1,56 +0,0 @@
-#ifndef TOPKEYS_H
-#define TOPKEYS_H 1
-
-#include <memcached/engine.h>
-#include <memcached/genhash.h>
-
-/* A list of operations for which we have int stats */
-#define TK_OPS(C) C(get_hits) C(get_misses) C(cmd_set) C(incr_hits) \
- C(incr_misses) C(decr_hits) C(decr_misses) \
- C(delete_hits) C(delete_misses) C(evictions) \
- C(cas_hits) C(cas_badval) C(cas_misses)
-
-#define TK_MAX_VAL_LEN 250
-
-/* Update the correct stat for a given operation */
-#define TK(tk, op, key, nkey, ctime) { \
- if (tk) { \
- assert(key); \
- assert(nkey > 0); \
- pthread_mutex_lock(&tk->mutex); \
- topkey_item_t *tmp = topkeys_item_get_or_create( \
- (tk), (key), (nkey), (ctime)); \
- tmp->op++; \
- pthread_mutex_unlock(&tk->mutex); \
- } \
-}
-
-typedef struct dlist {
- struct dlist *next;
- struct dlist *prev;
-} dlist_t;
-
-typedef struct topkey_item {
- dlist_t list; /* Must be at the beginning because we downcast! */
- int nkey;
- rel_time_t ctime, atime; /* Time this item was created/last accessed */
-#define TK_CUR(name) int name;
- TK_OPS(TK_CUR)
-#undef TK_CUR
- char key[]; /* A variable length array in the struct itself */
-} topkey_item_t;
-
-typedef struct topkeys {
- dlist_t list;
- pthread_mutex_t mutex;
- genhash_t *hash;
- int nkeys;
- int max_keys;
-} topkeys_t;
-
-topkeys_t *topkeys_init(int max_keys);
-void topkeys_free(topkeys_t *topkeys);
-topkey_item_t *topkeys_item_get_or_create(topkeys_t *tk, const void *key, size_t nkey, const rel_time_t ctime);
-ENGINE_ERROR_CODE topkeys_stats(topkeys_t *tk, const void *cookie, const rel_time_t current_time, ADD_STAT add_stat);
-
-#endif