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

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

前言:

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

一.redis incr命令调用流程

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

二.源码分析

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


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

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

voidincrbyCommand(client *c) {
   longlong incr;

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

voiddecrbyCommand(client *c) {
   longlong incr;

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

incrDecrCommand函数源码 ,t_string.c中:

voidincrDecrCommand(client *c, longlong incr) {
   longlong 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对象调试

增加数据部分调试

有键值是覆盖写入


相关文章
|
存储 缓存 监控
Redis设计与实现——Redis命令参考与高级特性
Redis 是一个高性能的键值存储系统,支持丰富的数据类型(字符串、列表、哈希、集合等)和多种高级功能。本文档涵盖 Redis 的核心命令分类,包括数据类型操作、事务与脚本、持久化、集群管理、系统监控等。特别介绍了事务的原子性特性、Lua 脚本的执行方式及优势、排序机制、发布订阅模型以及慢查询日志和监视器工具的使用方法。适用于开发者快速掌握 Redis 常用命令及其应用场景,优化系统性能与可靠性。
624 12
|
11月前
|
NoSQL 算法 Redis
【Docker】(3)学习Docker中 镜像与容器数据卷、映射关系!手把手带你安装 MySql主从同步 和 Redis三主三从集群!并且进行主从切换与扩容操作,还有分析 哈希分区 等知识点!
Union文件系统(UnionFS)是一种**分层、轻量级并且高性能的文件系统**,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem) Union 文件系统是 Docker 镜像的基础。 镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
1005 6
|
12月前
|
存储 缓存 NoSQL
Redis基础命令与数据结构概览
Redis是一个功能强大的键值存储系统,提供了丰富的数据结构以及相应的操作命令来满足现代应用程序对于高速读写和灵活数据处理的需求。通过掌握这些基础命令,开发者能够高效地对Redis进行操作,实现数据存储和管理的高性能方案。
377 12
|
NoSQL Redis
Lua脚本协助Redis分布式锁实现命令的原子性
利用Lua脚本确保Redis操作的原子性是分布式锁安全性的关键所在,可以大幅减少由于网络分区、客户端故障等导致的锁无法正确释放的情况,从而在分布式系统中保证数据操作的安全性和一致性。在将这些概念应用于生产环境前,建议深入理解Redis事务与Lua脚本的工作原理以及分布式锁的可能问题和解决方案。
481 8
|
12月前
|
存储 消息中间件 NoSQL
【Redis】常用数据结构之List篇:从常用命令到典型使用场景
本文将系统探讨 Redis List 的核心特性、完整命令体系、底层存储实现以及典型实践场景,为读者构建从理论到应用的完整认知框架,助力开发者在实际业务中高效运用这一数据结构解决问题。
|
存储 缓存 人工智能
Redis六大常见命令详解:从set/get到过期策略的全方位解析
本文将通过结构化学习路径,帮助读者实现从命令语法掌握到工程化实践落地的能力跃迁,系统性提升 Redis 技术栈的应用水平。
|
机器学习/深度学习 数据采集 人机交互
springboot+redis互联网医院智能导诊系统源码,基于医疗大模型、知识图谱、人机交互方式实现
智能导诊系统基于医疗大模型、知识图谱与人机交互技术,解决患者“知症不知病”“挂错号”等问题。通过多模态交互(语音、文字、图片等)收集病情信息,结合医学知识图谱和深度推理,实现精准的科室推荐和分级诊疗引导。系统支持基于规则模板和数据模型两种开发原理:前者依赖人工设定症状-科室规则,后者通过机器学习或深度学习分析问诊数据。其特点包括快速病情收集、智能病症关联推理、最佳就医推荐、分级导流以及与院内平台联动,提升患者就诊效率和服务体验。技术架构采用 SpringBoot+Redis+MyBatis Plus+MySQL+RocketMQ,确保高效稳定运行。
1002 0