mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-04 21:09:19 +08:00
791 lines
19 KiB
C++
791 lines
19 KiB
C++
#include "lib_acl.h"
|
|
#ifndef WIN32
|
|
#include <algorithm>
|
|
#include <vector>
|
|
#endif
|
|
#include "db/zdb.h"
|
|
#include "zdb_test.h"
|
|
#include "md5.h"
|
|
|
|
#pragma pack(4)
|
|
typedef struct {
|
|
int n;
|
|
char s[4];
|
|
} DUMMY;
|
|
#pragma pack(8)
|
|
|
|
#ifndef STORE_PATH
|
|
#define STORE_PATH(s) ACL_FHANDLE_PATH(&(s)->fhandle)
|
|
#endif
|
|
|
|
struct RANGE {
|
|
int from;
|
|
int to;
|
|
};
|
|
|
|
#ifdef WIN32
|
|
#define snprintf _snprintf
|
|
#endif
|
|
|
|
/****************************************************************************/
|
|
|
|
#ifdef WIN32
|
|
static const char *var_md5_key = "hello world!";
|
|
#endif
|
|
|
|
static const char *var_str = "hi!";
|
|
|
|
/* 模拟取得一个随机的整形数组 */
|
|
|
|
#ifndef WIN32
|
|
|
|
static int *random_get(int max, int mod)
|
|
{
|
|
int *a = (int*) acl_mymalloc(sizeof(int) * max);
|
|
int n = 1;
|
|
|
|
if (mod > 1) {
|
|
max /= mod;
|
|
mod--;
|
|
} else
|
|
mod = 0;
|
|
|
|
for (int i = 0; i < max; i++)
|
|
a[i] = i + mod;
|
|
|
|
printf("shuffle: %d\n", n++);
|
|
std::random_shuffle(a, a + max);
|
|
|
|
printf("shuffle: %d\n", n++);
|
|
std::random_shuffle(a, a + max);
|
|
|
|
printf("shuffle: %d\n", n++);
|
|
std::random_shuffle(a, a + max);
|
|
|
|
printf("shuffle: %d\n", n++);
|
|
std::random_shuffle(a, a + max);
|
|
|
|
return (a);
|
|
}
|
|
|
|
#else
|
|
static int *random_get(int max, int mod)
|
|
{
|
|
int i, j, k, *a, key, off = 0;
|
|
char buf[64], key_buf[16];
|
|
int m = 0;
|
|
|
|
/* 先分配一个大数组 */
|
|
a = (int*) acl_mymalloc(sizeof(int) * max);
|
|
|
|
/* 初始化该大数组 */
|
|
memset(a, -1, sizeof(int) * max);
|
|
|
|
printf("begin: max: %d\n", max);
|
|
|
|
for (i = 0; i < max; i++) {
|
|
snprintf(buf, sizeof(buf), "key: %d", i);
|
|
|
|
/* 先 mda5 */
|
|
MD5Key(buf, strlen(buf), var_md5_key, strlen(var_md5_key),
|
|
key_buf, sizeof(key_buf));
|
|
|
|
/* 再取模 */
|
|
key = acl_hash_crc32(key_buf, sizeof(key_buf)) % max;
|
|
if (a[key] == -1) {
|
|
a[key] = i;
|
|
continue;
|
|
}
|
|
|
|
acl_assert(a[key] != i);
|
|
|
|
// printf("key: %d, %d\n", i, a[key]);
|
|
|
|
m++;
|
|
|
|
/* 说明该 key 的数组下标已经被占用,需要顺序找一个位置即可 */
|
|
for (j = off; j < max; j++) {
|
|
if (a[j] == -1) {
|
|
a[j] = i;
|
|
for (k = j + 1; k < max; k++) {
|
|
if (a[k] == -1) {
|
|
off = k;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
acl_assert(j != max);
|
|
}
|
|
|
|
printf("end, m: %d\n", m);
|
|
return (a);
|
|
}
|
|
#endif
|
|
|
|
static void random_free(int *a)
|
|
{
|
|
acl_myfree(a);
|
|
}
|
|
|
|
/* 随机批量写 */
|
|
|
|
static int bench_random_add(ZDB *db, int max, int mod)
|
|
{
|
|
DUMMY dummy;
|
|
int i, ret, *a;
|
|
time_t begin;
|
|
|
|
ACL_SAFE_STRNCPY(dummy.s, var_str, sizeof(dummy.s));
|
|
|
|
a = random_get(max, mod);
|
|
|
|
if (mod > 1)
|
|
max /= mod;
|
|
|
|
time(&begin);
|
|
|
|
printf("---range_random_add: >> max: %d, ", max);
|
|
ACL_METER_TIME(" ");
|
|
|
|
for (i = 0; i < max; i++) {
|
|
dummy.n = i;
|
|
ret = zdb_update(db, a[i], NULL, &dummy, sizeof(dummy));
|
|
if (ret < 0) {
|
|
printf("zdb_udpate error, i: %d, key: %d\n", i, a[i]);
|
|
random_free(a);
|
|
return (-1);
|
|
}
|
|
if (i > 0 && i % 100000 == 0) {
|
|
printf("---%s: >> current: i: %d, key: %d, ",
|
|
__FUNCTION__, i, a[i]);
|
|
ACL_METER_TIME(" ");
|
|
}
|
|
}
|
|
|
|
printf("---range_add: >> end: current: %d, max: %d, ", i, max);
|
|
ACL_METER_TIME(" ");
|
|
|
|
printf("================= update ok, time: %ld ===============\n",
|
|
(long) (time(NULL) - begin));
|
|
|
|
random_free(a);
|
|
return (max);
|
|
}
|
|
|
|
/* 随机批量读 */
|
|
|
|
static int bench_random_get(ZDB *db, int max, int mod)
|
|
{
|
|
DUMMY *dummy;
|
|
int i, *a;
|
|
size_t size;
|
|
ZDB_BLK *blk;
|
|
ZDB_BLK_OFF blk_off;
|
|
time_t begin;
|
|
char buf[64];
|
|
|
|
a = random_get(max, mod);
|
|
|
|
if (mod > 1)
|
|
max /= mod;
|
|
|
|
time(&begin);
|
|
|
|
printf("---range_random_get: >> begin: max: %d, ", max);
|
|
ACL_METER_TIME(" ");
|
|
|
|
for (i = 0; i < max; i++) {
|
|
snprintf(buf, sizeof(buf), "key: %d", i);
|
|
blk = zdb_lookup(db, a[i], &size, &blk_off);
|
|
if (blk == NULL) {
|
|
printf("zdb_lookup error, i: %d\n", i);
|
|
random_free(a);
|
|
return (-1);
|
|
}
|
|
dummy = (DUMMY*) zdb_blk_data(blk);
|
|
if (i > 0 && i % 100000 == 0) {
|
|
printf("---%s: >> current: i: %d, n: %d,"
|
|
" key: %d, blk_off: %lld, ", __FUNCTION__,
|
|
i, dummy->n, a[i], blk_off.offset);
|
|
ACL_METER_TIME(" ");
|
|
}
|
|
zdb_blk_free(blk);
|
|
}
|
|
|
|
printf("---range_get: >> end: current: %d, max: %d, ", i, max);
|
|
ACL_METER_TIME(" ");
|
|
|
|
printf("================= lookup ok, time: %ld ===============\n",
|
|
(long) (time(NULL) - begin));
|
|
|
|
random_free(a);
|
|
return (max);
|
|
}
|
|
|
|
/****************************************************************************/
|
|
|
|
/* 顺序批量写 */
|
|
|
|
static int bench_add(ZDB *db, int max)
|
|
{
|
|
time_t begin;
|
|
int i, ret, delta = 100000;
|
|
DUMMY dummy;
|
|
|
|
if (max <= 100)
|
|
delta = 0;
|
|
time(&begin);
|
|
|
|
ACL_SAFE_STRNCPY(dummy.s, var_str, sizeof(dummy.s));
|
|
|
|
ACL_METER_TIME("----begin---");
|
|
for (i = 0; i < max; i++) {
|
|
dummy.n = i;
|
|
ret = zdb_update(db, i, NULL, &dummy, sizeof(dummy));
|
|
if (ret < 0) {
|
|
printf("zdb_udpate error, i: %d\n", i);
|
|
return (-1);
|
|
}
|
|
if (delta > 0 && i % delta == 0) {
|
|
printf("---%s: i: %d, ", __FUNCTION__, i);
|
|
ACL_METER_TIME("-----");
|
|
} else if (delta == 0)
|
|
printf("---%s: i: %d\n", __FUNCTION__, i);
|
|
}
|
|
printf("---%s: max: %d, ", __FUNCTION__, max);
|
|
ACL_METER_TIME("----end---");
|
|
|
|
printf("================= add ok, time: %ld ===============\n",
|
|
(long) (time(NULL) - begin));
|
|
|
|
return (max);
|
|
}
|
|
|
|
/* 顺序批量修改 */
|
|
|
|
static int bench_update(ZDB *db, int max, int num)
|
|
{
|
|
time_t begin;
|
|
int i, ret, j, delta = 100000;
|
|
DUMMY *dummy;
|
|
|
|
if (max <= 100)
|
|
delta = 0;
|
|
|
|
time(&begin);
|
|
|
|
dummy = (DUMMY*) acl_mycalloc(num, sizeof(DUMMY));
|
|
for (i = 0; i < num; i++) {
|
|
snprintf(dummy[i].s, sizeof(dummy[i].s), "%d", i);
|
|
}
|
|
|
|
ACL_METER_TIME("----begin---");
|
|
for (i = 0; i < max; i++) {
|
|
for (j = 0; j < num; j++)
|
|
dummy[j].n = 0;
|
|
ret = zdb_update(db, i, NULL, dummy, num * sizeof(DUMMY));
|
|
if (ret < 0) {
|
|
printf("zdb_udpate error, i: %d\n", i);
|
|
return (-1);
|
|
}
|
|
if (delta > 0 && i % delta == 0) {
|
|
printf("---%s: i: %d, ", __FUNCTION__, i);
|
|
ACL_METER_TIME("-----");
|
|
} else if (delta == 0)
|
|
printf("---%s: i: %d\n", __FUNCTION__, i);
|
|
}
|
|
printf("---%s: max: %d, ", __FUNCTION__, max);
|
|
ACL_METER_TIME("----end---");
|
|
|
|
printf("================= update ok, time: %ld ===============\n",
|
|
(long) (time(NULL) - begin));
|
|
|
|
acl_myfree(dummy);
|
|
|
|
return (max);
|
|
}
|
|
|
|
/* 顺序批量读 */
|
|
|
|
static int bench_get(ZDB *db, int max)
|
|
{
|
|
ZDB_BLK *blk;
|
|
DUMMY *dummy;
|
|
time_t begin;
|
|
size_t size;
|
|
int i, delta = 100000;
|
|
ZDB_BLK_OFF blk_off;
|
|
|
|
if (max <= 100)
|
|
delta = 0;
|
|
|
|
printf(">> max: %d, delta: %d\n", max, delta);
|
|
time(&begin);
|
|
ACL_METER_TIME("----begin---");
|
|
|
|
//for (i = 0; i < max; i++) {
|
|
for (i = max - 1; i >= 0; i--) {
|
|
blk = zdb_lookup(db, i, &size, &blk_off);
|
|
if (blk == NULL) {
|
|
printf("zdb_lookup error, i: %d\n", i);
|
|
return (-1);
|
|
}
|
|
|
|
dummy = (DUMMY*) zdb_blk_data(blk);
|
|
if (delta == 0)
|
|
printf("---%s: i: %d, n: %d, %s, size: %d,"
|
|
" blk_off: %lld, \n", __FUNCTION__,
|
|
i, dummy[0].n, dummy[0].s,
|
|
(int) size, blk_off.offset);
|
|
else if (delta > 0 && i % delta == 0) {
|
|
printf("---%s: i: %d, n: %d, %s, size: %d,"
|
|
" blk_off: %lld, ", __FUNCTION__,
|
|
i, dummy[0].n, dummy[0].s,
|
|
(int) size, blk_off.offset);
|
|
ACL_METER_TIME("");
|
|
}
|
|
|
|
zdb_blk_free(blk);
|
|
}
|
|
printf("---%s: max: %d, ", __FUNCTION__, max);
|
|
ACL_METER_TIME("----end---");
|
|
|
|
printf("================= lookup ok, time: %ld ===============\n",
|
|
(long) (time(NULL) - begin));
|
|
return (max);
|
|
}
|
|
|
|
/****************************************************************************/
|
|
|
|
static int zdb_test1(ZDB *db)
|
|
{
|
|
DUMMY dummy[2], *pdummy;
|
|
ZDB_BLK *blk;
|
|
size_t size;
|
|
zdb_key_t key = 10000;
|
|
int ret, i;
|
|
|
|
dummy[0].n = (int) key;
|
|
ACL_SAFE_STRNCPY(dummy[0].s, var_str, sizeof(dummy[0].s));
|
|
dummy[1].n = (int) key + 1;
|
|
ACL_SAFE_STRNCPY(dummy[1].s, var_str, sizeof(dummy[1].s));
|
|
|
|
printf(">>> first update, key: %lld, ", key);
|
|
ret = zdb_update(db, key, NULL, &dummy, sizeof(dummy) / 2);
|
|
printf("zdb_update: return %d\n\n", ret);
|
|
|
|
printf(">>> second update, key: %lld, ", key);
|
|
ret = zdb_update(db, key, NULL, &dummy, sizeof(dummy) / 2);
|
|
|
|
blk = zdb_lookup(db, key, &size, NULL);
|
|
if (blk) {
|
|
printf("zdb_lookup: key(%lld), size: %u\n", key, (unsigned) size);
|
|
|
|
pdummy = (DUMMY*) zdb_blk_data(blk);
|
|
for (i = 0; i < (int) (size / sizeof(DUMMY)); i++) {
|
|
printf("zdb_lookup: n: %d, s: %s\n", pdummy->n, pdummy->s);
|
|
pdummy++;
|
|
}
|
|
zdb_blk_free(blk);
|
|
} else
|
|
printf("zdb_lookup: key(%lld), return null\n", key);
|
|
|
|
printf(">>> third update, key: %lld\n", key);
|
|
ret = zdb_update(db, key, NULL, &dummy, sizeof(dummy) / 2);
|
|
|
|
return (ret);
|
|
}
|
|
|
|
static int zdb_test2(ZDB *db)
|
|
{
|
|
DUMMY dummy1[1], dummy2[2], dummy3[3], *pdummy;
|
|
ZDB_BLK *blk;
|
|
int key = 100, ret;
|
|
size_t size, i;
|
|
|
|
dummy1[0].n = key;
|
|
ACL_SAFE_STRNCPY(dummy1[0].s, "1: hello world!", sizeof(dummy1[0].s));
|
|
|
|
dummy2[0].n = key;
|
|
ACL_SAFE_STRNCPY(dummy2[0].s, "2: hello world!", sizeof(dummy2[0].s));
|
|
dummy2[1].n = key;
|
|
ACL_SAFE_STRNCPY(dummy2[1].s, "2: hello world!", sizeof(dummy2[1].s));
|
|
|
|
dummy3[0].n = key;
|
|
ACL_SAFE_STRNCPY(dummy3[0].s, "3: hello world!", sizeof(dummy3[0].s));
|
|
dummy3[1].n = key;
|
|
ACL_SAFE_STRNCPY(dummy3[1].s, "3: hello world!", sizeof(dummy3[1].s));
|
|
dummy3[2].n = key;
|
|
ACL_SAFE_STRNCPY(dummy3[2].s, "3: hello world!", sizeof(dummy3[2].s));
|
|
|
|
ret = zdb_update(db, key, NULL, &dummy1, sizeof(dummy1));
|
|
if (ret < 0) {
|
|
printf("zdb_update: set dummy1 error\n");
|
|
return (-1);
|
|
}
|
|
blk = zdb_lookup(db, key, &size, NULL);
|
|
if (blk == NULL) {
|
|
printf("zdb_lookup: get dummy1 error\n");
|
|
return (-1);
|
|
}
|
|
pdummy = (DUMMY*) zdb_blk_data(blk);
|
|
for (i = 0; i < sizeof(dummy1) / sizeof(DUMMY); i++) {
|
|
printf("dummy1: key: %d, n: %d, s: %s\n", key, pdummy->n, pdummy->s);
|
|
pdummy++;
|
|
}
|
|
zdb_blk_free(blk);
|
|
|
|
ret = zdb_update(db, key, NULL, &dummy2, sizeof(dummy2));
|
|
if (ret < 0) {
|
|
printf("zdb_update: set dummy2 error\n");
|
|
return (-1);
|
|
}
|
|
blk = zdb_lookup(db, key, &size, NULL);
|
|
if (blk == NULL) {
|
|
printf("zdb_lookup: get dummy2 error\n");
|
|
return (-1);
|
|
}
|
|
pdummy = (DUMMY*) zdb_blk_data(blk);
|
|
for (i = 0; i < sizeof(dummy2) / sizeof(DUMMY); i++) {
|
|
printf("dummy2: key: %d, n: %d, s: %s\n", key, pdummy->n, pdummy->s);
|
|
pdummy++;
|
|
}
|
|
zdb_blk_free(blk);
|
|
|
|
ret = zdb_update(db, key, NULL, &dummy3, sizeof(dummy3));
|
|
if (ret < 0) {
|
|
printf("zdb_update: set dummy3 error\n");
|
|
return (-1);
|
|
}
|
|
blk = zdb_lookup(db, key, &size, NULL);
|
|
if (blk == NULL) {
|
|
printf("zdb_lookup: get dummy3 error\n");
|
|
return (-1);
|
|
}
|
|
pdummy = (DUMMY*) zdb_blk_data(blk);
|
|
for (i = 0; i < sizeof(dummy3) / sizeof(DUMMY); i++) {
|
|
printf("dummy3: key: %d, n: %d, s: %s\n", key, pdummy->n, pdummy->s);
|
|
pdummy++;
|
|
}
|
|
zdb_blk_free(blk);
|
|
|
|
return (3);
|
|
}
|
|
|
|
static int key_walk_fn(ZDB_KEY_STORE *store)
|
|
{
|
|
const char *myname = "key_walk_fn";
|
|
ACL_ITER iter;
|
|
ZDB_BLK_OFF *blk_off;
|
|
int i = 0;
|
|
|
|
printf(">>> acl_foreach for %s now:\n", STORE_PATH((ZDB_STORE*) store));
|
|
acl_foreach(iter, (ZDB_STORE*) store) {
|
|
blk_off = (ZDB_BLK_OFF*) iter.data;
|
|
if (i > 0 && (i % 100000) == 0) {
|
|
printf("%s: i:%d, key: %d, blk_off: %lld, inode: %d, ",
|
|
myname, i, iter.i, blk_off->offset, blk_off->inode);
|
|
ACL_METER_TIME("-");
|
|
}
|
|
i++;
|
|
}
|
|
return (i);
|
|
}
|
|
|
|
static int test_zdb_key_walk(ZDB *db)
|
|
{
|
|
const char *myname = "test_zdb_key_walk";
|
|
int ret;
|
|
time_t begin;
|
|
|
|
time(&begin);
|
|
ret = zdb_key_walk(db, key_walk_fn);
|
|
printf(">>>%s, acl_foreach for key, total: %d, time: %ld\n",
|
|
myname, ret, (long) (time(NULL) - begin));
|
|
return (0);
|
|
}
|
|
|
|
static int dat_walk_fn(ZDB_DAT_STORE *store)
|
|
{
|
|
const char *myname = "dat_walk_fn";
|
|
int i = 0;
|
|
ZDB_BLK *blk;
|
|
DUMMY *dummy;
|
|
ACL_ITER iter;
|
|
|
|
printf(">>>%s, acl_foreach for %s now:\n", myname, STORE_PATH((ZDB_STORE*) store));
|
|
|
|
acl_foreach(iter, (ZDB_STORE*) store) {
|
|
blk = (ZDB_BLK*) iter.data;
|
|
dummy = (DUMMY*) zdb_blk_data(blk);
|
|
if (i > 0 && (i % 100000) == 0) {
|
|
printf("%s: i:%d,key:%lld,data:%s,inext:%d,",
|
|
myname, i, blk->hdr.key, dummy->s, iter.i);
|
|
ACL_METER_TIME("-");
|
|
} else if (store->hdr.count <= 100) {
|
|
printf("%s: i:%d, key:%lld, data:%s, inext:%d\n",
|
|
myname, i, blk->hdr.key, dummy->s, iter.i);
|
|
}
|
|
i++;
|
|
}
|
|
|
|
return (i);
|
|
}
|
|
|
|
static int test_zdb_dat_walk(ZDB *db)
|
|
{
|
|
const char *myname = "test_zdb_dat_walk";
|
|
time_t begin;
|
|
int ret;
|
|
|
|
time(&begin);
|
|
ret = zdb_dat_walk(db, dat_walk_fn);
|
|
printf(">>>%s, acl_foreach for dat, total: %d, time: %ld\n",
|
|
myname, ret, (long) (time(NULL) - begin));
|
|
return (ret);
|
|
}
|
|
|
|
static int dat_stat_fn(ZDB_DAT_STORE *store)
|
|
{
|
|
const char *myname = "dat_stat_fn";
|
|
ZDB_DAT_HDR hdr;
|
|
|
|
memcpy(&hdr, &store->hdr, sizeof(ZDB_DAT_HDR));
|
|
|
|
printf("%s(%d): %s's hdr status\n",
|
|
myname, __LINE__, STORE_PATH((ZDB_STORE*) store));
|
|
printf("%s(%d):\tlimit: %lld, size: %lld, used count: %lld\n",
|
|
myname, __LINE__, hdr.limit, hdr.size, hdr.count);
|
|
printf("%s(%d):\tnstep: %d, blk_hdr_dlen: %d, blk_dlen: %d,"
|
|
" blk_count: %d\n", myname, __LINE__, hdr.nstep,
|
|
hdr.blk_hdr_dlen, hdr.blk_dlen, hdr.blk_count);
|
|
printf("%s(%d):\tihead_idle: %d, ihead_busy: %d\n",
|
|
myname, __LINE__, hdr.ihead_idle, hdr.ihead_busy);
|
|
|
|
return (0);
|
|
}
|
|
|
|
static int test_zdb_dat_stat(ZDB *db)
|
|
{
|
|
return (zdb_dat_walk(db, dat_stat_fn));
|
|
}
|
|
|
|
static int key_stat_fn(ZDB_KEY_STORE *store)
|
|
{
|
|
const char *myname = "key_stat_fn";
|
|
ZDB_KEY_HDR key_hdr;
|
|
|
|
memcpy(&key_hdr, &store->hdr, sizeof(ZDB_KEY_HDR));
|
|
|
|
printf(">> %s: %s's status:\n", myname, STORE_PATH((ZDB_STORE*) store));
|
|
printf(">>\tkey_limit: %lld, key_count: %lld, key_begin: %lld\n",
|
|
key_hdr.key_limit, key_hdr.key_count, key_hdr.key_begin);
|
|
|
|
return (0);
|
|
}
|
|
|
|
static int test_zdb_key_stat(ZDB *db)
|
|
{
|
|
return (zdb_key_walk(db, key_stat_fn));
|
|
}
|
|
|
|
static int dat_check_fn(ZDB_DAT_STORE *store)
|
|
{
|
|
return (zdb_dat_check(store, NULL));
|
|
}
|
|
|
|
static int test_zdb_dat_check(ZDB *db)
|
|
{
|
|
return (zdb_dat_walk(db, dat_check_fn));
|
|
}
|
|
|
|
static int key_check_fn(ZDB_KEY_STORE *store)
|
|
{
|
|
return (zdb_key_check(store, NULL));
|
|
}
|
|
|
|
static int test_zdb_key_check(ZDB *db)
|
|
{
|
|
return (zdb_key_walk(db, key_check_fn));
|
|
}
|
|
|
|
void zdb_test_main(const char *cmd)
|
|
{
|
|
const char *myname = "zdb_test";
|
|
ZDB *db;
|
|
const char *dbname = "test", *key_path = "./var";
|
|
|
|
/*ZDB_FLAG_CACHE_DAT | ZDB_FLAG_CACHE_KEY | ZDB_FLAG_SLICE_KEY | ZDB_FLAG_SLICE_DAT;*/
|
|
unsigned int oflags = 0;
|
|
|
|
ZDB_CFG zdb_cfg;
|
|
zdb_key_t key_begin = 0, key_limit = 1000000, dat_limit = 10000000, blk_dlen = sizeof(DUMMY);
|
|
int ret, max = 10000000, use_random = 0, walk_all = 0, dat_nstep = 1000, mod = 1;
|
|
int cache_key_limit = 0, cache_key_timeout = 0;
|
|
int cmd_add = 0, cmd_get = 0, cmd_update = 0, update_num = 2;
|
|
int cmd_stat = 0, cmd_check = 0;
|
|
ACL_ARGV *argv = acl_argv_split(cmd, ":");
|
|
ACL_ITER iter;
|
|
char *name, *value, *ptr;
|
|
char usage[] = "help:stat:check:link:random:walk:add:get:update={d}"
|
|
":max={d}:key_limit={d}:dat_limit={d}:nstep={d}:mod={d}:cache_key_limit={d}"
|
|
":cache_key_timeout={d}";
|
|
|
|
acl_make_dirs(key_path, 0700);
|
|
|
|
acl_foreach(iter, argv) {
|
|
name = ptr = (char*) iter.data;
|
|
if (strcasecmp(name, "help") == 0) {
|
|
printf("usage: %s\n", usage);
|
|
acl_argv_free(argv);
|
|
return;
|
|
} else if (strcasecmp(name, "stat") == 0) {
|
|
cmd_stat = 1;
|
|
continue;
|
|
} else if (strcasecmp(name, "check") == 0) {
|
|
cmd_check = 1;
|
|
continue;
|
|
} else if (strcasecmp(name, "link") == 0) {
|
|
oflags |= ZDB_FLAG_LINK_BUSY;
|
|
continue;
|
|
} else if (strcasecmp(name, "random") == 0) {
|
|
use_random = 1;
|
|
continue;
|
|
} else if (strcasecmp(name, "walk") == 0) {
|
|
walk_all = 1;
|
|
continue;
|
|
} else if (strcasecmp(name, "add") == 0) {
|
|
cmd_add = 1;
|
|
continue;
|
|
} else if (strcasecmp(name, "get") == 0) {
|
|
cmd_get = 1;
|
|
continue;
|
|
}
|
|
|
|
name = acl_mystrtok(&ptr, "=");
|
|
if (name == NULL)
|
|
continue;
|
|
value = acl_mystrtok(&ptr, "=");
|
|
if (value == NULL)
|
|
continue;
|
|
if (strcasecmp(name, "max") == 0) {
|
|
ret = atoi(value);
|
|
if (ret > 0)
|
|
max = ret;
|
|
} else if (strcasecmp(name, "key_limit") == 0) {
|
|
ret = atoi(value);
|
|
if (ret > 0)
|
|
key_limit = ret;
|
|
} else if (strcasecmp(name, "dat_limit") == 0) {
|
|
ret = atoi(value);
|
|
if (ret > 0)
|
|
dat_limit = ret;
|
|
} else if (strcasecmp(name, "update") == 0) {
|
|
ret = atoi(value);
|
|
if (ret > 0) {
|
|
update_num = ret;
|
|
cmd_update = 1;
|
|
}
|
|
} else if (strcasecmp(name, "nstep") == 0) {
|
|
ret = atoi(value);
|
|
if (ret > 0)
|
|
dat_nstep = ret;
|
|
} else if (strcasecmp(name, "mod") == 0) {
|
|
ret = atoi(value);
|
|
if (ret > 0)
|
|
mod = ret;
|
|
} else if (strcasecmp(name, "cache_key_limit") == 0) {
|
|
ret = atoi(value);
|
|
if (ret > 0)
|
|
cache_key_limit = ret;
|
|
} else if (strcasecmp(name, "cache_key_timeout") == 0) {
|
|
ret = atoi(value);
|
|
if (ret > 0)
|
|
cache_key_timeout = ret;
|
|
}
|
|
}
|
|
|
|
acl_argv_free(argv);
|
|
|
|
memset(&zdb_cfg, 0, sizeof(zdb_cfg));
|
|
|
|
/* 初始化 ZDB 存储引擎 */
|
|
zdb_init();
|
|
|
|
/* 开始配置 ZDB 配置对象 */
|
|
zdb_cfg.key_path = key_path;
|
|
zdb_cfg.key_begin = key_begin;
|
|
zdb_cfg.key_limit = key_limit;
|
|
zdb_cfg.dat_limit = dat_limit;
|
|
zdb_cfg.blk_dlen = (int) blk_dlen;
|
|
zdb_cfg.dat_nstep = dat_nstep; /* 值存储文件每次增加的数据块个数 */
|
|
if (cache_key_limit > 0 && cache_key_timeout > 0) {
|
|
zdb_cfg.key_cache_max = cache_key_limit * 2;
|
|
zdb_cfg.key_cache_timeout = cache_key_timeout;
|
|
zdb_cfg.key_wback_max = cache_key_limit;
|
|
oflags |= ZDB_FLAG_CACHE_KEY | ZDB_FLAG_SLICE_KEY;
|
|
printf("===========open key\n");
|
|
} else {
|
|
zdb_cfg.key_cache_max = 0;
|
|
zdb_cfg.key_cache_timeout = 0;
|
|
zdb_cfg.key_wback_max = 0;
|
|
}
|
|
zdb_cfg.dat_cache_max = 0;
|
|
zdb_cfg.dat_cache_timeout = 0;
|
|
zdb_cfg.dat_wback_max = 0;
|
|
|
|
/* 打开一个 ZDB 数据库对象 */
|
|
db = zdb_open(dbname, oflags, &zdb_cfg);
|
|
if (db == NULL)
|
|
acl_msg_fatal("%s: zdb open error(%s)", myname, acl_last_serror());
|
|
|
|
printf("DUMMY.sizeof: %d\n", (int) sizeof(DUMMY));
|
|
|
|
if (0) {
|
|
ret = zdb_test1(db);
|
|
if (ret > 0)
|
|
ret = zdb_test2(db);
|
|
} else
|
|
ret = 1;
|
|
|
|
if (!use_random) {
|
|
if (ret > 0 && cmd_add)
|
|
ret = bench_add(db, max);
|
|
if (ret > 0 && cmd_get)
|
|
ret = bench_get(db, max);
|
|
if (ret > 0 && cmd_update)
|
|
ret = bench_update(db, max, update_num);
|
|
} else {
|
|
if (ret > 0 && cmd_add)
|
|
ret = bench_random_add(db, max, mod);
|
|
if (ret > 0 && cmd_get)
|
|
ret = bench_random_get(db, max, mod);
|
|
}
|
|
|
|
if (walk_all) {
|
|
if (ret > 0)
|
|
ret = test_zdb_dat_walk(db);
|
|
if (ret >= 0)
|
|
ret = test_zdb_key_walk(db);
|
|
}
|
|
|
|
if (cmd_stat) {
|
|
if (ret >= 0)
|
|
ret = test_zdb_dat_stat(db);
|
|
if (ret >= 0)
|
|
ret = test_zdb_key_stat(db);
|
|
}
|
|
|
|
if (cmd_check) {
|
|
if (ret >= 0)
|
|
ret = test_zdb_dat_check(db);
|
|
if (ret >= 0)
|
|
ret = test_zdb_key_check(db);
|
|
}
|
|
|
|
zdb_close(db);
|
|
zdb_end();
|
|
}
|