<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ? ? ? ? 今天的學習效率比較高,把Rio分析完了,又順便學習了其中的RedisObject的文件,只要講的就是RedisObject的一些轉換和創建。里面的大多數方法都是非常類似的。列出里面長長的API列表: ~~~ /* ------------ API --------------------- */ robj *createObject(int type, void *ptr) /* 最初的創建robj對象方法,后面的創建方法與此類似 */ robj *createStringObject(char *ptr, size_t len) robj *createStringObjectFromLongLong(long long value) robj *createStringObjectFromLongDouble(long double value) robj *dupStringObject(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中的特定對象,這里free的是r->ptr */ void freeListObject(robj *o) void freeSetObject(robj *o) void freeZsetObject(robj *o) void freeHashObject(robj *o) /* 釋放hashObject有2種形式,1個是o-ptr的字典對象,還有1個回事壓縮表o->ptr */ void incrRefCount(robj *o) /* robj對象增減引用計數,遞增robj中的refcount的值 */ void decrRefCount(robj *o) /* 遞減robj中的引用計數,引用到0后,釋放對象 */ void decrRefCountVoid(void *o) robj *resetRefCount(robj *obj) int checkType(redisClient *c, robj *o, int type) /* 檢查robj的類型是否為給定的Type類型 */ int isObjectRepresentableAsLongLong(robj *o, long long *llval) robj *tryObjectEncoding(robj *o) /* 編碼一個robj中的額字符對象,主要是為了省空間 */ robj *getDecodedObject(robj *o) /* 獲取解碼后的robj */ int compareStringObjectsWithFlags(robj *a, robj *b, int flags) int compareStringObjects(robj *a, robj *b) int collateStringObjects(robj *a, robj *b) int equalStringObjects(robj *a, robj *b) size_t stringObjectLen(robj *o) int getDoubleFromObject(robj *o, double *target) /* 從robj中獲取double數值 */ 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 long *target) int getLongLongFromObjectOrReply(redisClient *c, robj *o, long 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的查找命令, */ robj *objectCommandLookupOrReply(redisClient *c, robj *key, robj *reply) void objectCommand(redisClient *c) ~~~ 從前往后看,第一個創建obj: ~~~ /* 最初的創建robj對象方法 */ 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; } ~~~ 有創建就必然會有釋放的free方法: ~~~ /* free Obj中的特定對象 */ void freeStringObject(robj *o) { if (o->encoding == REDIS_ENCODING_RAW) { sdsfree(o->ptr); } } ~~~ free方法有很多衍生的方法,看你要釋放哪種類型的空間了,可以,set,dict,ziplist等等。有下面的一些類型: ~~~ 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; } ~~~ 重點介紹里面的關于引用計數的相關方法,通過robj->refcount的數值進行控制的: ~~~ /* robj對象增減引用計數,遞增robj中的refcount的值 */ void incrRefCount(robj *o) { //遞增robj中的refcount的值 o->refcount++; } ~~~ 增加引用計數就一行代碼,但是遞減的話,我們猜也可以猜到,引用計數變為0的時候,說明無人使用了,就可以釋放空間了; ~~~ /* 遞減robj中的引用計數,引用到0后,釋放對象 */ void decrRefCount(robj *o) { //如果之前的引用計數已經<=0了,說明出現異常情況了 if (o->refcount <= 0) redisPanic("decrRefCount against refcount <= 0"); if (o->refcount == 1) { //如果之前的引用計數為1,再遞減一次,恰好內有被任何對象引用了,所以就可以釋放對象了 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; } zfree(o); } else { //其他對于>1的引用計數的情況,只需要按常規的遞減引用計數即可 o->refcount--; } } ~~~ 標準的引用計數法控制內存的管理,(提醒一下,在JVM中的對象的生命周期管理用的是根搜索法,不是引用計數),還有一個在robj中的編碼方法的實現也是定義在這個文件中: ~~~ /* Try to encode a string object in order to save space */ /* 編碼一個robj中的額字符對象,主要是為了省空間 */ robj *tryObjectEncoding(robj *o) { long value; sds s = o->ptr; size_t len; if (o->encoding != REDIS_ENCODING_RAW) //如果robj已經被編碼了,則直接返回 return o; /* 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) */ /* 如果robj的引用計數超過1個人引用的時候,是不安全的去編碼obj,因為對象是共享的 */ if (o->refcount > 1) return o; /* Currently we try to encode only strings */ redisAssertWithInfo(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 performed when the object is too large to be * encoded as EMBSTR. */ if (len > 32 && o->encoding == REDIS_ENCODING_RAW && sdsavail(s) > len/10) { //調用sdsRemoveFreeSpace把0->ptr中的字符串中的空格給移除掉 o->ptr = sdsRemoveFreeSpace(o->ptr); } /* Return the original object. */ return o; } ..... ~~~ 就是移除字符串中的空格所占的空間。想對應也存在一個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. */ /* 獲取解碼后的robj */ robj *getDecodedObject(robj *o) { robj *dec; if (o->encoding == REDIS_ENCODING_RAW) { //如果沒有編碼方式,則直接增加引用計數,并返回 incrRefCount(o); return o; } if (o->type == REDIS_STRING && o->encoding == REDIS_ENCODING_INT) { char buf[32]; //如果是string,Type而且是encoding_int方式的,先做一步轉換 ll2string(buf,32,(long)o->ptr); dec = createStringObject(buf,strlen(buf)); return dec; } else { redisPanic("Unknown encoding type"); } } ~~~ 以上就是對于對于RedisObject的簡單分析。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看