字符串对象
字符串对象的编码可以是:int
,raw
,embstr
#define REDIS_STRING 0
#define REDIS_ENCODING_INT 1
#define REDIS_ENCODING_RAW 0
#define REDIS_ENCODING_EMBSTR 8
int
如果以字符串对象保存的是一个整数值,且这个整数值可以用long类型来表示,那么字符串对象会将整数值保存在ptr属性里面(void* 转为long*),并将字符串对象的编码设置为REDIS_ENCODING_INT
。
![](https://img.haomeiwen.com/i7304940/ba931817048280cb.png)
// 只对长度小于或等于 21 字节,并且可以被解释为整数的字符串进行编码
if (len <= 21 && string2l(s,len,&value)) {
if (server.maxmemory == 0 && value >= 0 && value < REDIS_SHARED_INTEGERS) {
decrRefCount(o);
incrRefCount(shared.integers[value]);
return shared.integers[value]; // 这里value < REDIS_SHARED_INTEGERS,直接使用共享的字符串对象。
} else {
if (o->encoding == REDIS_ENCODING_RAW)
sdsfree(o->ptr);
o->encoding = REDIS_ENCODING_INT;
o->ptr = (void*)value;
return o;
}
}
embstr
如果字符串对象保存的是一个字符串值,并且这个字符串值长度小于等于39字节。
![](https://img.haomeiwen.com/i7304940/f9790014d893bdc2.png)
- 减少内存分配次数
- 减少内存释放次数
- 缓存友好
// 尝试将 RAW 编码的字符串编码为 EMBSTR 编码
if (len <= REDIS_ENCODING_EMBSTR_SIZE_LIMIT) {
robj *emb;
if (o->encoding == REDIS_ENCODING_EMBSTR)
return o;
emb = createEmbeddedStringObject(s,sdslen(s));
decrRefCount(o);
return emb;
}
raw
如果字符串对象保存的是一个字符串值,并且这个字符串值长度大于39字节。
![](https://img.haomeiwen.com/i7304940/5b3a1bbfa0d1400e.png)
总结起来,就是:
![](https://img.haomeiwen.com/i7304940/3ac504cc2c8ad52e.png)
#0 tryObjectEncoding (o=0x5555556eb058) at object.c:554
#1 0x0000555555595f3b in setCommand (c=0x5555556ebe68) at t_string.c:178
#2 0x0000555555577911 in call (c=0x5555556ebe68, flags=7) at redis.c:2441
#3 0x000055555557842d in processCommand (c=0x5555556ebe68) at redis.c:2766
#4 0x00005555555868c7 in processInputBuffer (c=0x5555556ebe68) at networking.c:1539
#5 0x0000555555586bb5 in readQueryFromClient (el=0x5555556a6248, fd=6, privdata=0x5555556ebe68,
mask=1) at networking.c:1631
#6 0x000055555557059a in aeProcessEvents (eventLoop=0x5555556a6248, flags=3) at ae.c:576
#7 0x000055555557075b in aeMain (eventLoop=0x5555556a6248) at ae.c:635
#8 0x000055555557b6c0 in main (argc=1, argv=0x7fffffffe3f8) at redis.c:4079
网友评论