【Redis源码】setrange命令

66e60b76b1c028eb77ffbdb9c2773321.jpg

简介

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

命令格式:

setrange key offset value

setrange 命令

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

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

if (checkStringLength(c,offset+sdslen(value)) != C_OK)
            return;

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

/* 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)大于原值长度时才会扩充空间,否则直接返回原字符串。

o->ptr = sdsgrowzero(o->ptr,offset+sdslen(value));
memcpy((char*)o->ptr+offset,value,sdslen(value));

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

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


标 题:《【Redis源码】setrange命令
作 者:zeekling
提 示:转载请注明文章转载自个人博客:小令童鞋

评论

取消