前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >源码-调试Redis

源码-调试Redis

作者头像
DH镔
发布2023-10-21 11:49:44
1400
发布2023-10-21 11:49:44
举报

# 源码-调试Redis

在阅读源码的时候,通过debug调试的方式逐行去理解代码的意思,不免是一个好的方式。

第一步:

src目录下新建一个文件learn.h,在这里面定义入口

代码语言:javascript
复制
#ifndef REDIS_LEARN_H
#define REDIS_LEARN_H

int learn();

#endif //REDIS_LEARN_H

定义learn.c,例子:

代码语言:javascript
复制
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include "learn.h"
#include "quicklist.h"
#include "ziplist.h"
#include "sds.h"
#include "server.h"
#include "dict.h"

void learn_sds();

/* 压缩链表 */
void learn_ziplist();

/* 快速链表 */
void learn_quicklist();

/* 跳跃表 */
void learn_zsl();

/* 字典 */
void learn_dict();

/* 整数集合 */
void learn_intset();

/* 紧凑列表 */
void learn_listpack();

// =========util=========
void println();
void randomStr(char* str, size_t len);
// =========util=========

int learn() {
//    learn_sds();
//    learn_ziplist();
    // learn_quicklist();
//    learn_zsl();
//    learn_dict();
//    learn_intset();
    learn_listpack();
    exit(0);
    return 0;
}

void learn_sds() {
    sds s = sdsnew("dhb");
    printf("sds: %s\n", s);
    println();
}

void learn_ziplist() {
    /* 创建一个ziplist */
    unsigned char *zl = ziplistNew();
    char *s = "dhbh";
    zl = ziplistPush(zl, (void *) s, 5, ZIPLIST_HEAD);
    char *ss = malloc(254);
    /* 长度大于等于254的情况 */
    zl = ziplistPush(zl, (void *) ss, 254, ZIPLIST_HEAD);

    unsigned int len = ziplistLen(zl);
    printf("ziplist len: %d\n", len);

    unsigned char *p = ziplistIndex(zl, -1);
    while (p != NULL) {
        unsigned char *vstr;
        unsigned int vlen;
        long long vlong;
        ziplistGet(p, &vstr, &vlen, &vlong);
        if (vstr) {
            printf("len : %d value: %s\n", vlen, vstr);
        } else {
            printf("len : %d value: %lld\n", vlen, vlong);
        }
        p = ziplistPrev(zl, p);
    }

    println();
}

void learn_quicklist() {
    quicklist *list = quicklistCreate();
//    quicklistPushHead(list, "hello", 6);
//    quicklistPushHead(list, "xxx", 4);
//    quicklistPushHead(list, "xxxx", 5);

    for(int i = 2; i < 1000; i++) {
        char str[i];
        randomStr(str, i);
        quicklistPushHead(list, str, i);
    }
    unsigned long count = quicklistCount(list);
    printf("快速链表的长度:%lu\n", count);
    /* 快速链表迭代器 */
    quicklistIter *li = quicklistGetIterator(list, AL_START_HEAD);
    quicklistEntry entry;
    /* 遍历,取节点 */
    while (quicklistNext(li, &entry)) {
        printf("str: %s\n", entry.value);
    }
    println();
}

void learn_zsl() {

    zskiplist *zsl = zslCreate();
    for(int i = 2; i < 1000; i++) {
        char str[i];
        randomStr(str, i);
        zslInsert(zsl, i, sdsnew(str));
    }
//    zslInsert(zsl, 10, sdsnew("10"));
//    zslInsert(zsl, 17, sdsnew("17"));
//    zslInsert(zsl, 500, sdsnew("500"));
//    zslInsert(zsl, 11, sdsnew("11"));
//    zslInsert(zsl, 1, sdsnew("1"));
//    zslInsert(zsl, 600, sdsnew("600"));



    zrangespec range;
    range.max = 985;
    range.min = 500;
    range.minex = 1;
    range.maxex = 0;
    zskiplistNode *node = zslFirstInRange(zsl, &range);
    zskiplistNode *node1 = zslLastInRange(zsl, &range);

    println();
}

