Redis源码学习(14),t_set.c 学习(二),sismember,scard,spop 命令学习
1 sismemberCommand
1.1 方法说明
判断一个值是否属于集合的成员,成功返回1,失败返回0。
1.2 命令实践
1.3 方法源代码
void sismemberCommand(redisClient *c) {robj *set;//获取集合键对象if ((set = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||checkType(c,set,REDIS_SET)) return;c->argv[2] = tryObjectEncoding(c->argv[2]);//判断一个元素是否属于对象if (setTypeIsMember(set,c->argv[2]))addReply(c,shared.cone);elseaddReply(c,shared.czero);
}
int setTypeIsMember(robj *subject, robj *value) {long long llval;//如果是哈希表if (subject->encoding == REDIS_ENCODING_HT) {return dictFind((dict*)subject->ptr,value) != NULL;}//如果是整数集合 else if (subject->encoding == REDIS_ENCODING_INTSET) {if (isObjectRepresentableAsLongLong(value,&llval) == REDIS_OK) {return intsetFind((intset*)subject->ptr,llval);}} else {redisPanic("Unknown set encoding");}return 0;
}
1.4 代码理解
- 先获取集合键对象,并检查对象类型。
- 调用 setTypeIsMember 判断元素是否属于集合中。
2 scardCommand
2.1 方法说明
获取集合元素的个数。
2.2 命令实践
2.3 方法源代码
void scardCommand(redisClient *c) {robj *o;//获取键,并判断键类型if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||checkType(c,o,REDIS_SET)) return;//获取集合的长度addReplyLongLong(c,setTypeSize(o));
}
unsigned long setTypeSize(robj *subject) {//如果是哈希表if (subject->encoding == REDIS_ENCODING_HT) {return dictSize((dict*)subject->ptr);} //如果是整数集合else if (subject->encoding == REDIS_ENCODING_INTSET) {return intsetLen((intset*)subject->ptr);} else {redisPanic("Unknown set encoding");}
}
2.4 代码理解
- 先获取集合键对象,并检查对象类型。
- 调用 setTypeIsMember 判断元素是否属于集合中。
3 spopCommand
3.1 方法说明
从集合中随机弹出一个元素,成功返回弹出的元素。
3.2 命令实践
3.3 方法源代码
void spopCommand(redisClient *c) {robj *set, *ele, *aux;int64_t llele;int encoding;//获取集合键对象,并判断类型if ((set = lookupKeyWriteOrReply(c,c->argv[1],shared.nullbulk)) == NULL ||checkType(c,set,REDIS_SET)) return;//随机获取集合中的一个元素encoding = setTypeRandomElement(set,&ele,&llele);//从集合中删除这个元素if (encoding == REDIS_ENCODING_INTSET) {ele = createStringObjectFromLongLong(llele);set->ptr = intsetRemove(set->ptr,llele,NULL);} else {incrRefCount(ele);setTypeRemove(set,ele);}//触发通知事件notifyKeyspaceEvent(REDIS_NOTIFY_SET,"spop",c->argv[1],c->db->id);/* Replicate/AOF this command as an SREM operation */aux = createStringObject("SREM",4);rewriteClientCommandVector(c,3,aux,c->argv[1],ele);decrRefCount(ele);decrRefCount(aux);addReplyBulk(c,ele);//如果集合中没有元素,则删除集合键if (setTypeSize(set) == 0) {dbDelete(c->db,c->argv[1]);notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",c->argv[1],c->db->id);}//标记键被修改signalModifiedKey(c->db,c->argv[1]);server.dirty++;
}
/* Return random element from a non empty set.* The returned element can be a int64_t value if the set is encoded* as an "intset" blob of integers, or a redis object if the set* is a regular set.** The caller provides both pointers to be populated with the right* object. The return value of the function is the object->encoding* field of the object and is used by the caller to check if the* int64_t pointer or the redis object pointer was populated.** When an object is returned (the set was a real set) the ref count* of the object is not incremented so this function can be considered* copy on write friendly. */
int setTypeRandomElement(robj *setobj, robj **objele, int64_t *llele) {if (setobj->encoding == REDIS_ENCODING_HT) {dictEntry *de = dictGetRandomKey(setobj->ptr);*objele = dictGetKey(de);} else if (setobj->encoding == REDIS_ENCODING_INTSET) {*llele = intsetRandom(setobj->ptr);} else {redisPanic("Unknown set encoding");}return setobj->encoding;
}
3.4 代码理解
- 获取集合键对象,并判断类型。
- 调用 setTypeRandomElement 方法 随机获取集合中的一个元素。
- 根据数据结构调用相应的方法,删除这个元素。
- 触发 spop 类型触发事件。
- 如果集合中没有元素的话,则需要将集合删除,并触发del 类型触发事件。
- 标记键被修改。
4 总结
- spop 是从集合中随机弹出一个元素。
Redis源码学习(14),t_set.c 学习(二),sismember,scard,spop 命令学习相关推荐
- 达达php源码,达达房卡麻将二次开发VIP系统学习课程
[↓↓↓资源简介↓↓↓] 1:幼麟棋牌官方学习课程!!!2:幼麟棋牌达达房卡麻将的creator + node.js基础技术课程;3:幼麟棋牌达达房卡麻将的客户端与服务器搭建与源码分析课;对于想学习棋 ...
- (素材源码) 猫猫学IOS(十二)UI之UITableView学习(上)LOL英雄联盟练习
猫猫分享,必须精品 素材代码地址:http://download.csdn.net/detail/u013357243/8542789 原文地址:http://blog.csdn.net/u01335 ...
- Redis源码学习(20),学习感悟
最近学习Redis源码也有半个月的时间了,有不少收获也有不少感悟,今天来好好聊聊我学习的感悟. 1 发现问题 人非圣贤孰能无过,只要是人难免会犯错,回顾我之前的学习历程,其实是可以发现不少的问 ...
- Redis源码解析(15) 哨兵机制[2] 信息同步与TILT模式
Redis源码解析(1) 动态字符串与链表 Redis源码解析(2) 字典与迭代器 Redis源码解析(3) 跳跃表 Redis源码解析(4) 整数集合 Redis源码解析(5) 压缩列表 Redis ...
- 阅读 redis 源码,学习缓存淘汰算法 W-TinyLFU
所有 IT 从业者都接触过缓存,一定了解基本工作原理,业界流行一句话: 缓存就是万金油,哪里有问题哪里抹一下 .那他的本质是什么呢? 上图代表从 cpu 到底层硬盘不同层次,不同模块的运行速度,上层多 ...
- redis源码学习笔记目录
Redis源码分析(零)学习路径笔记 Redis源码分析(一)redis.c //redis-server.c Redis源码分析(二)redis-cli.c Redis源码剖析(三)--基础数据结构 ...
- 10年大厂程序员是如何高效学习使用redis的丨redis源码分析丨redis存储原理
10年大厂程序员是怎么学习使用redis的 1. redis存储原理分析 2. redis源码学习分享 3. redis跳表和B+树详细对比分析 视频讲解如下,点击观看: 10年大厂程序员是如何高效学 ...
- 为什么C/C++程序员都要阅读Redis源码之:Redis学习事件驱动设计
0. 为什么我说C/C++程序员都要阅读Redis源码 主要原因就是『简洁』.如果你用源码编译过Redis,你会发现十分轻快,一步到位.其他语言的开发者可能不会了解这种痛,作为C/C++程序员,如果你 ...
- c++ 多线程 类成员函数_为什么我说C/C++程序员都要阅读Redis源码之:通过Redis学习事件驱动设计
0. 为什么我说C/C++程序员都要阅读Redis源码 主要原因就是『简洁』.如果你用源码编译过Redis,你会发现十分轻快,一步到位.其他语言的开发者可能不会了解这种痛,作为C/C++程序员,如果你 ...
- 【Redis学习笔记】2018-05-30 Redis源码学习之Ziplist、Server
作者:施洪宝 顺风车运营研发团队 一. 压缩列表 压缩列表是Redis的关键数据结构之一.目前已经有大量的相关资料,下面几个链接都已经对Ziplist进行了详细的介绍. http://origin.r ...
最新文章
- 后端码农谈前端(CSS篇)第三课:选择器
- Apache Kylin v2.6.1 发布,开源的分布式分析引擎
- C# winform打印总结 z
- DL之PerceptronAdalineGD:基于iris莺尾花数据集利用Perceptron感知机和AdalineGD算法实现二分类
- 全球及中国钒(V)蒸发材料行业发展动态分析及未来前景预测报告2021年版
- SQLServer存储过程的返回值 查询分析器/程序
- 横版游戏的摄像机移动理论与实践(上)
- 精通Android自定义View(八)绘制篇Canvas分析之绘制文本
- 经典蓝色主题海报设计,永恒色彩趋势
- 决策树(二)--C4.5
- html返回顶部开始隐藏,回到顶部并且监听顶部按钮显示或隐藏
- python编程软件开发_Python编程-绑定方法、软件开发
- 父级fixed_子元素使用position:fixed,导致他的宽度不能和父元素保持一致的解决方案...
- The Little Schemer读书笔记1
- Apache http设置反向代理和负载均衡
- 养生的常见方法有哪些?
- 各省份非金融类对外直接投资存量(2003-2020年)
- 麦克米伦高阶词典 7500词汇表 红星
- 中文 gbk gb2312 在线转换 编码码 对照表 自动转换 在线转换(推荐)
- QAbstractItemView子类如:QTreeView、QTableView等子项单元格复选框勾选/取消勾选功能实现
热门文章
- Python 中 'unicodeescape' codec can't decode bytes in position XXX: trun错误解决方案
- 很多人知道外包的种种不好,但还是选择去外包,这是为什么呢?
- paddle 基础函数 cosine_decay
- Java 的大 Class 到底是什么?,java高级程序员面试笔试宝典蔡羽
- 微信网页开发之网页授权获取用户信息
- 构建前端项目及使用技术
- putty连不上华为云服务器(Linux)怎么办?
- Sigfox融资1.5亿欧元扩展LPWA网络
- yarn安装依赖时出现错误(2种解决方法)Integrity check failed for “antd“ computed integrity doesn‘t match our records)
- pinia 的使用(三)—— actions