1.介绍

redis中的list既实现了栈(先进后出)又实现了队列(先进先出)

1.示意图

2.各命令详解

LPUSH/RPUSH

LPUSH:

从队列的左边入队一个或多个元素

将所有指定的值插入到存于 key 的列表的头部。如果 key 不存在,那么在进行 push 操作前会创建一个空列表。 如果 key 对应的值不是一个 list 的话,那么会返回一个错误。

可以使用一个命令把多个元素 push 进入列表,只需在命令末尾加上多个指定的参数。元素是从最左端的到最右端的、一个接一个被插入到 list 的头部。

所以对于这个命令例子 LPUSH mylist a b c,返回的列表是 c 为第一个元素, b 为第二个元素, a 为第三个元素。

RPUSH:

从队列的右边入队一个元素

向存于 key 的列表的尾部插入所有指定的值。如果 key 不存在,那么会创建一个空的列表然后再进行 push 操作。 当 key 保存的不是一个列表,那么会返回一个错误。

可以使用一个命令把多个元素打入队列,只需要在命令后面指定多个参数。元素是从左到右一个接一个从列表尾部插入。 比如命令 RPUSH mylist a b c 会返回一个列表,其第一个元素是 a ,第二个元素是 b ,第三个元素是 c。

两个命令都返回list的长度

时间复杂度O(1) 相对于i++的操作

127.0.0.1:6379>lpush mylist c b a

(integer)3

127.0.0.1:6379>rpush mylist d e f

(integer)6

127.0.0.1:6379> lrange mylist 0 5

1) "a"

2) "b"

3) "c"

4) "d"

5) "e"

6) "f"

127.0.0.1:6379>

源码解析

{"rpush",rpushCommand,-3,"write use-memory fast @list",0,NULL,1,1,1,0,0,0},

{"lpush",lpushCommand,-3,"write use-memory fast @list",0,NULL,1,1,1,0,0,0},

LPUSH和RPUSH都是调的同一个函数通过传入LIST_HEAD和LIST_TAIL来判断怎么入队列

void lpushCommand(client *c) {

pushGenericCommand(c,LIST_HEAD);

}void rpushCommand(client *c) {

pushGenericCommand(c,LIST_TAIL);

}

void pushGenericCommand(client *c, int where) {int j, pushed = 0;

robj*lobj = lookupKeyWrite(c->db,c->argv[1]);if (lobj && lobj->type !=OBJ_LIST) {

addReply(c,shared.wrongtypeerr);return;

}for (j = 2; j < c->argc; j++) {if (!lobj) {

lobj=createQuicklistObject();

quicklistSetOptions(lobj->ptr, server.list_max_ziplist_size,

server.list_compress_depth);

dbAdd(c->db,c->argv[1],lobj);

}

listTypePush(lobj,c->argv[j],where);

pushed++;

}

addReplyLongLong(c, (lobj? listTypeLength(lobj) : 0));if(pushed) {char *event = (where == LIST_HEAD) ? "lpush" : "rpush";

signalModifiedKey(c,c->db,c->argv[1]);

notifyKeyspaceEvent(NOTIFY_LIST,event,c->argv[1],c->db->id);

}

server.dirty+=pushed;

}

LPOP/RPOP

LPOP:

移除并且返回 key 对应的 list 的第一个元素。

RPOP:

移除并返回存于 key 的 list 的最后一个元素。

两个命令都返回被移除的元素

时间复杂度O(1) 相对于i--的操作

127.0.0.1:6379>lpop mylist"a"

127.0.0.1:6379>rpop mylist"f"

127.0.0.1:6379> lrange mylist 0 5

1) "b"

2) "c"

3) "d"

4) "e"

127.0.0.1:6379>

源码解析

{"rpop",rpopCommand,2,"write fast @list",0,NULL,1,1,1,0,0,0},

{"lpop",lpopCommand,2,"write fast @list",0,NULL,1,1,1,0,0,0},

void lpopCommand(client *c) {

popGenericCommand(c,LIST_HEAD);

}void rpopCommand(client *c) {

popGenericCommand(c,LIST_TAIL);

}

可见和push一样通过判断LIST_HEAD,来确定删除db中元素

void popGenericCommand(client *c, int where) {

robj*o = lookupKeyWriteOrReply(c,c->argv[1],shared.null[c->resp]);if (o == NULL || checkType(c,o,OBJ_LIST)) return;

robj*value = listTypePop(o,where);if (value ==NULL) {

addReplyNull(c);

}else{char *event = (where == LIST_HEAD) ? "lpop" : "rpop";

addReplyBulk(c,value);

decrRefCount(value);

notifyKeyspaceEvent(NOTIFY_LIST,event,c->argv[1],c->db->id);if (listTypeLength(o) == 0) {

notifyKeyspaceEvent(NOTIFY_GENERIC,"del",

c->argv[1],c->db->id);

dbDelete(c->db,c->argv[1]);

}

signalModifiedKey(c,c->db,c->argv[1]);

server.dirty++;

}

}

LLEN

返回存储在 key 里的list的长度。 如果 key 不存在,那么就被看作是空list,并且返回长度为 0。 当存储在 key 里的值不是一个list的话,会返回error。

时间复杂度:O(1) 相当于常量操作

127.0.0.1:6379>llen mylist

(integer)4

127.0.0.1:6379>

源码解析

{"llen",llenCommand,2,"read-only fast @list",0,NULL,1,1,1,0,0,0},

void llenCommand(client *c) {

robj*o = lookupKeyReadOrReply(c,c->argv[1],shared.czero);if (o == NULL || checkType(c,o,OBJ_LIST)) return;

addReplyLongLong(c,listTypeLength(o));

}

