object.c
object.c文件主要记录了Redis对象的创建和释放方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20robj *createEmbeddedStringObject(char *ptr, size_t len) {
robj *o = zmalloc(sizeof(robj)+sizeof(struct sdshdr)+len+1);
struct sdshdr *sh = (void*)(o+1);
o->type = REDIS_STRING;
o->encoding = REDIS_ENCODING_EMBSTR;
o->ptr = sh+1;
o->refcount = 1;
o->lru = LRU_CLOCK();
sh->len = len;
sh->free = 0;
if (ptr) {
memcpy(sh->buf,ptr,len);
sh->buf[len] = '\0';
} else {
memset(sh->buf,0,len+1);
}
return o;
}
从这个函数中,我们可以看出Redis在创建一个REDIS_ENCODING_EMBSTR编码的字符串对象时,是SDS连同redisObject一同创建的。也就是说这个字符串是不可以修改的。
1 | robj *createStringObjectFromLongLong(long long value) { |
这个函数是根据传入的整数值来创建一个字符串对象。从这里可以看到主要有三个判断:
- 如果设置的值符合Redis共享整数对象的范围时,是直接复用共享对象,并不会去创建一个新的对象。
- 如果传入的值是long类型的,这创建一个REDIS_ENCODING_INT编码类型的字符串对象。
- 如果传入的值为long long类型的,则创建REDIS_ENCODING_RAW编码类型的字符串对象。
debug命令1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26/* Object command allows to inspect the internals of an Redis Object.
* Usage: OBJECT <verb> ... arguments ... */
void objectCommand(redisClient *c) {
robj *o;
// 返回对戏哪个的引用计数
if (!strcasecmp(c->argv[1]->ptr,"refcount") && c->argc == 3) {
if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.nullbulk))
== NULL) return;
addReplyLongLong(c,o->refcount);
// 返回对象的编码
} else if (!strcasecmp(c->argv[1]->ptr,"encoding") && c->argc == 3) {
if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.nullbulk))
== NULL) return;
addReplyBulkCString(c,strEncoding(o->encoding));
// 返回对象的空闲时间
} else if (!strcasecmp(c->argv[1]->ptr,"idletime") && c->argc == 3) {
if ((o = objectCommandLookupOrReply(c,c->argv[2],shared.nullbulk))
== NULL) return;
addReplyLongLong(c,estimateObjectIdleTime(o)/1000);
} else {
addReplyError(c,"Syntax error. Try OBJECT (refcount|encoding|idletime)");
}
}