【Redis源码】Redis命令INCR、DECR、INCRBY、DECRBY学习(二)

20 篇文章 3 订阅

前言:

该篇内容为我对redis的学习记录,欢迎指正批评。文中只是放了部分调试内容,完整的可以根据流程图跟踪。

 

redis版本:4.0.0

调试工具:lldb

一.redis incr命令调用流程

DECR和INCR和类似只是一个是增加一个是减少。其余两个命令也大同小异;

 

二.源码分析

4个命令相应源码,t_string.c中:

void incrCommand(client *c) {
    incrDecrCommand(c,1);      //incr每次增加1 命令原型:incr test1
}

void decrCommand(client *c) {
    incrDecrCommand(c,-1);     //incr每次减少1 命令原型:decr test1
}

void incrbyCommand(client *c) {
    long long incr;

    if (getLongLongFromObjectOrReply(c, c->argv[2], &incr, NULL) != C_OK) return;   //获得第二个,增加数量
    incrDecrCommand(c,incr);    //incrby每次增加输入的数 命令原型增加100:incrby test1 100
}

void decrbyCommand(client *c) {
    long long incr;

    if (getLongLongFromObjectOrReply(c, c->argv[2], &incr, NULL) != C_OK) return;  //获得第二个,减少数量
    incrDecrCommand(c,-incr);   //decrby每次加少输入的数 命令原型减少100:decrby test1 100
}

 

incrDecrCommand函数源码 ,t_string.c中:

void incrDecrCommand(client *c, long long incr) {
    long long value, oldvalue;
    robj *o, *new;

    o = lookupKeyWrite(c->db,c->argv[1]);         //查找有没有对应的键值
    if (o != NULL && checkType(c,o,OBJ_STRING)) return;      //判断类型
    if (getLongLongFromObjectOrReply(c,o,&value,NULL) != C_OK) return;  //获得键值中的数据

    oldvalue = value;
    if ((incr < 0 && oldvalue < 0 && incr < (LLONG_MIN-oldvalue)) ||
        (incr > 0 && oldvalue > 0 && incr > (LLONG_MAX-oldvalue))) {   //判断不能不能越界,超出long long范围
        addReplyError(c,"increment or decrement would overflow");
        return;
    }
    value += incr;   //与操作数相加

    /*
    判断是否大于对象共享整数,value是否在long只最小到最大之间。共享对象整数为大于10000
    */
    if (o && o->refcount == 1 && o->encoding == OBJ_ENCODING_INT &&
        (value < 0 || value >= OBJ_SHARED_INTEGERS) &&
        value >= LONG_MIN && value <= LONG_MAX)                     
    {
        new = o;
        o->ptr = (void*)((long)value);
    } else {
        new = createStringObjectFromLongLong(value); //根据数值创建一个long long的robj结构指针
        if (o) {
            dbOverwrite(c->db,c->argv[1],new);     //重写字典
        } else {
            dbAdd(c->db,c->argv[1],new);           //添加字典
        }
    }
    signalModifiedKey(c->db,c->argv[1]); //通知修改了key
    notifyKeyspaceEvent(NOTIFY_STRING,"incrby",c->argv[1],c->db->id); //发送事件通知
    server.dirty++;
    addReply(c,shared.colon);
    addReply(c,new);
    addReply(c,shared.crlf);
}

 

 

三.调试信息(看图片可能看不懂,先看流程图,根据图片再看)

 

下一个call断点,然后进入incrCommand

打印命令信息,以及调用栈 

 

获得long long对象调试

增加数据部分调试

有键值是覆盖写入

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值