unsigned long listTypeLength(const robj *subject) {if (subject->encoding ==OBJ_ENCODING_QUICKLIST) {return quicklistCount(subject->ptr);

}else{

serverPanic("Unknown list encoding");

}

}

unsigned long quicklistCount(const quicklist *ql) { return ql->count; }

lpush rpush 区别_Redis系列(六):数据结构List双向链表LPUSH、LPOP、RPUSH、RPOP、LLEN命令...相关推荐

  1. redis hash field过期时间_Redis系列-Redis数据类型

    1.全局命令 1.1查看所有键 127.0.0.1:6379> set k1 111OK127.0.0.1:6379> set k2 222OK127.0.0.1:6379> set ...

  2. Redis(六):list/lpush/lrange/lpop 命令源码解析

    上一篇讲了hash数据类型的相关实现方法,没有茅塞顿开也至少知道redis如何搞事情的了吧. 本篇咱们继续来看redis中的数据类型的实现: list 相关操作实现. 同样,我们以使用者的角度,开始理 ...

  3. JAVA面试常考系列六

    转载自 JAVA面试常考系列六 题目一 一个Applet有哪些生命周期? 一个Applet的生命周期分为以下四个阶段: Init 每次加载时都会初始化一个小程序.此方法通知Applet,方法已经被装入 ...

  4. Java学习系列及数据结构博客全目录

    Java学习系列 Java学习系列(一)Java的运行机制.JDK的安装配置及常用命令详解 Java学习系列(二)Java注释.标识符.基本数据类型及其转换易错点详解 Java学习系列(三)Java运 ...

  5. Silverlight Blend动画设计系列六:动画技巧(Animation Techniques)之对象与路径转化、波感特效...

    原文:Silverlight & Blend动画设计系列六:动画技巧(Animation Techniques)之对象与路径转化.波感特效 当我们在进行Silverlight & Bl ...

  6. xen虚拟化实战系列(六)之xen虚拟机破解密码

    xen虚拟化实战系列文章列表 xen虚拟化实战系列(一)之xen虚拟化环境安装 xen虚拟化实战系列(二)之xen虚拟机安装 xen虚拟化实战系列(三)之xen虚拟机复制 xen虚拟化实战系列(四)之 ...

  7. 数学之美系列六 -- 图论和网络爬虫 (Web Crawlers)

    数学之美系列六 -- 图论和网络爬虫 (Web Crawlers) [离散数学是当代数学的一个重要分支,也是计算机科学的数学基础.它包括数理逻辑.集合论.图论和近世代数四个分支.数理逻辑基于布尔运算, ...

  8. 2013年最值得我们学习的网页作品示例【系列六】

    这是本系列的最后一篇文章了,和大家一起学习2013年里最优秀的网页设计作品.在过去的一年,网页设计领域出现了几个新的流行趋势,最热门的要数响应式设计(Responsive Design)和扁平化设计( ...

  9. Web前端开发人员和设计师必读文章推荐【系列六】

    这篇文章收录了十一月份发布在梦想天空的优秀文章,特别推荐给Web开发人员和设计师阅读.梦天空博客关注前端开发技术,展示最新HTML5和CSS3技术应用,分享实用的jQuery插件,推荐优秀的网页设计案 ...

  10. struts2官方 中文教程 系列六:表单验证

    先贴个本帖的地址,以免被爬:struts2教程 官方系列六:表单验证  即 http://www.cnblogs.com/linghaoxinpian/p/6906720.html 下载本章节代码 介 ...

最新文章

  1. 内核通信错误处理方法
  2. LSTM-pytorch 写诗之位置编码
  3. jquery 常见选择器详解3
  4. Dwg图纸属性的读取
  5. JavaScript 技术篇-使用js代码获取浏览器窗口标题名,js获取页面URL地址
  6. Python - 列表与字符串的互相转换
  7. 阿里云专家穆轩的《杭州九年程序员之“修炼”手册》
  8. 爬虫用mysql存储还是mongodb_【面试题】Mongodb和MySQL存储爬虫数据的特点是什么?...
  9. Apache Commons DbUtils 入门
  10. 求解平稳分布matlab,计算二阶马尔可夫信源的熵
  11. webpack5学习与实战-(一)-webpack的初步认识
  12. java dagger2_mvp+dagger2+retrofit2+rxjava 项目框架 最佳实践
  13. 信息学奥赛C++编程:计算分数加减表达式的值
  14. linux 禁用超线程,Linux动态启用/禁用超线程技术
  15. 上涨趋势回踩均线选股器
  16. 将java封装的实体类数据生成excel供下载
  17. 库乐队历史版本怎么下载_ios库乐队旧版本下载
  18. 计算机表格性格计算,MBTI职业性格测试自动计算得分并得出分析结果.docx
  19. JDBC+MySQL入门增删改查案例
  20. 真我Realme GT Neo5有无线充电吗? 真我Realme GT Neo5快充速度是多少瓦?

热门文章

  1. 【Android 安装包优化】Android 中使用 SVG 图片 ( 批量转换 SVG 格式图片为 Vector Asset 矢量图资源 )
  2. jinja2说明文档
  3. python打开rar_使用Python解压zip、rar文件
  4. android 调用百度地图客户端,
  5. POJ3207,2-sat问题
  6. 打印纸张尺寸换算_常用纸张的尺寸大小对照表
  7. 7-6 华氏度转摄氏度(四舍五入)
  8. 前端工作七个月经验总结以及技术分享
  9. python可以手眼定标吗_机器人无标定手眼协调
  10. 静态HTML网页设计作品——食品餐饮行业网站模板(10页) HTML+CSS+JavaScript 学生DW网页设计作业成品 美食生鲜零食网页设计