Skip to content

Commit ac8ee0c

Browse files
committed
key_stat funcs work better, and mcache.key_alloc flag
1 parent c33e08a commit ac8ee0c

File tree

4 files changed

+75
-43
lines changed

4 files changed

+75
-43
lines changed

cproxy.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,11 @@ proxy *cproxy_create(char *name,
131131

132132
pthread_mutex_init(&p->proxy_lock, NULL);
133133

134-
mcache_init(&p->front_cache, true, &mcache_item_funcs);
134+
mcache_init(&p->front_cache, true, &mcache_item_funcs, true);
135135
matcher_init(&p->front_cache_matcher, true);
136136
matcher_init(&p->front_cache_unmatcher, true);
137137

138-
mcache_init(&p->key_stats, true, &mcache_key_stat_funcs);
138+
mcache_init(&p->key_stats, true, &mcache_key_stat_funcs, false);
139139
matcher_init(&p->key_stats_matcher, true);
140140
matcher_init(&p->key_stats_unmatcher, true);
141141

cproxy.h

+14-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ typedef struct {
5050

5151
pthread_mutex_t *lock; // NULL-able, for non-multithreaded.
5252

53+
bool key_alloc; // True if mcache must alloc key memory.
54+
5355
GHashTable *map; // NULL-able, keyed by string, value is item.
5456

5557
uint32_t max; // Maxiumum number of items to keep.
@@ -79,6 +81,7 @@ typedef struct proxy_main proxy_main;
7981
typedef struct proxy_stats proxy_stats;
8082
typedef struct proxy_behavior proxy_behavior;
8183
typedef struct downstream downstream;
84+
typedef struct key_stat key_stat;
8285

8386
struct proxy_behavior {
8487
// IL means startup, system initialization level behavior.
@@ -233,6 +236,15 @@ typedef struct {
233236
uint64_t cas; // Number that had or required cas-id.
234237
} proxy_stats_cmd;
235238

239+
struct key_stat {
240+
char key[KEY_MAX_LENGTH + 1];
241+
int refcount;
242+
uint32_t exptime;
243+
key_stat *next;
244+
key_stat *prev;
245+
proxy_stats_cmd stat;
246+
};
247+
236248
typedef enum {
237249
STATS_CMD_GET = 0, // For each "get" cmd, even if multikey get.
238250
STATS_CMD_GET_KEY, // For each key in a "get".
@@ -555,7 +567,8 @@ void cproxy_del_front_cache_key_ascii_response(downstream *d,
555567

556568
// Functions for the front cache.
557569
//
558-
void mcache_init(mcache *m, bool multithreaded, mcache_funcs *funcs);
570+
void mcache_init(mcache *m, bool multithreaded,
571+
mcache_funcs *funcs, bool key_alloc);
559572
void mcache_start(mcache *m, uint32_t max);
560573
bool mcache_started(mcache *m);
561574
void mcache_stop(mcache *m);

cproxy_front.c

+38-20
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,12 @@ mcache_funcs mcache_item_funcs = {
4141
};
4242

4343
void mcache_init(mcache *m, bool multithreaded,
44-
mcache_funcs *funcs) {
44+
mcache_funcs *funcs, bool key_alloc) {
4545
assert(m);
4646
assert(funcs);
4747

4848
m->funcs = funcs;
49+
m->key_alloc = key_alloc;
4950
m->map = NULL;
5051
m->max = 0;
5152
m->lru_head = NULL;
@@ -100,7 +101,7 @@ void mcache_start(mcache *m, uint32_t max) {
100101

101102
m->map = g_hash_table_new_full(skey_hash,
102103
skey_equal,
103-
helper_g_free,
104+
m->key_alloc ? helper_g_free : NULL,
104105
m->funcs->item_dec_ref);
105106
if (m->map != NULL) {
106107
m->max = max;
@@ -227,30 +228,46 @@ void mcache_add(mcache *m, void *it,
227228
break;
228229

229230
void *last_it = m->lru_tail;
231+
230232
mcache_item_unlink(m, last_it);
231233

232-
int len = m->funcs->item_key_len(last_it);
233-
char buf[KEY_MAX_LENGTH + 10];
234-
memcpy(buf, m->funcs->item_key(last_it), len);
235-
buf[len] = '\0';
234+
if (m->key_alloc) {
235+
int len = m->funcs->item_key_len(last_it);
236+
char buf[KEY_MAX_LENGTH + 10];
237+
memcpy(buf, m->funcs->item_key(last_it), len);
238+
buf[len] = '\0';
236239

237-
g_hash_table_remove(m->map, buf);
240+
g_hash_table_remove(m->map, buf);
241+
} else {
242+
g_hash_table_remove(m->map,
243+
m->funcs->item_key(last_it));
244+
}
238245

239246
m->tot_evictions++;
240247
}
241248

242249
if (g_hash_table_size(m->map) < m->max) {
243-
// The ITEM_key is not NULL or space terminated,
244-
// and we need a copy, too, for hashtable ownership.
245-
//
250+
char *key = m->funcs->item_key(it);
246251
int key_len = m->funcs->item_key_len(it);
247-
char *key_buf = malloc(key_len + 1);
248-
if (key_buf != NULL) {
249-
memcpy(key_buf, m->funcs->item_key(it), key_len);
250-
key_buf[key_len] = '\0';
252+
char *key_buf = NULL;
253+
254+
if (m->key_alloc) {
255+
// The ITEM_key is not NULL or space terminated,
256+
// and we need a copy, too, for hashtable ownership.
257+
//
258+
key_buf = malloc(key_len + 1);
259+
if (key_buf != NULL) {
260+
memcpy(key_buf, key, key_len);
261+
key_buf[key_len] = '\0';
262+
key = key_buf;
263+
} else {
264+
key = NULL;
265+
}
266+
}
251267

268+
if (key != NULL) {
252269
void *existing =
253-
(void *) g_hash_table_lookup(m->map, key_buf);
270+
(void *) g_hash_table_lookup(m->map, key);
254271
if (existing != NULL) {
255272
mcache_item_unlink(m, existing);
256273
mcache_item_touch(m, existing);
@@ -259,21 +276,22 @@ void mcache_add(mcache *m, void *it,
259276

260277
if (settings.verbose > 1)
261278
fprintf(stderr,
262-
"mcache add-skip: %s\n", key_buf);
279+
"mcache add-skip: %s\n", key);
263280

264-
free(key_buf);
281+
if (key_buf != NULL)
282+
free(key_buf);
265283
} else {
266284
m->funcs->item_set_exptime(it, exptime);
267-
m->funcs->item_add_ref(it); // TODO: Need item lock here?
285+
m->funcs->item_add_ref(it);
268286

269-
g_hash_table_insert(m->map, key_buf, it);
287+
g_hash_table_insert(m->map, key, it);
270288

271289
m->tot_adds++;
272290
m->tot_add_bytes += m->funcs->item_len(it);
273291

274292
if (settings.verbose > 1)
275293
fprintf(stderr,
276-
"mcache add: %s\n", key_buf);
294+
"mcache add: %s\n", key);
277295
}
278296
} else {
279297
m->tot_add_fails++;

cproxy_stats.c

+21-20
Original file line numberDiff line numberDiff line change
@@ -383,67 +383,68 @@ void cproxy_reset_stats_cmd(proxy_stats_cmd *sc) {
383383
// -------------------------------------------------
384384

385385
static char *key_stat_key(void *it) {
386-
item *i = it;
386+
key_stat *i = it;
387387
assert(i);
388-
return ITEM_key(i);
388+
return i->key;
389389
}
390390

391391
static int key_stat_key_len(void *it) {
392-
item *i = it;
392+
key_stat *i = it;
393393
assert(i);
394-
return i->nkey;
394+
return strlen(i->key);
395395
}
396396

397397
static int key_stat_len(void *it) {
398-
item *i = it;
399-
assert(i);
400-
return i->nbytes;
398+
return sizeof(key_stat);
401399
}
402400

403401
static void key_stat_add_ref(void *it) {
404-
item *i = it;
402+
key_stat *i = it;
405403
if (i != NULL)
406-
i->refcount++; // TODO: Need item lock here?
404+
i->refcount++;
407405
}
408406

409407
static void key_stat_dec_ref(void *it) {
410-
item *i = it;
411-
if (i != NULL)
412-
item_remove(i);
408+
key_stat *i = it;
409+
if (i != NULL) {
410+
i->refcount--;
411+
if (i->refcount <= 0)
412+
free(it);
413+
}
413414
}
414415

415416
static void *key_stat_get_next(void *it) {
416-
item *i = it;
417+
key_stat *i = it;
417418
assert(i);
418419
return i->next;
419420
}
420421

421422
static void key_stat_set_next(void *it, void *next) {
422-
item *i = it;
423+
key_stat *i = it;
423424
assert(i);
424-
i->next = (item *) next;
425+
i->next = (key_stat *) next;
425426
}
426427

427428
static void *key_stat_get_prev(void *it) {
428-
item *i = it;
429+
key_stat *i = it;
429430
assert(i);
430431
return i->prev;
431432
}
432433

433434
static void key_stat_set_prev(void *it, void *prev) {
434-
item *i = it;
435+
key_stat *i = it;
435436
assert(i);
436-
i->prev = (item *) prev;
437+
i->prev = (key_stat *) prev;
437438
}
438439

439440
static uint32_t key_stat_get_exptime(void *it) {
440-
item *i = it;
441+
key_stat *i = it;
441442
assert(i);
442443
return i->exptime;
443444
}
444445

445446
static void key_stat_set_exptime(void *it, uint32_t exptime) {
446-
item *i = it;
447+
key_stat *i = it;
447448
assert(i);
448449
i->exptime = exptime;
449450
}

0 commit comments

Comments
 (0)