7 #include <memcached/genhash.h>
10 static topkey_item_t *topkey_item_init(
const void *key,
int nkey, rel_time_t ctime) {
19 memcpy(item->key, key, nkey);
23 static inline size_t topkey_item_size(
const topkey_item_t *item) {
31 static int my_hash_eq(
const void *k1,
size_t nkey1,
32 const void *k2,
size_t nkey2) {
33 return nkey1 == nkey2 && memcmp(k1, k2, nkey1) == 0;
42 pthread_mutex_init(&tk->mutex, NULL);
43 tk->max_keys = max_keys;
44 tk->list.next = &tk->list;
45 tk->list.prev = &tk->list;
47 static struct hash_ops my_hash_ops = {
57 if (tk->hash == NULL) {
64 pthread_mutex_destroy(&tk->mutex);
67 while (p != &tk->list) {
74 static inline void dlist_remove(
dlist_t *list) {
75 assert(list->prev->next == list);
76 assert(list->next->prev == list);
77 list->prev->next = list->next;
78 list->next->prev = list->prev;
81 static inline void dlist_insert_after(
dlist_t *list,
dlist_t *
new) {
82 new->next = list->next;
84 list->next->prev =
new;
88 static inline void dlist_iter(
dlist_t *list,
89 void (*iterfunc)(
dlist_t *item,
void *arg),
93 while ((p = p->next) != list) {
100 dlist_remove(&item->list);
105 topkey_item_t *topkeys_item_get_or_create(
topkeys_t *tk,
const void *key,
size_t nkey,
const rel_time_t ctime) {
108 item = topkey_item_init(key, nkey, ctime);
110 if (++tk->nkeys > tk->max_keys) {
111 topkeys_item_delete(tk, topkeys_tail(tk));
114 item, topkey_item_size(item));
119 dlist_remove(&item->list);
121 dlist_insert_after(&tk->list, &item->list);
125 static inline void append_stat(
const void *cookie,
136 klen =
sizeof(key_str) - namelen - 2;
140 memcpy(key_str, key, klen);
142 memcpy(&key_str[klen+1], name, namelen + 1);
144 vlen = snprintf(val_str,
sizeof(val_str) - 1,
"%d", value);
145 add_stats(key_str, klen, val_str, vlen, cookie);
151 rel_time_t current_time;
154 #define TK_FMT(name) #name "=%d,"
155 #define TK_ARGS(name) item->name,
157 static void tk_iterfunc(
dlist_t *list,
void *arg) {
160 char val_str[TK_MAX_VAL_LEN];
162 int vlen = snprintf(val_str,
sizeof(val_str) - 1, TK_OPS(TK_FMT)
"ctime=%"PRIu32
",atime=%"PRIu32, TK_OPS(TK_ARGS)
163 c->current_time - item->ctime, c->current_time - item->atime);
164 c->add_stat(item->key, item->nkey, val_str, vlen, c->cookie);
167 ENGINE_ERROR_CODE topkeys_stats(
topkeys_t *tk,
169 const rel_time_t current_time,
172 context.cookie = cookie;
173 context.add_stat = add_stat;
174 context.current_time = current_time;
176 pthread_mutex_lock(&tk->mutex);
177 dlist_iter(&tk->list, tk_iterfunc, &context);
178 pthread_mutex_unlock(&tk->mutex);
179 return ENGINE_SUCCESS;