redis源码分析-string的incr操作

  1. incr、decr、incrby都会调用相同的incrDecrCommand函数,里面再传进正负1或者指定的数字

    void incrCommand(client *c) {
    	incrDecrCommand(c,1);
    }
    
  2. 接下来主要分析incrDecrCommand函数

    1. 用2个long long类型的数字分别记录修改前后的值,并且用2个robj实例来记录当前redis变量。robj是redis通用元素类型,可以理解为string、list等数据结构的共同父类。
    2. 通过lookupKeyWrite函数从数据库中得到该实例,然后检查该实例是否是string类型还是long long类型。
    3. 从该实例中获取其中的value值,并和oldvalue共享。
    4. 判断相加减后是否溢出。
    5. value值进行加减操作。
    6. 主要判断lookup到的实例是否存在,并且引用计数器为1。如果是的话,通过ptr修改robj的值。
    7. 如果上述条件不成立,则根据最新的value新构建一个long long类型的实例,如果是原来不存在robj实例,则dbAdd一个实例,如果是引用计数器不为1的话,则dbOverwrite重写该实例。
void incrDecrCommand(client *c, long long incr) {
    long long value, oldvalue;
    robj *o, *new;

    o = lookupKeyWrite(c->db,c->argv[1]);
    if (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))) {
        addReplyError(c,"increment or decrement would overflow");
        return;
    }
    value += incr;

    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 = createStringObjectFromLongLongForValue(value);
        if (o) {
            dbOverwrite(c->db,c->argv[1],new);
        } else {
            dbAdd(c->db,c->argv[1],new);
        }
    }
    signalModifiedKey(c,c->db,c->argv[1]);
    notifyKeyspaceEvent(NOTIFY_STRING,"incrby",c->argv[1],c->db->id);
    server.dirty++;
    addReplyLongLong(c, value);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值