Today's learning efficiency is relatively high. After analyzing Rio, I learned the RedisObject file, which is about converting and creating RedisObject. Most of the methods are very similar. List the long API list: * ------------ API --------------------- * robj * createObject (intty
Today's learning efficiency is relatively high. After analyzing Rio, I learned the RedisObject file, which is about converting and creating RedisObject. Most of the methods are very similar. List the long API list:/* ------------ API --------------------- */robj * createObject (int ty
Today's learning efficiency is relatively high. After analyzing Rio, I learned the RedisObject file, which is about converting and creating RedisObject. Most of the methods are very similar. List the long API list:
/* ------------ API ------------------- */robj * createObject (int type, void * ptr)/* method for creating a robj object, the subsequent creation method is similar to */robj * createStringObject (char * ptr, size_t len) robj * createStringObjectFromLongLong (long value) robj * createStringObjectFromLongDouble (long double value) robj * Forward (robj * o) robj * createListObject (void) robj * createZiplistObject (void) robj * createSetObject (void) robj * createIntsetObject (void) robj * createHashObject (void) robj * createZsetObject (void) robj * createZsetZiplistObject (void) void freeStringObject (robj * o)/* free Obj specific object, here, free is r-> ptr */void freeListObject (robj * o) void freeSetObject (robj * o) void freeZsetObject (robj * o) void freeHashObject (robj * o) /* hashObject can be released in two forms: one is an o-ptr dictionary object, and the other is a compressed table o-> ptr */void incrRefCount (robj * o) /* increase or decrease the reference count of the robj object, and increase the refcount value in robj */void decrRefCount (robj * o)/* decrease the reference count in robj. After 0 is referenced, release object */void decrRefCountVoid (void * o) robj * resetRefCount (robj * obj) int checkType (redisClient * c, robj * o, int type) /* check whether the robj Type is of the given Type */int isObjectRepresentableAsLongLong (robj * o, long * llval) robj * tryObjectEncoding (robj * o) /* encode the arn object in a robj, mainly to save space */robj * getDecodedObject (robj * o) /* Get the decoded robj */int compareStringObjectsWithFlags (robj * a, robj * B, int flags) int compareStringObjects (robj * a, robj * B) int collateStringObjects (robj * a, robj * B) int struct stringobjects (robj * a, robj * B) size_t stringObjectLen (robj * o) int getDoubleFromObject (robj * o, double * target) /* obtain the double value from robj */int getDoubleFromObjectOrReply (redisClient * c, robj * o, double * target, const char * msg) int getLongDoubleFromObject (robj * o, long double * target) int getLongDoubleFromObjectOrReply (redisClient * c, robj * o, long double * target, const char * msg) int getLongLongFromObject (robj * o, long * target) int getLongLongFromObjectOrReply (redisClient * c, robj * o, long * target, const char * msg) int getLongFromObjectOrReply (redisClient * c, robj * o, long * target, const char * msg) char * strEncoding (int encoding) unsigned long estimateObjectIdleTime (robj * o) robj * objectCommandLookup (redisClient * c, robj * key)/* obj SEARCH command, */robj * objectCommandLookupOrReply (redisClient * c, robj * key, robj * reply) void objectCommand (redisClient * c)
From the past, we can see that the first object to be created is obj:
/* Method for creating a robj object */robj * createObject (int type, void * ptr) {robj * o = zmalloc (sizeof (* o )); o-> type = type; o-> encoding = REDIS_ENCODING_RAW; o-> ptr = ptr; o-> refcount = 1; /* Set the LRU to the current lruclock (minutes resolution ). */o-> lru = server. lruclock; return o ;}
A free method is bound to be released after creation:
/* Specific object in free Obj */void freeStringObject (robj * o) {if (o-> encoding = REDIS_ENCODING_RAW) {sdsfree (o-> ptr );}}
The free method has many derivative methods, depending on which type of space you want to release, you can, set, dict, ziplist, and so on. There are the following types:
switch(o->type) { case REDIS_STRING: freeStringObject(o); break; case REDIS_LIST: freeListObject(o); break; case REDIS_SET: freeSetObject(o); break; case REDIS_ZSET: freeZsetObject(o); break; case REDIS_HASH: freeHashObject(o); break; default: redisPanic("Unknown object type"); break; }
This section focuses on the reference counting method, which is controlled by the robj-> refcount value:
/* Increase or decrease the reference count of the robj object, increasing the value of refcount in robj */void incrRefCount (robj * o) {// increasing the value of refcount in robj o-> refcount ++ ;}
Adding a reference count is just a line of code, but if it is decreasing, we can guess that when the reference count is changed to 0, it indicates that no one uses it and space can be released;
/* Decrease the reference count in robj. After referencing 0, release the object */void decrRefCount (robj * o) {// if the previous reference count is already <= 0, it indicates that an exception occurs. if (o-> refcount <= 0) redisPanic ("decrRefCount against refcount <= 0"); if (o-> refcount = 1) {// if the previous reference count is 1, it will be decreased once again, and the object is referenced by any object, so the switch (o-> type) of the object can be released) {case REDIS_STRING: freeStringObject (o); break; case REDIS_LIST: freeListObject (o); break; case REDIS_SET: freeSetObject (o); break; case REDIS_ZSET: freeZsetObject (o ); break; case REDIS_HASH: freeHashObject (o); break; default: redisPanic ("Unknown object type"); break;} zfree (o );} else {// for other cases where the reference count of> 1 is used, you only need to count the reference count in descending order of the regular order. o-> refcount --;}}
The standard reference counting method controls memory management. (Note that the root search method is used for object lifecycle management in JVM, rather than reference counting ), the implementation of the encoding method in robj is also defined in this file:
/* Try to encode a string object in order to save space * // * encode the number of character objects in a robj, mainly to save space */robj * tryObjectEncoding (robj * o) {long value; sds s = o-> ptr; size_t len; if (o-> encoding! = REDIS_ENCODING_RAW) // If robj is encoded, return o directly;/* Already encoded * // * It's not safe to encode shared objects: shared objects can be shared * everywhere in the "object space" of Redis. encoded objects can only * appear as "values" (and not, for instance, as keys) * // * if the reference count of robj exceeds 1, it is unsafe to encode obj, because the object is shared */if (o-> refcount> 1) return o;/* Currently we try to encode only strings */r EdisAssertWithInfo (NULL, o, o-> type = REDIS_STRING);/* Check if we can represent this string as a long integer */len = sdslen (s ); if (len> 21 |! String2l (s, len, & value) {/* We can't encode the object... ** Do the last try, and at least optimize the SDS string inside * the string object to require little space, in case there * is more than 10% of free space at the end of the SDS string. ** We do that for larger strings, using the arbitrary value * of 32 bytes. this code was backported from the unstable branch * where this is already med when the object is too large to be * encoded as EMBSTR. */if (len> 32 & o-> encoding = REDIS_ENCODING_RAW & sdsavail (s)> len/10) {// call sdsRemoveFreeSpace to remove the spaces in the string 0-> ptr from o-> ptr = sdsRemoveFreeSpace (o-> ptr);}/* Return the original object. */return o ;}.....
Removes the space occupied by spaces in a string. GetDecodeObject (),:
/* Get a decoded version of an encoded object (returned as a new object ). * If the object is already raw-encoded just increment the ref count. * // * Get the decoded robj */robj * getDecodedObject (robj * o) {robj * dec; if (o-> encoding = REDIS_ENCODING_RAW) {// if no encoding method is available, the reference count is directly increased and incrRefCount (o); return o;} is returned ;} if (o-> type = REDIS_STRING & o-> encoding = REDIS_ENCODING_INT) {char buf [32]; // if it is string, Type and encoding_int, first, convert ll2string (buf, 32, (long) o-> ptr); dec = createStringObject (buf, strlen (buf); return dec ;} else {redisPanic ("Unknown encoding type ");}}
The above is a simple analysis of RedisObject.