[redis] sds
源码位置
这里使用了Arrays of Length Zero技巧,以下是一个例子,更详细的用法见reference.
struct line {
int length;
char contents[0];
};
struct line *thisline = (struct line *)
malloc (sizeof (struct line) + this_length);
thisline->length = this_length;
在redis中,sds*指向的是第一个char开始的位置,且不开启字节对齐,在此之前是sds的控制块。
typedef char *sds;
/* Note: sdshdr5 is never used, we just access the flags byte directly.
* However is here to document the layout of type 5 SDS strings. */
struct __attribute__ ((__packed__)) sdshdr5 {
unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {
uint8_t len; /* used */
uint8_t alloc; /* excluding the header and null terminator */
unsigned char flags; /* 3 lsb of type, 5 unused bits */
char buf[];
};
struct __attribute__ ((__packed__)) sdshdr16 {
uint16_t len; /* used */
uint16_t alloc; /* excluding the header and null terminator */
unsigned char flags; /* 3 lsb of type, 5 unused bits */
char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {
uint32_t len; /* used */
uint32_t alloc; /* excluding the header and null terminator */
unsigned char flags; /* 3 lsb of type, 5 unused bits */
char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {
uint64_t len; /* used */
uint64_t alloc; /* excluding the header and null terminator */
unsigned char flags; /* 3 lsb of type, 5 unused bits */
char buf[];
};
int size = sizeof(struct sdshdr64);
这里的sdshdrXX是为了应对存储各种长度字符串而定义的类型,运行时该类型存储在结构体的unsigned char flags的低3位中。
一个"奇怪的"的用法
下标为-1的写法
static inline size_t sdslen(const sds s) {
unsigned char flags = s[-1];
// ...
}
一些api
len:当前已经使用的长度,alloc表示可使用长度
- sdslen: 结构体中的len字段
- sdsavail: 可用空间 alloc - len
- sdssetlen: 设置len字段
- sdsinclen: 对len字段增加inc
- sdsalloc: 获取alloc值
- adssetalloc
- sds sdsnewlen(const void *init, size_t initlen):传入const char *和长度,创建sds对象
- sdscatlen: string cat
调试redis
launch.json
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "redis",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/src/redis-server",
"args": [
"redis.conf"
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"preLaunchTask": "build",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}
task.json
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "make",
"args": [
"CFLAGS=\"-g -O0\""
]
}
]
}
reference
- 面试杀手锏:Redis源码之SDS
- Arrays of Length Zero
- [规定数组下标为 -1 ](C++ 是否有某个标准,规定数组下标为 -1 时输出什么? - pansz的回答 - 知乎
https://www.zhihu.com/question/34790951/answer/59854614)