redis五大类型分析--list(1)
此篇为对redis五大数据类型中list的分析,希望能有所帮助
List API
listTypePush函数
void listTypePush(robj *subject, robj *value, int where) {/* 检查编码类型是否为 quicklist (快速列表) */if (subject->encoding == OBJ_ENCODING_QUICKLIST) {/* 根据参数 where 选择插入位置,由 pos 保存插入位置信息 */int pos = (where == LIST_HEAD) ? QUICKLIST_HEAD : QUICKLIST_TAIL;/* value 为整数编码 */if (value->encoding == OBJ_ENCODING_INT) {/* 将 value 先转换为字符串 */char buf[32];ll2string(buf, 32, (long)value->ptr);/* 将元素插入列表 */quicklistPush(subject->ptr, buf, strlen(buf), pos);/* value 为字符串编码 */} else {quicklistPush(subject->ptr, value->ptr, sdslen(value->ptr), pos);}} else {serverPanic("Unknown list encoding");}
}
分析:
该函数将一个元素插入到指定的列表对象 'subject', 插入位置由 'where' 决定是在列表头部还是尾部插入,调用者不需要自己来增加 'value' 的 refcount,该函数会负责处理。
作用:
实现命令函数pushGenericCommand中会用到
/* 读取输入的元素,并向列表插入元素 */for (j = 2; j < c->argc; j++) {listTypePush(lobj,c->argv[j],where);/* 脏数据 + 1,即缓存中未保存到本地的数据 */server.dirty++;}
实现 lmove 命令中向目的列表(destination)插入元素中会用到
/* 向列表中插入元素 */listTypePush(dstobj,value,where);
listPopSaver函数(用于给列表弹出的元素创建副本的函数)
void *listPopSaver(unsigned char *data, size_t sz) {return createStringObject((char*)data,sz);
}
示例:
给quicklistPopCustom传参用到
/* 从列表中弹出元素 */if (quicklistPopCustom(subject->ptr, ql_where, (unsigned char **)&value,NULL, &vlong, listPopSaver))
listTypePop函数(弹出列表元素的通用实现函数)
robj *listTypePop(robj *subject, int where) {long long vlong;robj *value = NULL;/* 根据参数 where 选择插入位置,由 ql_where 保存插入位置信息 */int ql_where = where == LIST_HEAD ? QUICKLIST_HEAD : QUICKLIST_TAIL;/* 检查编码类型是否为 quicklist (快速列表) */if (subject->encoding == OBJ_ENCODING_QUICKLIST) {/* 从列表中弹出元素 */if (quicklistPopCustom(subject->ptr, ql_where, (unsigned char **)&value,NULL, &vlong, listPopSaver)) {/* 如果 value 为 NULL ,则弹出元素被保存在 vlong 中(若不为 NULL 则说明保存在 value 中)* 则用 vlong 创建一个字符串对象并让 value 对其引用 */if (!value)value = createStringObjectFromLongLong(vlong);}} else {serverPanic("Unknown list encoding");}return value;
}
示例:
popGenericCommand函数,弹出一个元素
/* 弹出一个元素,这是 pop 的原始操作,会向客户端回复一个字符串 */value = listTypePop(o,where);
listTypeLength函数(获取列表长度(元素总数))
unsigned long listTypeLength(const robj *subject) {if (subject->encoding == OBJ_ENCODING_QUICKLIST) {return quicklistCount(subject->ptr);} else {serverPanic("Unknown list encoding");}
}
listTypeInitIterator函数(在指定的索引处初始化一个列表迭代器)
listTypeIterator *listTypeInitIterator(robj *subject, long index,unsigned char direction) {/* 给列表迭代器分配内存空间 */listTypeIterator *li = zmalloc(sizeof(listTypeIterator));/* 初始化列表迭代器 */li->subject = subject;li->encoding = subject->encoding;li->direction = direction;li->iter = NULL;/* LIST_HEAD means start at TAIL and move *towards* head.* LIST_TAIL means start at HEAD and move *towards* tail. *//* LIST_HEAD 意味着从列表尾部开始,并向头部移动。* LIST_TAIL 表示从列表头部开始,并向尾部移动 */int iter_direction =direction == LIST_HEAD ? AL_START_TAIL : AL_START_HEAD;/* 检查编码类型是否为 quicklist (快速列表) */if (li->encoding == OBJ_ENCODING_QUICKLIST) {/* 初始化一个 quicklist 节点的迭代器,并且该迭代器指向列表的第 index 个元素,* 虽然用词是”指向“但是迭代器并不是一个指针,而是个结构体,它记录的元素信息是列表第 index 个元素 */li->iter = quicklistGetIteratorAtIdx(li->subject->ptr,iter_direction, index);} else {serverPanic("Unknown list encoding");}return li;
}
用处:
linsertCommand函数中用于遍历查找,初始化迭代器;在addListRangeReply函数中初始化范围起点位置的迭代器
listTypeSetIteratorDirection函数(设置迭代器的方向 )
void listTypeSetIteratorDirection(listTypeIterator *li, unsigned char direction) {li->direction = direction;int dir = direction == LIST_HEAD ? AL_START_TAIL : AL_START_HEAD;quicklistSetDirection(li->iter, dir);
}
listTypeReleaseIterator函数(释放迭代器)
void listTypeReleaseIterator(listTypeIterator *li) {quicklistReleaseIterator(li->iter);zfree(li);//redis定义的一个函数,在free函数的基础上有改变
}
基本上跟在listTypeInitIterator函数后面,释放迭代器
listTypeNext函数
int listTypeNext(listTypeIterator *li, listTypeEntry *entry) {/* Protect from converting when iterating *//* 保护迭代时编码不被转换,则需要迭代器记录的编码类型和迭代器指向的列表对象编码一致 */serverAssert(li->subject->encoding == li->encoding);/* 将参数 li 赋值给参数 entry 的迭代器成员 */entry->li = li;/* 检查编码类型是否为 quicklist (快速列表) */if (li->encoding == OBJ_ENCODING_QUICKLIST) {/* 调用 quicklistNext 函数获取下一个元素,* 元素 (quicklistEntry) 保存在 entry->entry 中,并推进迭代器位置* 如果 下一个元素存在,该函数返回1,否则返回0 */return quicklistNext(li->iter, &entry->entry);} else {serverPanic("Unknown list encoding");}return 0;
}
分析:
获取迭代器指向元素的下一个元素,并推进迭代器的位置(推进方向由迭代器成员 direction 决定)。 如果 entry(下一个元素) 存在,返回1,否则返回0
用处:
linsertCommand函数中用于遍历查找,在addListRangeReply函数中设置迭代器的范围起点位置
总结:
本篇分析了listpush,popsaver,poplength函数,对列表弹出元素和计算列表长度的功能进行分析,同时还分析了关于迭代器初始化,设置方向,释放和获取迭代器下一个元素的函数,对迭代器的功能进行分析。
相关文章:
redis五大类型分析--list(1)
此篇为对redis五大数据类型中list的分析,希望能有所帮助 List API listTypePush函数 void listTypePush(robj *subject, robj *value, int where) {/* 检查编码类型是否为 quicklist (快速列表) */if (subject->encoding OBJ_ENCODING_QUICKLIST) {/* 根据参数…...

【多重信号分类】超分辨率测向方法——依赖于将观测空间分解为噪声子空间和源/信号子空间的方法具有高分辨率(HR)并产生准确的估计(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
【Express.js】集成Websocket
集成websocket 本节我们介绍在如何在 express 中集成 websocket。 WebSocket 服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。 准备工作 创建一个 express.js 项目&a…...

MachineLearningWu_14/P65-P69_Multiclass
x.1 Multiclass多分类问题 对于分类问题,往往指的是二分类问题,而对于二分类的decision boundary较为简单,而实际生活中会有很多问题是多分类问题,例如MNIST手写数字识别, 从特征空间上来看,二分类和多分类…...
深入理解高并发编程 - SimpleDateFormat 类的线程安全问题
1、重现与解决 1.1、重现 import java.text.SimpleDateFormat; import java.util.Date;public class UnsafeSimpleDateFormatExample {public static void main(String[] args) {SimpleDateFormat sdf new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Runnable task…...

接口幂等性实现方式
优质博文:IT-BLOG-CN 幂等 操作的特点是一次和多次请求某一个资源对于资源本身应该具有同样的结果(网络超时等问题除外)。幂等函数或幂等方法是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态&am…...

redis高可用之持久化
目录 一、Redis 高可用的相关知识 1)什么是高可用 2)Redis的高可用技术 3)持久化的功能 4)redis持久化的方式 二、RDB持久化 1)RDB持久化的触发方式 (1)手动触发 (2&…...

Cocos Creator 3.8 后期效果 Shader 编写(2/2) 进阶篇
前言 在上一篇文章中,麒麟子给大家分享了如何在 Cocos Creator 3.8 中的自定义管线中,添加属于自己的后期效果 Shader。 但基于 BlitScreen 的方案,我们只能编写最简单后效 Shader,如果我们想要支持更多复杂的 Shader,…...
【JS自用模板】自动点击选课的操作模板
以激动点击课程为案例复习一下基本前端,容易涉及的问题包括如何提取object类的数字,setTimeout为什么不起作用? 具体思路是,此处会立刻选中符合条件的页面元素打开,然后1小时后会刷新页面,相应地播放页面也…...

TENNECO EDI 项目——X12与XML之间的转换
近期为了帮助广大用户更好地使用 EDI 系统,我们根据以往的项目实施经验,将成熟的 EDI 项目进行开源。用户安装好知行之桥EDI系统之后,只需要下载我们整理好的示例代码,并放置在知行之桥指定的工作区中,即可开始使用。 …...

C++项目:在线五子棋对战(网页版)
项目介绍 本项⽬主要实现⼀个⽹⻚版的五⼦棋对战游戏,其主要⽀持以下核⼼功能: • 用户管理:实现用户注册,用户登录、获取用户信息、用户天梯分数记录、用户比赛场次记录等。 • 匹配对战:实现两个玩家在网页端根据天梯分数匹配游戏对⼿&…...
flutter遇到的小问题记录
flutter-getx的Get.bottomSheet组件改变高度 Get.bottomSheet( isScrollControlled: true,) isScrollControlled: true 就是控制高度 (无语) 截取视频第一针 返回的是本地url 或者Uint8List的数据 String? videoStr await VideoThumbnail.thumbnailFile(video: videoPath,…...

Golang bitset 基本使用
安装: go get github.com/bits-and-blooms/bitset下面代码把fmtx换成fmt就行 //------------基本操作------------//构建一个64bit长度的bitsetb : bitset.New(64)//放入一个数b.Set(10)fmtx.Println("add-10:", b.DumpAsBits()) // 0000000…...
sql 分组讨论,二级分组(非2个字段分组),使用 窗口函数和普通分组实现
1. 二级分组需求 先按照一个字段分组,在按照 第二个字段分组。之后,如果 这个 二级分组中的数据,是 > 1条的。就筛选出来。 比如: 先按照 站点分组,再按照 设备分组, 即:如果站点上配置了…...

业务中如何过滤敏感词
在我们访问网站的时候,如果发现我们发布的内容有色情暴力的东西等等,会屏蔽掉,这种行为就是过滤敏感词。 从技术层面实现起来,其实比较简单,因为我们输入的内容就是一个大型的字符串,我们要调用某些api来判…...
用服务器搭建网站需要做什么
网站建设是一个广义的术语,涵盖了许多不同的技能和学科中所使用的生产和维护的网站。不同领域的网页设计,网页图形设计,界面设计,创作,其中包括标准化的代码和专有软件,用户体验设计和搜索引擎优化。许多人…...

clickhouse 删除操作
OLAP 数据库设计的宗旨在于分析适合一次插入多次查询的业务场景,市面上成熟的 AP 数据库在更新和删除操作上支持的均不是很好,当然 clickhouse 也不例外。但是不友好不代表不支持,本文主要介绍在 clickhouse 中如何实现数据的删除,…...

C 语言中,「.」与「->」有什么区别?
使用“.”的话,只需要声明一个结构体。格式是结构体类型名结构体名。然后通过结构体名加上“.”再加上域名,就可以引用结构体的域了。因为结构体的内存是自动分配的,就像使用int a;一样。而使用“->”的话,需要声明一个结构体的…...

github pages 用法详解 发布自己的网站
github pages 基础用法 URL 规则 假设你的 github 帐号为 mygithub,需要发布的仓库名为 myrepo,那么 pages 的 URL 为: https://mygithub.github.io/myrepo 添加内容 用任意编辑器写好(或者生成)标准的网页内容&a…...

坤简炫酷的JQuery轮播图插件
介绍: 找到了一个炫酷的JQuery轮播图插件,只需要配置三四行代码就可以实现很多二维三维炫酷的切换效果。 视频效果及教程: https://www.bilibili.com/video/BV1Fu4y1d776/ 代码: https://github.com/w-x-x-w/AwesomeWeb 使用…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...

【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...

学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...