Browse files

support mul-lru

  • Loading branch information...
1 parent 1b587e6 commit c65e142c95887c3989f1feec5813730ebab98ab7 @believe3301 committed Sep 17, 2012
Showing with 226 additions and 223 deletions.
  1. +19 −14 binding/lru_jni.c
  2. +6 −6 binding/lru_jni.h
  3. +11 −42 hash.c
  4. +3 −7 hash.h
  5. +104 −100 lru.c
  6. +25 −11 lru.h
  7. +20 −13 test/bench.c
  8. +38 −30 test/test.c
View
33 binding/lru_jni.c
@@ -2,33 +2,34 @@
#include "lru.h"
/* open */
-JNIEXPORT jint JNICALL
-Java_com_feinno_kv_MemDB_open(JNIEnv *jenv, jobject clazz, jlong bufsize)
+JNIEXPORT jlong JNICALL
+Java_com_feinno_kv_MemDB_open(JNIEnv *jenv, jobject clazz, jlong bufsize, jint hashpower)
{
(void) clazz;
(void) jenv;
- lru_init((size_t) bufsize);
+ lru *l = lru_init((uint64_t) bufsize, (unsigned int) hashpower);
- return (jint)0;
+ return (jlong)(intptr_t)l;
}
/* set */
JNIEXPORT jint JNICALL
-Java_com_feinno_kv_MemDB_set(JNIEnv *jenv, jobject clazz, jbyteArray jkey, jint jklen, jbyteArray jval, jint jvlen)
+Java_com_feinno_kv_MemDB_set(JNIEnv *jenv, jobject clazz, jlong ptr, jbyteArray jkey, jint jklen, jbyteArray jval, jint jvlen)
{
(void)clazz;
char *key, *val;
int ret = -1;
+ lru *l = (lru*) ptr;
key = (char*)(*jenv)->GetByteArrayElements(jenv, jkey, 0);
val = (char*)(*jenv)->GetByteArrayElements(jenv, jval, 0);
if (key == NULL || val == NULL)
goto RET;
- ret = item_set(key, (int)jklen, val, (int)jvlen);
+ ret = item_set(l, key, (int)jklen, val, (int)jvlen);
RET:
if (key) {
@@ -42,11 +43,12 @@ Java_com_feinno_kv_MemDB_set(JNIEnv *jenv, jobject clazz, jbyteArray jkey, jint
/* get */
JNIEXPORT jint JNICALL
-Java_com_feinno_kv_MemDB_get(JNIEnv *jenv, jobject clazz, jbyteArray jkey, jint jklen, jbyteArray jbuf, jint jblen)
+Java_com_feinno_kv_MemDB_get(JNIEnv *jenv, jobject clazz, jlong ptr, jbyteArray jkey, jint jklen, jbyteArray jbuf, jint jblen)
{
(void) clazz;
char *key, *buf;
int ret = -1;
+ lru *l = (lru*) ptr;
key = (char*)(*jenv)->GetByteArrayElements(jenv, jkey, 0);
buf = (char*)(*jenv)->GetByteArrayElements(jenv, jbuf, 0);
@@ -55,7 +57,7 @@ Java_com_feinno_kv_MemDB_get(JNIEnv *jenv, jobject clazz, jbyteArray jkey, jint
goto RET;
size_t sz;
- ret = item_get(key, (int)jklen, buf, (int)jblen, &sz);
+ ret = item_get(l, key, (int)jklen, buf, (int)jblen, &sz);
//(*jenv)->SetByteArrayRegion(jenv, jbuf, 0, sz, (jbyte*)buf);
RET:
@@ -71,18 +73,19 @@ Java_com_feinno_kv_MemDB_get(JNIEnv *jenv, jobject clazz, jbyteArray jkey, jint
/* remove */
JNIEXPORT jint JNICALL
-Java_com_feinno_kv_MemDB_remove(JNIEnv *jenv, jobject clazz, jbyteArray jkey, jint jklen)
+Java_com_feinno_kv_MemDB_remove(JNIEnv *jenv, jobject clazz, jlong ptr, jbyteArray jkey, jint jklen)
{
(void) clazz;
char *key;
int ret = -1;
+ lru *l = (lru*) ptr;
key = (char*)(*jenv)->GetByteArrayElements(jenv, jkey, 0);
if (key == NULL)
goto RET;
- ret = item_delete(key, (int)jklen);
+ ret = item_delete(l, key, (int)jklen);
RET:
if (key) {
@@ -94,24 +97,26 @@ Java_com_feinno_kv_MemDB_remove(JNIEnv *jenv, jobject clazz, jbyteArray jkey, ji
/* stat */
JNIEXPORT void JNICALL
-Java_com_feinno_kv_MemDB_info(JNIEnv *jenv, jobject clazz, jbyteArray jbuf, jint jblen)
+Java_com_feinno_kv_MemDB_info(JNIEnv *jenv, jobject clazz, jlong ptr, jbyteArray jbuf, jint jblen)
{
(void) clazz;
char *buf;
+ lru *l = (lru*) ptr;
buf = (char*)(*jenv)->GetByteArrayElements(jenv, jbuf, 0);
if (buf) {
- stat_print(buf, (int)jblen);
+ stat_print(l, buf, (int)jblen);
}
}
/* free */
JNIEXPORT void JNICALL
-Java_com_feinno_kv_MemDB_close(JNIEnv *jenv, jobject clazz)
+Java_com_feinno_kv_MemDB_close(JNIEnv *jenv, jobject clazz, jlong ptr)
{
(void) jenv;
(void) clazz;
+ lru *l = (lru*) ptr;
- lru_free();
+ lru_free(l);
}
View
12 binding/lru_jni.h
@@ -1,13 +1,13 @@
#include "jni.h"
-JNIEXPORT jint JNICALL Java_com_feinno_kv_MemDB_open(JNIEnv *, jobject, jlong);
+JNIEXPORT jlong JNICALL Java_com_feinno_kv_MemDB_open(JNIEnv *, jobject, jlong, jint);
-JNIEXPORT jint JNICALL Java_com_feinno_kv_MemDB_set(JNIEnv *, jobject, jbyteArray, jint, jbyteArray, jint);
+JNIEXPORT jint JNICALL Java_com_feinno_kv_MemDB_set(JNIEnv *, jobject, jlong, jbyteArray, jint, jbyteArray, jint);
-JNIEXPORT jint JNICALL Java_com_feinno_kv_MemDB_get(JNIEnv *, jobject, jbyteArray, jint, jbyteArray, jint);
+JNIEXPORT jint JNICALL Java_com_feinno_kv_MemDB_get(JNIEnv *, jobject, jlong, jbyteArray, jint, jbyteArray, jint);
-JNIEXPORT jint JNICALL Java_com_feinno_kv_MemDB_remove(JNIEnv *, jobject, jbyteArray, jint);
+JNIEXPORT jint JNICALL Java_com_feinno_kv_MemDB_remove(JNIEnv *, jobject, jlong, jbyteArray, jint);
-JNIEXPORT void JNICALL Java_com_feinno_kv_MemDB_info(JNIEnv *, jobject , jbyteArray , jint);
+JNIEXPORT void JNICALL Java_com_feinno_kv_MemDB_info(JNIEnv *, jobject , jlong, jbyteArray , jint);
-JNIEXPORT void JNICALL Java_com_feinno_kv_MemDB_close(JNIEnv *, jobject);
+JNIEXPORT void JNICALL Java_com_feinno_kv_MemDB_close(JNIEnv *, jobject, jlong);
View
53 hash.c
@@ -1,32 +1,9 @@
#include "lru.h"
-unsigned int hashpower = 16;
-
-#define hashsize(n) ((size_t)1<<(n))
-#define hashmask(n) (hashsize(n)-1)
-
-static lru_item** table;
-static unsigned int hash_items = 0;
-
-int
-hash_init(const int hashpower_init)
-{
- if (hashpower_init > 0) {
- hashpower = hashpower_init;
- }
- table = calloc(hashsize(hashpower), sizeof(void *));
-
- if (table) {
- stat.hash_power_level = hashpower;
- stat.hash_bytes = hashsize(hashpower) * sizeof(void *);
- }
- return table == NULL;
-}
-
lru_item*
-hash_find(const char *key, const size_t nkey, const uint32_t hv)
+hash_find(lru *l, const char *key, const size_t nkey, const uint32_t hv)
{
- lru_item *it = table[hv & hashmask(hashpower)];
+ lru_item *it = l->table[hv & hashmask(l->hashpower)];
lru_item *ret = NULL;
unsigned int depth = 0;
while (it) {
@@ -37,25 +14,24 @@ hash_find(const char *key, const size_t nkey, const uint32_t hv)
it = it->h_next;
++depth;
}
- stat.hash_find_depth = MAX(stat.hash_find_depth, depth);
+ l->stat.hash_find_depth = MAX(l->stat.hash_find_depth, depth);
return ret;
}
int
-hash_insert(lru_item *it, const uint32_t hv)
+hash_insert(lru *l, lru_item *it, const uint32_t hv)
{
- it->h_next = table[hv & hashmask(hashpower)];
- table[hv & hashmask(hashpower)] = it;
- hash_items++;
+ it->h_next = l->table[hv & hashmask(l->hashpower)];
+ l->table[hv & hashmask(l->hashpower)] = it;
return 1;
}
static lru_item**
-hashitem_before (const char *key, const size_t nkey, const uint32_t hv)
+hashitem_before (lru *l, const char *key, const size_t nkey, const uint32_t hv)
{
lru_item **pos;
- pos = &table[hv & hashmask(hashpower)];
+ pos = &(l->table[hv & hashmask(l->hashpower)]);
while (*pos && ((nkey != (*pos)->nkey) || memcmp(key, ITEM_key(*pos), nkey))) {
pos = &(*pos)->h_next;
@@ -64,21 +40,14 @@ hashitem_before (const char *key, const size_t nkey, const uint32_t hv)
}
void
-hash_delete(const char *key, const size_t nkey, const uint32_t hv)
+hash_delete(lru *l, const char *key, const size_t nkey, const uint32_t hv)
{
- lru_item **before = hashitem_before(key, nkey, hv);
+ lru_item **before = hashitem_before(l, key, nkey, hv);
if (*before) {
lru_item *nxt;
- hash_items--;
nxt = (*before)->h_next;
- (*before)->h_next = 0; /* probably pointless, but whatever. */
+ (*before)->h_next = 0;
*before = nxt;
}
}
-
-void
-hash_free(void)
-{
- free(table);
-}
View
10 hash.h
@@ -1,9 +1,5 @@
-int hash_init(const int hashpower_init);
+lru_item* hash_find(lru *l, const char *key, const size_t nkey, const uint32_t hv);
-lru_item* hash_find(const char *key, const size_t nkey, const uint32_t hv);
+int hash_insert(lru *l, lru_item *it, const uint32_t hv);
-int hash_insert(lru_item *it, const uint32_t hv);
-
-void hash_delete(const char *key, const size_t nkey, const uint32_t hv);
-
-void hash_free(void);
+void hash_delete(lru *l, const char *key, const size_t nkey, const uint32_t hv);
View
204 lru.c
@@ -4,23 +4,34 @@
#include <stdarg.h>
#include <stdio.h>
-static lru_item *head = NULL;
-static lru_item *tail = NULL;
-lru_stat stat;
-
-int
-lru_init(const size_t maxbytes)
+lru*
+lru_init(const uint64_t maxbytes, const unsigned int hashpower)
{
- head = NULL;
- tail = NULL;
+ lru *l = calloc(sizeof(lru), 1);
- if (maxbytes <= 0) {
- stat.max_bytes = MAXBYTE_DEDAULT;
+ if (l == NULL) {
+ fprintf(stderr, "lru init alloc lru failed.\n");
+ return NULL;
+ }
+
+ if (hashpower > 32) {
+ fprintf(stderr, "hash power must less than 32.\n");
+ return NULL;
} else {
- stat.max_bytes = maxbytes;
+ l->hashpower = hashpower <= 0 ? HASH_POWER_DEFAULT: hashpower;
}
- return hash_init(0);
+ l->max_bytes = maxbytes <=0 ? MAXBYTE_DEDAULT: maxbytes;
+ l->table = calloc(hashsize(l->hashpower), sizeof(void *));
+
+ if (l->table == NULL) {
+ fprintf(stderr, "lru init alloc hash buckets failed.\n");
+ free(l);
+ return NULL;
+ }
+
+ l->stat.hash_bytes = hashsize(l->hashpower);
+ return l;
}
static uint32_t
@@ -38,52 +49,52 @@ hash(const char *key, const int nkey)
}
static inline lru_item*
-do_item_get(const char *key, const size_t nkey, const uint32_t hv)
+do_item_get(lru *l, const char *key, const size_t nkey, const uint32_t hv)
{
- return hash_find(key, nkey, hv);
+ return hash_find(l, key, nkey, hv);
}
static void
-do_item_remove_hv(lru_item *it, const uint32_t hv)
+do_item_remove_hv(lru *l, lru_item *it, const uint32_t hv)
{
assert(it != NULL);
- hash_delete(ITEM_key(it), it->nkey, hv);
- if (head == it) {
+ hash_delete(l, ITEM_key(it), it->nkey, hv);
+ if (l->head == it) {
assert(it->prev == 0);
- head = it->next;
+ l->head = it->next;
}
- if (tail == it) {
+ if (l->tail == it) {
assert(it->next == 0);
- tail = it->prev;
+ l->tail = it->prev;
}
assert(it->next != it);
assert(it->prev != it);
if (it->next) it->next->prev = it->prev;
if (it->prev) it->prev->next = it->next;
- stat.curr_items --;
- stat.curr_bytes -= it->nbytes;
- stat.free_bytes += it->nbytes;
- stat.free++;
+ l->stat.curr_items --;
+ l->stat.curr_bytes -= it->nbytes;
+ l->stat.free_bytes += it->nbytes;
+ l->stat.free++;
free(it);
}
static void
-do_item_remove(lru_item *it)
+do_item_remove(lru *l, lru_item *it)
{
uint32_t hv = hash(ITEM_key(it), it->nkey);
- do_item_remove_hv(it, hv);
+ do_item_remove_hv(l, it, hv);
}
int
-item_get(const char *key, const size_t nkey, char *buf, const size_t nbuf, size_t *nvalue)
+item_get(lru *l, const char *key, const size_t nkey, char *buf, const size_t nbuf, size_t *nvalue)
{
- stat.get_cmds++;
+ l->stat.get_cmds++;
uint32_t hv = hash(key, nkey);
- lru_item *it = do_item_get(key, nkey, hv);
+ lru_item *it = do_item_get(l, key, nkey, hv);
if (it != NULL) {
- stat.get_hits ++;
+ l->stat.get_hits ++;
size_t vlen = it->nbytes - ITEM_size - it->nkey - 1;
if (nvalue) {
@@ -96,71 +107,71 @@ item_get(const char *key, const size_t nkey, char *buf, const size_t nbuf, size_
}
return 0;
}
- stat.get_misses ++;
+ l->stat.get_misses ++;
return 1;
}
static void*
-item_alloc(const size_t sz, lru_item *old)
+item_alloc(lru *l, const size_t sz, lru_item *old)
{
void *m = NULL;
int delta = old ? old->nbytes : 0;
- if ((stat.curr_bytes + sz - delta) <= stat.max_bytes) {
+ if ((l->stat.curr_bytes + sz - delta) <= l->max_bytes) {
m = malloc(sz);
if (!m) {
- stat.malloc_failed += 1;
+ l->stat.malloc_failed += 1;
return NULL;
}
- } else if (sz > stat.max_bytes) {
+ } else if (sz > l->max_bytes) {
return NULL;
} else {
//evict
- assert(tail != NULL);
- lru_item *it = tail;
- while((it != NULL) && (stat.curr_bytes + sz - delta) > stat.max_bytes) {
+ assert(l->tail != NULL);
+ lru_item *it = l->tail;
+ while((it != NULL) && (l->stat.curr_bytes + sz - delta) > l->max_bytes) {
if (it != old) {
- do_item_remove(it);
- it = tail;
+ do_item_remove(l, it);
+ it = l->tail;
} else {
- it = tail->prev;
+ it = l->tail->prev;
}
- stat.evictions ++;
+ l->stat.evictions ++;
}
m = malloc(sz);
if (!m) {
- stat.malloc_failed += 1;
+ l->stat.malloc_failed += 1;
return NULL;
}
}
- stat.malloc ++;
- stat.curr_bytes += sz;
- stat.total_bytes += sz;
- stat.curr_items ++;
- stat.total_items ++;
+ l->stat.malloc ++;
+ l->stat.curr_bytes += sz;
+ l->stat.total_bytes += sz;
+ l->stat.curr_items ++;
+ l->stat.total_items ++;
return m;
}
int
-item_set(const char *key, const size_t nkey, const char *value, const size_t nvalue)
+item_set(lru *l, const char *key, const size_t nkey, const char *value, const size_t nvalue)
{
- stat.set_cmds ++;
+ l->stat.set_cmds ++;
uint32_t hv = hash(key, nkey);
- lru_item *old = do_item_get(key, nkey, hv);
+ lru_item *old = do_item_get(l, key, nkey, hv);
size_t isize = ITEM_size + nkey + 1 + nvalue;
- lru_item *it = item_alloc(isize, old);
+ lru_item *it = item_alloc(l, isize, old);
if (it == NULL) {
- stat.set_failed ++;
+ l->stat.set_failed ++;
return 1;
}
if (old != NULL) {
- do_item_remove_hv(old, hv);
+ do_item_remove_hv(l, old, hv);
}
it->nkey = nkey;
@@ -169,28 +180,28 @@ item_set(const char *key, const size_t nkey, const char *value, const size_t nva
memcpy(ITEM_key(it), key, nkey);
memcpy(ITEM_data(it), value, nvalue);
- hash_insert(it, hv);
+ hash_insert(l, it, hv);
it->prev = 0;
- it->next = head;
+ it->next = l->head;
if (it->next) it->next->prev = it;
- head = it;
- if (tail == NULL) tail = it;
+ l->head = it;
+ if (l->tail == NULL) l->tail = it;
return 0;
}
int
-item_delete(const char *key, const size_t nkey)
+item_delete(lru *l, const char *key, const size_t nkey)
{
- stat.del_cmds++;
+ l->stat.del_cmds++;
uint32_t hv = hash(key, nkey);
- lru_item *it = hash_find(key, nkey, hv);
+ lru_item *it = hash_find(l, key, nkey, hv);
if (it != NULL) {
- do_item_remove_hv(it, hv);
- stat.del_hits++;
+ do_item_remove_hv(l, it, hv);
+ l->stat.del_hits++;
return 0;
} else {
- stat.del_misses++;
+ l->stat.del_misses++;
return 1;
}
}
@@ -216,57 +227,50 @@ append_stat(char **buf, int *nbuf, char *name, const char *fmt, ...)
}
void
-stat_print(char *buf, const int nbuf)
+stat_print(lru *l, char *buf, const int nbuf)
{
int remaining = nbuf;
- append_stat(&buf, &remaining, "max_bytes","%llu",stat.max_bytes);
- append_stat(&buf, &remaining, "total_items","%llu",stat.total_items);
- append_stat(&buf, &remaining, "curr_items","%llu",stat.curr_items);
- append_stat(&buf, &remaining, "total_bytes","%llu",stat.total_bytes);
- append_stat(&buf, &remaining, "curr_bytes","%llu",stat.curr_bytes);
- append_stat(&buf, &remaining, "malloc","%llu",stat.malloc);
- append_stat(&buf, &remaining, "malloc_failed","%llu",stat.malloc_failed);
- append_stat(&buf, &remaining, "free_bytes","%llu",stat.free_bytes);
- append_stat(&buf, &remaining, "free","%llu",stat.free);
+ append_stat(&buf, &remaining, "max_bytes","%llu", l->max_bytes);
+ append_stat(&buf, &remaining, "total_items","%llu", l->stat.total_items);
+ append_stat(&buf, &remaining, "curr_items","%llu", l->stat.curr_items);
+ append_stat(&buf, &remaining, "total_bytes","%llu", l->stat.total_bytes);
+ append_stat(&buf, &remaining, "curr_bytes","%llu", l->stat.curr_bytes);
+ append_stat(&buf, &remaining, "malloc","%llu", l->stat.malloc);
+ append_stat(&buf, &remaining, "malloc_failed","%llu", l->stat.malloc_failed);
+ append_stat(&buf, &remaining, "free_bytes","%llu", l->stat.free_bytes);
+ append_stat(&buf, &remaining, "free","%llu", l->stat.free);
- append_stat(&buf, &remaining, "get_cmds","%llu",stat.get_cmds);
- append_stat(&buf, &remaining, "get_hits","%llu",stat.get_hits);
- append_stat(&buf, &remaining, "get_misses","%llu",stat.get_misses);
+ append_stat(&buf, &remaining, "get_cmds","%llu", l->stat.get_cmds);
+ append_stat(&buf, &remaining, "get_hits","%llu", l->stat.get_hits);
+ append_stat(&buf, &remaining, "get_misses","%llu", l->stat.get_misses);
- append_stat(&buf, &remaining, "set_cmds","%llu",stat.set_cmds);
- append_stat(&buf, &remaining, "set_failed","%llu",stat.set_failed);
+ append_stat(&buf, &remaining, "set_cmds","%llu", l->stat.set_cmds);
+ append_stat(&buf, &remaining, "set_failed","%llu", l->stat.set_failed);
- append_stat(&buf, &remaining, "del_cmds","%llu",stat.del_cmds);
- append_stat(&buf, &remaining, "del_hits","%llu",stat.del_hits);
- append_stat(&buf, &remaining, "del_misses","%llu",stat.del_misses);
+ append_stat(&buf, &remaining, "del_cmds","%llu", l->stat.del_cmds);
+ append_stat(&buf, &remaining, "del_hits","%llu", l->stat.del_hits);
+ append_stat(&buf, &remaining, "del_misses","%llu", l->stat.del_misses);
- append_stat(&buf, &remaining, "hash_power_level","%u",stat.hash_power_level);
- append_stat(&buf, &remaining, "hash_find_depth","%u",stat.hash_find_depth);
- append_stat(&buf, &remaining, "hash_bytes","%llu",stat.hash_bytes);
+ append_stat(&buf, &remaining, "hash_power_level","%u", l->hashpower);
+ append_stat(&buf, &remaining, "hash_find_depth","%u", l->stat.hash_find_depth);
+ append_stat(&buf, &remaining, "hash_bytes","%llu", l->stat.hash_bytes);
- append_stat(&buf, &remaining, "evictions","%llu",stat.evictions);
-}
-
-void stat_reset(void)
-{
- size_t max_bytes = stat.max_bytes;
- memset(&stat, 0, sizeof(struct lru_stat));
- stat.max_bytes = max_bytes;
+ append_stat(&buf, &remaining, "evictions","%llu", l->stat.evictions);
}
void
-lru_free(void)
+lru_free(lru *l)
{
//free items
lru_item *it;
- it = head;
+ it = l->head;
while (it != NULL) {
- do_item_remove(it);
- it = head;
+ do_item_remove(l, it);
+ it = l->head;
}
- assert(head == NULL);
- assert(tail == NULL);
+ assert(l->head == NULL);
+ assert(l->tail == NULL);
//free hashtable
- hash_free();
+ free(l->table);
}
View
36 lru.h
@@ -5,6 +5,11 @@
#define MAX(a, b) (((a) > (b))?(a) : (b))
#define MIN(a, b) (((a) > (b))?(b) : (a))
#define MAXBYTE_DEDAULT 64 * 1024 * 1024 /* 64M */
+#define HASH_POWER_DEFAULT 16
+
+#define hashsize(n) ((size_t)1<<(n))
+#define hashmask(n) (hashsize(n)-1)
+
#define ITEM_size (sizeof(lru_item))
@@ -25,8 +30,6 @@ typedef struct lru_item_ {
/* stat */
typedef struct lru_stat {
- uint64_t max_bytes;
-
uint64_t total_items;
uint64_t curr_items;
@@ -49,35 +52,46 @@ typedef struct lru_stat {
uint64_t del_hits;
uint64_t del_misses;
- unsigned int hash_power_level;
unsigned int hash_find_depth;
uint64_t hash_bytes;
uint64_t evictions;
}lru_stat;
-extern lru_stat stat;
+typedef struct lru{
+ unsigned int hashpower;
+ uint64_t max_bytes; /* max used bytes, include item size, not include hash bytes */
+
+ lru_item **table; /* hash */
+ lru_item *head; /* double link head */
+ lru_item *tail; /* double link tail */
+
+ lru_stat stat; /* stat */
+}lru;
+
#include "hash.h"
-int lru_init(size_t maxbytes);
+lru* lru_init(const uint64_t maxbytes, const unsigned int hashpower);
/*
0 success
1 failed
alloc value buf by caller or add refcount by item...
*/
-int item_get(const char *key, const size_t nkey, char *buf, const size_t nbuf, size_t *nvalue);
+int item_get(lru *l, const char *key, const size_t nkey, char *buf, const size_t nbuf, size_t *nvalue);
/* 0 success , 1 failed */
-int item_set(const char *key, const size_t nkey, const char *value, const size_t nvalue);
+int item_set(lru *l, const char *key, const size_t nkey, const char *value, const size_t nvalue);
/* 0 hit, 1 miss */
-int item_delete(const char *key, const size_t nkey);
+int item_delete(lru *l, const char *key, const size_t nkey);
-void stat_reset(void);
+#define stat_reset(l) do { \
+ memset(&(l->stat), 0, sizeof(struct lru_stat)); \
+} while(0)
-void stat_print(char *buf, const int nbuf);
+void stat_print(lru *l, char *buf, const int nbuf);
-void lru_free(void);
+void lru_free(lru *l);
View
33 test/bench.c
@@ -13,13 +13,15 @@ static struct config {
int num;
int keysize;
int datasize;
+ int hashpower;
}config;
static void usage(void) {
printf("-n <num> total number of loop(default 1000,000)\n"
- "-m <num> max memory for userd in megabytes(default 64MB)\n"
+ "-m <num> max memory for userd in megabytes(default 512MB)\n"
"-k <num> key size(default 16B)\n"
"-d <num> data size(default 32B)\n"
+ "-p <num> hash power level(default 16, 64K)\n"
"-h print this help and exit\n");
}
@@ -68,6 +70,7 @@ static void print_env(void) {
printf("DataSize: %.1f MB\n", (1L *(config.keysize + config.datasize) * config.num ) / 1048576.0);
printf("TotalSize: %.1f MB\n", (1L *(config.keysize + config.datasize + ITEM_size) * config.num ) / 1048576.0);
+ printf("CacheSize: %.1f MB\n", config.maxbytes / 1048576.0);
printf("-----------------------------------------\n");
}
@@ -124,14 +127,15 @@ static void bench_stop(void) {
static void config_init(void) {
config.num = 1000000;
- config.maxbytes = 64 * 1024 * 1024;
+ config.maxbytes = 512 * 1024 * 1024;
config.keysize = 16;
config.datasize = 32;
+ config.hashpower = 16;
}
-static void print_stat(void) {
+static void print_stat(lru *l) {
char bstat[1024];
- stat_print(bstat, sizeof(bstat));
+ stat_print(l, bstat, sizeof(bstat));
printf("-----------------------------------------\n");
printf("STAT\n%s", bstat);
printf("-----------------------------------------\n");
@@ -142,7 +146,7 @@ int main(int argc, char **argv) {
int c;
- while (-1 != (c = getopt(argc, argv, "n:m:k:d:h"))) {
+ while (-1 != (c = getopt(argc, argv, "n:m:k:d::p:h"))) {
switch(c) {
case 'n':
config.num = atoi(optarg);
@@ -156,6 +160,9 @@ int main(int argc, char **argv) {
case 'd':
config.datasize = atoi(optarg);
break;
+ case 'p':
+ config.hashpower = atoi(optarg);
+ break;
case 'h':
usage();
return EXIT_SUCCESS;
@@ -167,7 +174,7 @@ int main(int argc, char **argv) {
generate_key_init();
print_env();
- lru_init(config.maxbytes);
+ lru *l = lru_init(config.maxbytes, config.hashpower);
char *bvalue = malloc(config.datasize);
memset(bvalue, 'x', config.datasize);
@@ -182,20 +189,20 @@ int main(int argc, char **argv) {
int i;
for (i = 0; i < config.num; i++) {
snprintf(key, config.keysize, fmt_, gnum, generate_key(gnum), i);
- int r = item_set(key, config.keysize, bvalue, config.datasize);
+ int r = item_set(l, key, config.keysize, bvalue, config.datasize);
assert(r == 0);
process_report();
}
bench_stop();
- print_stat();
+ print_stat(l);
char *buf = malloc(config.datasize);
size_t sz;
generate_key_reset();
bench_start("GET");
for (i = 0; i < config.num; i++) {
snprintf(key, config.keysize, fmt_, gnum, generate_key(gnum), i);
- int r = item_get(key, config.keysize, buf, config.datasize, &sz);
+ int r = item_get(l, key, config.keysize, buf, config.datasize, &sz);
if (!r) {
assert((int)sz == config.datasize);
assert(memcmp(bvalue, buf, config.datasize) == 0);
@@ -204,25 +211,25 @@ int main(int argc, char **argv) {
process_report();
}
bench_stop();
- print_stat();
+ print_stat(l);
generate_key_reset();
bench_start("DELETE");
for (i = 0; i < config.num; i++) {
snprintf(key, config.keysize, fmt_, gnum, generate_key(gnum), i);
- item_delete(key, config.keysize);
+ item_delete(l, key, config.keysize);
process_report();
}
bench_stop();
- print_stat();
+ print_stat(l);
free(buf);
free(bvalue);
free(key);
free(fmt_);
free(key_);
- lru_free();
+ lru_free(l);
/*
printf("print any key to exit...\n");
getchar();
View
68 test/test.c
@@ -11,35 +11,35 @@ struct testcase {
test_func function;
};
-static enum test_return lru_normal_op(int new, size_t mb, char *key, size_t nkey, char *value, size_t nvalue) {
+static enum test_return lru_normal_op(lru *l, size_t mb, char *key, size_t nkey, char *value, size_t nvalue) {
char buf[64];
size_t sz;
+ int new = 0;
- if (new) {
- lru_init(mb);
+ if (!l) {
+ l = lru_init(mb, 0);
+ new = 1;
}
- int r = item_set(key, nkey, value, nvalue);
+ int r = item_set(l, key, nkey, value, nvalue);
if (r) {
if (new) {
- lru_free();
- stat_reset();
+ lru_free(l);
}
return TEST_FAIL;
}
- r = item_get(key, nkey, buf, sizeof(buf), &sz);
+ r = item_get(l, key, nkey, buf, sizeof(buf), &sz);
assert(r == 0);
assert(sz == nvalue);
assert(memcmp(value, buf, sz) == 0);
- r = item_delete(key, nkey);
+ r = item_delete(l, key, nkey);
assert(r == 0);
if (new) {
- lru_free();
- stat_reset();
+ lru_free(l);
}
return TEST_PASS;
}
@@ -48,21 +48,22 @@ static enum test_return lru_normal_test(void) {
char *key = "key1";
char *value = "value1";
- return lru_normal_op(1, 0, key, strlen(key), value, strlen(value) + 1);
+ return lru_normal_op(NULL, 0, key, strlen(key), value, strlen(value) + 1);
}
static enum test_return lru_overwrite_test(void) {
char *key = "key1";
char *value = "value1";
char *value2 = "value2";
+ lru *l;
- lru_init(0);
+ l = lru_init(0, 0);
- item_set(key, strlen(key), value, strlen(value) + 1);
+ item_set(l, key, strlen(key), value, strlen(value) + 1);
- enum test_return r = lru_normal_op(0, 0, key, strlen(key), value2, strlen(value2) + 1);
+ enum test_return r = lru_normal_op(l, 0, key, strlen(key), value2, strlen(value2) + 1);
- lru_free();
+ lru_free(l);
return r;
}
@@ -73,13 +74,13 @@ static enum test_return lru_big_set_test(void) {
int malloc = ITEM_size + strlen(key) + 1 + strlen(value) + 1;
- enum test_return r = lru_normal_op(1, malloc, key, strlen(key), value, strlen(value) + 1);
+ enum test_return r = lru_normal_op(NULL, malloc, key, strlen(key), value, strlen(value) + 1);
if ( r != TEST_PASS) {
return r;
}
- r = lru_normal_op(1, malloc - 1, key, strlen(key), value, strlen(value) + 1);
+ r = lru_normal_op(NULL, malloc - 1, key, strlen(key), value, strlen(value) + 1);
if ( r == TEST_FAIL) {
return TEST_PASS;
@@ -97,22 +98,23 @@ static enum test_return lru_evict_test(void) {
int malloc = ITEM_size + nkey + nvalue + 1;
int r, i = 0, loop;
+ lru *l;
loop = sizeof(key) / (nkey + 1);
- lru_init(malloc * loop);
+ l = lru_init(malloc * loop, 0);
size_t sz;
char buf[256];
for (i = 0; i < loop; i++) {
- r = item_set(key[i], nkey, value, nvalue);
+ r = item_set(l, key[i], nkey, value, nvalue);
assert(r == 0);
}
for (i = 0; i < loop; i++) {
- r = item_get(key[i], nkey, buf, sizeof(buf), &sz);
+ r = item_get(l, key[i], nkey, buf, sizeof(buf), &sz);
assert(r == 0);
assert(sz == nvalue);
assert(memcmp(value, buf, sz) == 0);
@@ -129,45 +131,51 @@ static enum test_return lru_evict_test(void) {
value2[nvalue2 -1] = '\0';
value2[0] = 'a';
- r = item_set(key2, nkey, value2, nvalue2);
+ r = item_set(l, key2, nkey, value2, nvalue2);
assert(r == 0);
for (i = 0; i < 3; i++) {
if (i == 1) {
continue;
}
- r = item_get(key[i], nkey, buf, sizeof(buf), &sz);
+ r = item_get(l, key[i], nkey, buf, sizeof(buf), &sz);
assert(r == 1);
}
for (i = 3; i < loop; i++) {
- r = item_get(key[i], nkey, buf, sizeof(buf), &sz);
+ r = item_get(l, key[i], nkey, buf, sizeof(buf), &sz);
assert(r == 0);
assert(sz == nvalue);
assert(memcmp(value, buf, sz) == 0);
memset(buf, 0, sizeof(buf));
}
- r = item_get(key2, nkey, buf, sizeof(buf), &sz);
+ r = item_get(l, key2, nkey, buf, sizeof(buf), &sz);
assert(r == 0);
assert(sz == nvalue2);
assert(memcmp(value2, buf, sz) == 0);
memset(buf, 0, sizeof(buf));
- lru_free();
+ lru_free(l);
return TEST_PASS;
}
static enum test_return lru_stat_test(void) {
char buf[1024];
- stat_print(buf, sizeof(buf));
- //printf("%s\n", buf);
+ lru *l = lru_init(0, 0);
+ char *key = "key1";
+ char *value = "value1";
+
+ lru_normal_op(l, 0, key, strlen(key), value, strlen(value) + 1);
+
+ stat_print(l, buf, sizeof(buf));
+ printf("%s\n", buf);
- stat_reset();
+ stat_reset(l);
- stat_print(buf, sizeof(buf));
- //printf("%s\n", buf);
+ stat_print(l, buf, sizeof(buf));
+ printf("%s\n", buf);
return TEST_PASS;
}

0 comments on commit c65e142

Please sign in to comment.