【Redis源码】setrange命令

2022-08-26 19:40:14 浏览数 (1)

简介

setrange命令主要用于设置value的部分子串,设置时将值从偏移量offset开始覆盖成value值。如果偏移值大于原值的长度,则偏移量之前的字符串由“x00”填充。

命令格式:

代码语言:javascript复制
setrange key offset value

setrange 命令

由于要指定值的偏移量,所以setrange在执行时会首先判断offset参数必须为long类型且必须大于等于0,否则设置失败。

与append命令一样,原key在Redis中不存在时,Redis会创建一个robj对象,并将robj先设置到数据库;当key在Redis中存在时,会要求原值必须为string类型,并且由于Redis的限制,value的长度加offset值必须小于512 MB。

代码语言:javascript复制
if (checkStringLength(c,offset sdslen(value)) != C_OK)
            return;

setrange命令会修改原value值,如果原值是共享类型的,则需解除共享,新创建一个新robj对象,对新对象进行操作。代码实现:

代码语言:javascript复制
/* Create a copy when the object is shared or encoded. */
        o = dbUnshareStringValue(c->db,c->argv[1],o);

考虑到当value的长度加offset会大于原值长度时,需要额外分配空间用于存储新值并返回。此时调用了sdsgrowzero函数。sdsgrowzero函数会进行识别,只有当offset sdslen(value)大于原值长度时才会扩充空间,否则直接返回原字符串。

代码语言:javascript复制
o->ptr = sdsgrowzero(o->ptr,offset sdslen(value));
memcpy((char*)o->ptr offset,value,sdslen(value));

当有了robj的地址之后,从offset位置开始将value覆盖掉原值,通过memcpy函数来实现。

通过以上步骤,实现了字符串的setrange操作。

0 人点赞