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 代码理解

  1. 先获取集合键对象,并检查对象类型。
  2. 调用 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 代码理解

  1. 先获取集合键对象,并检查对象类型。
  2. 调用 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 代码理解

  1. 获取集合键对象,并判断类型。
  2. 调用 setTypeRandomElement 方法 随机获取集合中的一个元素。
  3. 根据数据结构调用相应的方法,删除这个元素。
  4. 触发 spop 类型触发事件。
  5. 如果集合中没有元素的话,则需要将集合删除,并触发del 类型触发事件。
  6. 标记键被修改。

4 总结

  1. spop 是从集合中随机弹出一个元素。

Redis源码学习(14),t_set.c 学习(二),sismember,scard,spop 命令学习相关推荐

  1. 达达php源码,达达房卡麻将二次开发VIP系统学习课程

    [↓↓↓资源简介↓↓↓] 1:幼麟棋牌官方学习课程!!!2:幼麟棋牌达达房卡麻将的creator + node.js基础技术课程;3:幼麟棋牌达达房卡麻将的客户端与服务器搭建与源码分析课;对于想学习棋 ...

  2. (素材源码) 猫猫学IOS(十二)UI之UITableView学习(上)LOL英雄联盟练习

    猫猫分享,必须精品 素材代码地址:http://download.csdn.net/detail/u013357243/8542789 原文地址:http://blog.csdn.net/u01335 ...

  3. Redis源码学习(20),学习感悟

      最近学习Redis源码也有半个月的时间了,有不少收获也有不少感悟,今天来好好聊聊我学习的感悟. 1 发现问题   人非圣贤孰能无过,只要是人难免会犯错,回顾我之前的学习历程,其实是可以发现不少的问 ...

  4. Redis源码解析(15) 哨兵机制[2] 信息同步与TILT模式

    Redis源码解析(1) 动态字符串与链表 Redis源码解析(2) 字典与迭代器 Redis源码解析(3) 跳跃表 Redis源码解析(4) 整数集合 Redis源码解析(5) 压缩列表 Redis ...

  5. 阅读 redis 源码,学习缓存淘汰算法 W-TinyLFU

    所有 IT 从业者都接触过缓存,一定了解基本工作原理,业界流行一句话: 缓存就是万金油,哪里有问题哪里抹一下 .那他的本质是什么呢? 上图代表从 cpu 到底层硬盘不同层次,不同模块的运行速度,上层多 ...

  6. redis源码学习笔记目录

    Redis源码分析(零)学习路径笔记 Redis源码分析(一)redis.c //redis-server.c Redis源码分析(二)redis-cli.c Redis源码剖析(三)--基础数据结构 ...

  7. 10年大厂程序员是如何高效学习使用redis的丨redis源码分析丨redis存储原理

    10年大厂程序员是怎么学习使用redis的 1. redis存储原理分析 2. redis源码学习分享 3. redis跳表和B+树详细对比分析 视频讲解如下,点击观看: 10年大厂程序员是如何高效学 ...

  8. 为什么C/C++程序员都要阅读Redis源码之:Redis学习事件驱动设计

    0. 为什么我说C/C++程序员都要阅读Redis源码 主要原因就是『简洁』.如果你用源码编译过Redis,你会发现十分轻快,一步到位.其他语言的开发者可能不会了解这种痛,作为C/C++程序员,如果你 ...

  9. c++ 多线程 类成员函数_为什么我说C/C++程序员都要阅读Redis源码之:通过Redis学习事件驱动设计

    0. 为什么我说C/C++程序员都要阅读Redis源码 主要原因就是『简洁』.如果你用源码编译过Redis,你会发现十分轻快,一步到位.其他语言的开发者可能不会了解这种痛,作为C/C++程序员,如果你 ...

  10. 【Redis学习笔记】2018-05-30 Redis源码学习之Ziplist、Server

    作者:施洪宝 顺风车运营研发团队 一. 压缩列表 压缩列表是Redis的关键数据结构之一.目前已经有大量的相关资料,下面几个链接都已经对Ziplist进行了详细的介绍. http://origin.r ...

最新文章

  1. 后端码农谈前端(CSS篇)第三课:选择器
  2. Apache Kylin v2.6.1 发布,开源的分布式分析引擎
  3. C# winform打印总结 z
  4. DL之PerceptronAdalineGD:基于iris莺尾花数据集利用Perceptron感知机和AdalineGD算法实现二分类
  5. 全球及中国钒(V)蒸发材料行业发展动态分析及未来前景预测报告2021年版
  6. SQLServer存储过程的返回值 查询分析器/程序
  7. 横版游戏的摄像机移动理论与实践(上)
  8. 精通Android自定义View(八)绘制篇Canvas分析之绘制文本
  9. 经典蓝色主题海报设计,永恒色彩趋势
  10. 决策树(二)--C4.5
  11. html返回顶部开始隐藏,回到顶部并且监听顶部按钮显示或隐藏
  12. python编程软件开发_Python编程-绑定方法、软件开发
  13. 父级fixed_子元素使用position:fixed,导致他的宽度不能和父元素保持一致的解决方案...
  14. The Little Schemer读书笔记1
  15. Apache http设置反向代理和负载均衡
  16. 养生的常见方法有哪些?
  17. 各省份非金融类对外直接投资存量(2003-2020年)
  18. 麦克米伦高阶词典 7500词汇表 红星
  19. 中文 gbk gb2312 在线转换 编码码 对照表 自动转换 在线转换(推荐)
  20. QAbstractItemView子类如:QTreeView、QTableView等子项单元格复选框勾选/取消勾选功能实现

热门文章

  1. Python 中 'unicodeescape' codec can't decode bytes in position XXX: trun错误解决方案
  2. 很多人知道外包的种种不好,但还是选择去外包,这是为什么呢?
  3. paddle 基础函数 cosine_decay
  4. Java 的大 Class 到底是什么?,java高级程序员面试笔试宝典蔡羽
  5. 微信网页开发之网页授权获取用户信息
  6. 构建前端项目及使用技术
  7. putty连不上华为云服务器(Linux)怎么办?
  8. Sigfox融资1.5亿欧元扩展LPWA网络
  9. yarn安装依赖时出现错误(2种解决方法)Integrity check failed for “antd“ computed integrity doesn‘t match our records)
  10. pinia 的使用(三)—— actions