robj *createStringObject(char *ptr, size_t len) { /* 这两种方式的区别是字节数少的时候,直接一次性分配zmalloc(sizeof(robj)+sizeof(struct sdshdr)+len+1) 如果大于39则分别分配sizeof(robj)和sizeof(struct sdshdr)+len空间 */ if (len <= REDIS_ENCODING_EMBSTR_SIZE_LIMIT) return createEmbeddedStringObject(ptr,len); else return createRawStringObject(ptr,len); }
/* Prepare the string object stored at 'key' to be modified destructively * to implement commands like SETBIT or APPEND. * * An object is usually ready to be modified unless one of the two conditions * are true: * * 1) The object 'o' is shared (refcount > 1), we don't want to affect * other users. * 2) The object encoding is not "RAW". * * If the object is found in one of the above conditions (or both) by the * function, an unshared / not-encoded copy of the string object is stored * at 'key' in the specified 'db'. Otherwise the object 'o' itself is * returned. * * USAGE: * * The object 'o' is what the caller already obtained by looking up 'key' * in 'db', the usage pattern looks like this: * * o = lookupKeyWrite(db,key); * if (checkType(c,o,OBJ_STRING)) return; * o = dbUnshareStringValue(db,key,o); * * At this point the caller is ready to modify the object, for example * using an sdscat() call to append some data, or anything else. */ robj *dbUnshareStringValue(redisDb *db, robj *key, robj *o) { serverAssert(o->type == OBJ_STRING); if (o->refcount != 1 || o->encoding != OBJ_ENCODING_RAW) { robj *decoded = getDecodedObject(o); o = createRawStringObject(decoded->ptr, sdslen(decoded->ptr)); decrRefCount(decoded); dbOverwrite(db,key,o); } return o; }
/* Duplicate a string object, with the guarantee that the returned object * has the same encoding as the original one. * * This function also guarantees that duplicating a small integere object * (or a string object that contains a representation of a small integer) * will always result in a fresh object that is unshared (refcount == 1). * * The resulting object always has refcount set to 1. */ robj *dupStringObject(robj *o) { robj *d; serverAssert(o->type == OBJ_STRING); switch(o->encoding) { case OBJ_ENCODING_RAW: return createRawStringObject(o->ptr,sdslen(o->ptr)); case OBJ_ENCODING_EMBSTR: return createEmbeddedStringObject(o->ptr,sdslen(o->ptr)); case OBJ_ENCODING_INT: d = createObject(OBJ_STRING, NULL); d->encoding = OBJ_ENCODING_INT; d->ptr = o->ptr; return d; default: serverPanic("Wrong encoding."); break; } }
//返回 复制的o对象的副本的地址,且创建的对象非共享 robj *dupStringObject(robj *o) { robj *d; serverAssert(o->type == OBJ_STRING); //一定是OBJ_STRING类型 switch(o->encoding) { //根据不同的编码类型 case OBJ_ENCODING_RAW: return createRawStringObject(o->ptr,sdslen(o->ptr)); //创建的对象非共享 case OBJ_ENCODING_EMBSTR: return createEmbeddedStringObject(o->ptr,sdslen(o->ptr)); //创建的对象非共享 case OBJ_ENCODING_INT: //整数编码类型 d = createObject(OBJ_STRING, NULL); //即使是共享整数范围内的整数,创建的对象也是非共享的 d->encoding = OBJ_ENCODING_INT; d->ptr = o->ptr; return d; default: serverPanic("Wrong encoding."); break; } }
/* Duplicate a string object, with the guarantee that the returned object * has the same encoding as the original one. * * This function also guarantees that duplicating a small integere object * (or a string object that contains a representation of a small integer) * will always result in a fresh object that is unshared (refcount == 1). * * The resulting object always has refcount set to 1. */ robj *dupStringObject(robj *o) { robj *d; assert(o->type == OBJ_STRING); switch(o->encoding) { case OBJ_ENCODING_RAW: return createRawStringObject(o->ptr,sdslen(o->ptr)); case OBJ_ENCODING_EMBSTR: return createEmbeddedStringObject(o->ptr,sdslen(o->ptr)); case OBJ_ENCODING_INT: d = createObject(OBJ_STRING, NULL); d->encoding = OBJ_ENCODING_INT; d->ptr = o->ptr; return d; default: rr_log(RR_LOG_ERROR, "Wrong encoding"); return NULL; break; } }
robj *createStringObject(const char *ptr, size_t len) { if (len <= OBJ_ENCODING_EMBSTR_SIZE_LIMIT) return createEmbeddedStringObject(ptr,len); else return createRawStringObject(ptr,len); }