【Redis源码】append命令
2023-06-13 09:11:31 时间
简介
数据库已经有了key,它的值为value。当我们发现value值需要追加字符串却又不想直接用set命令覆盖原值时,可以用append命令来实现。
命令格式:
append key value
- 说明: 将value追加到原值的末尾,如果key不存在,此命令等同于set key value命令。
append 实现
现在介绍在key已经存在的情况下进行的操作。我们知道,只有value为字符串时才可以追加字符串,数字是不可以追加的,所以当key存在时,首先判断下value的类型是否为string类型。如果不为string类型时会报错。
if (checkType(c,o,OBJ_STRING))
return;
在追加字符串时,需要判断追加后的字符串长度必须小于512MB,否则会报错。
append = c->argv[2];
totlen = stringObjectLen(o)+sdslen(append->ptr);//检查长度
if (checkStringLength(c,totlen) != C_OK)
checkStringLength函数原型如下:
static int checkStringLength(client *c, long long size) {
if (size > 512*1024*1024) {
addReplyError(c,"string exceeds maximum allowed size (512MB)");
return C_ERR;
}
return C_OK;
}
这里我们不禁要问,为什么在追加字符串时才考虑追加后的长度不能大于512 MB,那么在set命令时为什么没有限制最大长度呢?在networking.c中找到如下代码:
ok = string2ll(c->querybuf+1+c->qb_pos,newline-(c->querybuf+1+c->qb_pos),&ll);
if (!ok || ll > 1024*1024) {
addReplyError(c,"Protocol error: invalid multibulk length");
setProtocolError("invalid mbulk count",c);
return C_ERR;
}
由此可见,在服务端接收到命令的时候,就已经判断了命令的最大长度不能大于1 MB,所以set命令不需要再次判断了。
字符串追加会修改原字符串的值,所以必须保证字符串是非共享的。如果字符串是共享的,则需要解除共享,新创建一个值对象。实现代码为:
robj *dbUnshareStringValue(redisDb *db, robj *key, robj *o) {
serverAssert(o->type == OBJ_STRING);
if (o->refcount != 1 || o->encoding != OBJ_ENCODING_RAW) {
// 如果是共享的,则需要解除共享,创建新的字符串
robj *decoded = getDecodedObject(o);
o = createRawStringObject(decoded->ptr, sdslen(decoded->ptr));
decrRefCount(decoded);
dbOverwrite(db,key,o);
}
return o;
}
值对象创建好之后,将新字符串追加到原字符串末尾。
o->ptr = sdscatlen(o->ptr,append->ptr,sdslen(append->ptr));
这样就完成了字符串的append操作。
相关文章
- 数据结构深入浅出Redis之字典数据结构(redis字典)
- Redis特性:快速、可靠、高效(redis的特性)
- 探索Redis集群的神奇搭建世界(redis集群的搭建)
- 利用Redis灵活保存复杂数据结构(redis保存复杂对象)
- 「Redis客户端」连接易用工具:上手简单,功能强大!(redis客户端连接工具)
- Easy Steps to Download Redis The Powerful Data Structure Server(下载redis)
- 自学研究Redis手写Redis源码的过程(手写redis源码)
- 服务如何在Redis集群中定位服务(怎么在redis集群找到)
- 使用Redis缓存,提升网站访问速度(网站redis缓存)
- 解读Redis源码,展开深度理解(看懂redis源码)
- 深入探索使用Redis缓存的好处(用redis做缓存的原因)
- 深入研究Redis源码分析(源码分析redis)
- 掌握Redis必备技能优雅清楚队列值的命令(清除redis队列值命令)
- 用命令清空Redis缓存(清空redis的命令)
- 用清Redis命令优化数据库性能(清redis命令)
- 如何关闭Redis数据库(关闭redis数据库命令)
- 从零起步学习如何阅读Redis源码(如何看懂redis源码)
- 如何快速查看Redis命令帮助信息(如何查看redis 命令)
- 如何使用Redis客户端轻松连接Redis服务器(如何redis客户端连接)
- 教你一步步操作命令行连接Redis(命令连接redis步骤)
- Redis让你失去集合超时的担忧(redis 集合超时)
- Redis集合的查询大招到底是什么(redis集合查询命令)
- 红色的抑制Redis 限频 (redis 限频)
- 导致的问题Redis连接过多引发的危害(redis 链接太多)
- Redis连接命令的测试与验证(redis 连接命令测试)
- Redis玩转命令行火速掌握运行技能(redis 运行命令大全)
- Redis解决超内存之道(redis 超过内存容量)
- 红色的蚁穴Redis 操作指南(redis 该如何使用)
- 深入探索Redis的多重使用方式(redis设置多个命令)
- 使用Redis缓解抢购压力(redis解决抢购问题)
- 研究Redis淘汰策略算法探索优化空间(redis淘汰策略算法)