void learn_dict() {
    dict *myDict = dictCreate(&hashDictType, NULL);
    /* 空扩容 */
    printf("expand ret: %d\n", dictExpand(myDict, 100));
    /* 向字典添加数据,返回0代表成功,否则失败*/
    int ret = dictAdd(myDict, "dhb", "binary");
    printf("want to add 'dhb'-> 'binary' to dict. ret: %d\n", ret);

    /* 根据key查找value值 */
    void *value = dictFetchValue(myDict, "dhb");
    printf("value: %s\n", value);

    println();
    /* 根据key查找value值,返回的是dictEntry */
    dictEntry *valueEntry = dictFind(myDict, "dhb");
    printf("key: %s\n", valueEntry->key);
    printf("value: %s\n", valueEntry->v.val);

}

void learn_intset() {
    intset *is = intsetNew();
    uint8_t ret;
    is = intsetAdd(is, 1, &ret);
    printf("添加1到整数集合中的结果: %d\n", ret);

    // int16 临界值
    is = intsetAdd(is, INT16_MAX - 1, &ret);
    // 升级到int32
    is = intsetAdd(is, INT16_MAX, &ret);
    // int32 临界值
    is = intsetAdd(is, INT32_MAX - 1, &ret);
    // 升级到int64
    is = intsetAdd(is, INT32_MAX, &ret);

    // 中间插入
    is = intsetAdd(is, 3, &ret);

    ret = intsetFind(is, 1);
    printf("在整数集合中查找1的结果: %d\n", ret);
    println();
}

/*
 * 紧凑链表的出现是为了解决压缩链表中更新链表的时候会出现级联更新的问题
 * */
void learn_listpack() {
    unsigned char *lp = lpNew(32);
    lp = lpAppend(lp, "hello", 6);
    lpLast(lp);
    lp = lpAppend(lp, "world", 6);
    uint32_t len = lpLength(lp);
    printf("len: %d\n", len);
    unsigned char *first = lpFirst(lp);
    printf("ele: %s\n", first);
    first = lpNext(lp, first);
    printf("ele: %s\n", first);

}

void randomStr(char* str, size_t len) {
    char* chars = "abcdefghijklmnopqrstuvwxyz";
    int position = 0;
    str[len--] = '\0';
    while(len--) {
        position = random() & 25;
        str[len] = chars[position];
    }
}

void println() {
    printf("====================\n");
}

第二步:生成可执行文件,运行上面的代码

修改src/Makefile,这一步参考chore: 修改调用learn的方式 · DHBin/redis@1052b3e (github.com)open in new window,不一一描述

修改src/server.c,这里面包含了一个mian函数,程序的入口,其中有一段是这样子的

代码语言:javascript
复制
    /* Check if we need to start in redis-check-rdb/aof mode. We just execute
     * the program main. However the program is part of the Redis executable
     * so that we can easily execute an RDB check on loading errors. */
    if (strstr(argv[0],"redis-check-rdb") != NULL)
        redis_check_rdb_main(argc,argv,NULL);
    else if (strstr(argv[0],"redis-check-aof") != NULL)
        redis_check_aof_main(argc,argv);

该代码是判断可执行文件的名称从而去走不同的逻辑,所以我们可以加上走learn逻辑的代码,修改成一下内容

代码语言:javascript
复制
    /* Check if we need to start in redis-check-rdb/aof mode. We just execute
     * the program main. However the program is part of the Redis executable
     * so that we can easily execute an RDB check on loading errors. */
    if (strstr(argv[0],"redis-check-rdb") != NULL)
        redis_check_rdb_main(argc,argv,NULL);
    else if (strstr(argv[0],"redis-check-aof") != NULL)
        redis_check_aof_main(argc,argv);
    else if (strstr(argv[0], "learn") != NULL)
        learn();
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • # 源码-调试Redis
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档