实现内存池的测试用例、继承jemalloc和自实现内存池。

This commit is contained in:
2026-01-09 20:09:05 +08:00
parent 4b4e06b33d
commit 1adb24482b
16 changed files with 664 additions and 436 deletions

View File

@@ -68,7 +68,7 @@ void testcase(int connfd, uint8_t op, const char* key, uint32_t key_len, const c
void array_testcase_1w(int connfd) {
int count = 1;
int count = 1000;
int i = 0;
struct timeval tv_begin;
@@ -98,7 +98,7 @@ void array_testcase_1w(int connfd) {
void rbtree_testcase_1w(int connfd) {
int count = 1;
int count = 1000;
int i = 0;
struct timeval tv_begin;
@@ -128,7 +128,7 @@ void rbtree_testcase_1w(int connfd) {
void hash_testcase_1w(int connfd) {
int count = 1;
int count = 1000;
int i = 0;
struct timeval tv_begin;
@@ -156,94 +156,6 @@ void hash_testcase_1w(int connfd) {
}
// void do_batch_SET_example(int fd)
// {
// kvs_batch_t batch;
// kvs_batch_init(&batch);
// char key[10]={0}, val[10]={0};
// // 组 batch最多 64 条)
// for(int i = 0;i < 48; ++ i){
// int len = sprintf(key, "k%d", i);
// len = sprintf(val, "v%d", i);
// kvs_batch_add(&batch, KVS_CMD_SET, key, val);
// }
// // 一次性发送
// kvs_batch_send(fd, &batch);
// // 一次性 recv + parse
// uint8_t recvbuf[BATCH_SIZE];
// kvs_response_t rsps[KVS_BATCH_MAX];
// int nrsp = kvs_batch_recv_parse(fd, &batch, rsps, recvbuf, sizeof(recvbuf));
// // 打印/处理
// for (int i = 0; i < nrsp; i++) {
// int len = sprintf(key, "SET%d", i);
// PRESP(key, &rsps[i]);
// }
// }
// void do_batch_GET_example(int fd)
// {
// kvs_batch_t batch;
// kvs_batch_init(&batch);
// char key[10]={0}, val[10]={0};
// // 组 batch最多 64 条)
// for(int i = 0;i < 48; ++ i){
// int len = sprintf(key, "k%d", i);
// kvs_batch_add(&batch, KVS_CMD_GET, key, NULL);
// }
// // 一次性发送
// kvs_batch_send(fd, &batch);
// // 一次性 recv + parse
// uint8_t recvbuf[BATCH_SIZE];
// kvs_response_t rsps[KVS_BATCH_MAX];
// int nrsp = kvs_batch_recv_parse(fd, &batch, rsps, recvbuf, sizeof(recvbuf));
// // 打印/处理
// for (int i = 0; i < nrsp; i++) {
// int len = sprintf(key, "GET%d", i);
// PRESP(key, &rsps[i]);
// }
// }
// void do_batch_DEL_example(int fd)
// {
// kvs_batch_t batch;
// kvs_batch_init(&batch);
// char key[10]={0}, val[10]={0};
// // 组 batch最多 64 条)
// for(int i = 0;i < 48; ++ i){
// int len = sprintf(key, "k%d", i);
// kvs_batch_add(&batch, KVS_CMD_DEL, key, NULL);
// }
// // 一次性发送
// kvs_batch_send(fd, &batch);
// // 一次性 recv + parse
// uint8_t recvbuf[BATCH_SIZE];
// kvs_response_t rsps[KVS_BATCH_MAX];
// int nrsp = kvs_batch_recv_parse(fd, &batch, rsps, recvbuf, sizeof(recvbuf));
// // 打印/处理
// for (int i = 0; i < nrsp; i++) {
// int len = sprintf(key, "DEL%d", i);
// PRESP(key, &rsps[i]);
// }
// }
void do_batch_test(int fd, int op, const char *key, const char *value){
kvs_batch_t batch;
kvs_batch_init(&batch);
@@ -282,6 +194,74 @@ void save(int connfd){
testcase(connfd, KVS_CMD_SAVE, NULL, 0, NULL, 0, KVS_STATUS_OK, NULL, 0, "SAVE");
}
void testcase_add2_del1_then_add1_del2_100w(int connfd) {
const int N = 1000000;
// 如果你有 KVS_CMD_ADD 就用 ADD没有就用 SET但 SET 会覆盖,意义不同)
// 这里按你说的“会返回 EXIST”所以我用 KVS_CMD_ADD 来写。
// 若你实际命令叫 KVS_CMD_SET 且语义是 ADD请自行替换。
const char *valA = "va";
const char *valB = "vb";
const char *valC = "vc";
char keyA[64], keyB[64], keyC[64];
struct timeval tv_begin, tv_end;
gettimeofday(&tv_begin, NULL);
// ---------------- Phase 1: ADD 两条 DEL 一条 (100w) ----------------
// 每轮ADD A_i, ADD B_i, DEL A_i -> 留下 B_i
for (int i = 0; i < N; i++) {
int klenA = snprintf(keyA, sizeof(keyA), "A_%d", i);
int klenB = snprintf(keyB, sizeof(keyB), "B_%d", i);
testcase(connfd, KVS_CMD_RSET, keyA, klenA, valA, 2, KVS_STATUS_OK, NULL, 0, "P1 ADD A_i");
testcase(connfd, KVS_CMD_RSET, keyB, klenB, valB, 2, KVS_STATUS_OK, NULL, 0, "P1 ADD B_i");
testcase(connfd, KVS_CMD_RDEL, keyA, klenA, NULL, 0, KVS_STATUS_OK, NULL, 0, "P1 DEL A_i");
if(i%10000 == 0) printf("i:%d\n", i);
}
printf("phase 1 end\n");
// ---------------- Phase 2: ADD 一条 DEL 两条 (100w) ----------------
// 每轮ADD C_i, DEL B_i, DEL C_i -> 每轮净删一个 B_i
for (int i = 0; i < N; i++) {
int klenC = snprintf(keyC, sizeof(keyC), "C_%d", i);
int klenB = snprintf(keyB, sizeof(keyB), "B_%d", i);
testcase(connfd, KVS_CMD_RSET, keyC, klenC, valC, 2, KVS_STATUS_OK, NULL, 0, "P2 ADD C_i");
testcase(connfd, KVS_CMD_RDEL, keyB, klenB, NULL, 0, KVS_STATUS_OK, NULL, 0, "P2 DEL B_i");
testcase(connfd, KVS_CMD_RDEL, keyC, klenC, NULL, 0, KVS_STATUS_OK, NULL, 0, "P2 DEL C_i");
if(i%10000 == 0) printf("i:%d\n", i);
}
printf("phase 2 end\n");
// for (int j = 0; j < 5; j++) {
// int idx = (j == 0) ? 0 : (j == 1) ? (N/2) : (N-1);
// int klenA = snprintf(keyA, sizeof(keyA), "A_%d", idx);
// int klenB = snprintf(keyB, sizeof(keyB), "B_%d", idx);
// int klenC = snprintf(keyC, sizeof(keyC), "C_%d", idx);
// testcase(connfd, KVS_CMD_EXIST, keyA, klenA, NULL, 0, KVS_STATUS_NO_EXIST, NULL, 0, "FINAL A not exist");
// testcase(connfd, KVS_CMD_EXIST, keyB, klenB, NULL, 0, KVS_STATUS_NO_EXIST, NULL, 0, "FINAL B not exist");
// testcase(connfd, KVS_CMD_EXIST, keyC, klenC, NULL, 0, KVS_STATUS_NO_EXIST, NULL, 0, "FINAL C not exist");
// }
gettimeofday(&tv_end, NULL);
int time_used = TIME_SUB_MS(tv_end, tv_begin);
// 统计Phase1 每轮3 opsPhase2 每轮3 ops
long long ops = (long long)N * 3 + (long long)N * 3;
long long qps = (time_used > 0) ? (ops * 1000 / time_used) : 0;
printf("ADD2-DEL1 then ADD1-DEL2 (N=%d) --> time_used=%d ms, ops=%lld, qps=%lld\n",
N, time_used, ops, qps);
}
int main(int argc, char *argv[]) {
if (argc != 4) {
@@ -301,6 +281,8 @@ int main(int argc, char *argv[]) {
rbtree_testcase_1w(connfd);
}else if(mode == 2){
hash_testcase_1w(connfd);
}else if(mode == 3){
testcase_add2_del1_then_add1_del2_100w(connfd);
}else if(mode == 10){
do_batch_test(connfd, KVS_CMD_SET, "array_set", "array_val");
}else if(mode == 11){