Redis 源代码学习日志:string-sdsrange
最编程
2024-04-30 18:14:01
...
将 sds
中存储的字符串修改为,[start, end]
这个子串。
void sdsrange(sds s, int start, int end) {
size_t newlen, len = sdslen(s); // len: s 中存储数据的字节数
if (len == 0) return; // 如果源 sds 中没有存储数据结束函数调用
// 下面的很长一段代码都是对 start 和 end 的修正哈
if (start < 0) { // 根据这个 start 和 end 的判断来看,是支持负的 start 和 end 呢!类似于负的下标吧
start = len+start;
if (start < 0) start = 0;
}
if (end < 0) {
end = len+end;
if (end < 0) end = 0;
}
// 子串的长度,要求 start <= end
newlen = (start > end) ? 0 : (end-start)+1;
// 修正 newlen
if (newlen != 0) {
if (start >= (signed)len) {
newlen = 0;
} else if (end >= (signed)len) {
end = len-1;
newlen = (start > end) ? 0 : (end-start)+1;
}
} else {
start = 0;
}
// 只有当 start != 0 并且 newlen != 0 的时候才需要挪动数据
// 可以使用 memcpy 吗?这个问题不好说哈,因为在发现 memcpy 的问题之后,memcpy 的底层实现应该就是修改成了 memmove 了吧!
if (start && newlen) memmove(s, s+start, newlen);
s[newlen] = 0; // 在字符串的末尾提那集 '\0'
// 修改 sds 的 len 属性
sdssetlen(s,newlen);
}