<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      java寶典

       

      Redis源碼入門(mén)-字符串sds,sdshdr

      sds,全稱Simple Dynamic Strings,是Redis自定義的一個(gè)字符串類型。

      typedef char *sds;
      

      看到這你肯定內(nèi)心覺(jué)得Redis在逗你,這不就是一個(gè)字符數(shù)組么,怎么就Simple Dynamic Strings了呢 !沒(méi)錯(cuò),我當(dāng)時(shí)也是這么覺(jué)得的,但是仔細(xì)閱讀源碼后發(fā)現(xiàn)sds并不是一個(gè)人在戰(zhàn)斗,它還有戰(zhàn)友sdshdr,sdshdr是個(gè)五胞胎,分別是sdshdr5,sdshdr8,sdshd16,sdshdr32,sdshd64。塊頭從小到大。

      sdshdr 全稱 Simple Dynamic Strings Header

      /* 因?yàn)樯母鷦e人不一樣(內(nèi)部結(jié)構(gòu)不一樣),老五(sdshdr5)從來(lái)不被使用 */
      struct __attribute__ ((__packed__)) sdshdr5 {
          unsigned char flags; /* 低三位表示類型, 高五位表示字符串長(zhǎng)度 */
          char buf[];
      };
      struct __attribute__ ((__packed__)) sdshdr8 {
          uint8_t len; /* 字符串長(zhǎng)度*/
          uint8_t alloc; /* 分配長(zhǎng)度 */
          unsigned char flags; /* 低三位表示類型,高五位未使用 */
          char buf[];
      };
      struct __attribute__ ((__packed__)) sdshdr16 {
          uint16_t len; /* 字符串長(zhǎng)度*/
          uint16_t alloc; /* 分配長(zhǎng)度 */
          unsigned char flags; /* 低三位表示類型,高五位未使用 */
          char buf[];
      };
      struct __attribute__ ((__packed__)) sdshdr32 {
          uint32_t len; /* 字符串長(zhǎng)度*/
          uint32_t alloc; /* 分配長(zhǎng)度 */
          unsigned char flags; /* 低三位表示類型,高五位未使用 */
          char buf[];
      };
      struct __attribute__ ((__packed__)) sdshdr64 {
          uint64_t len; /* 字符串長(zhǎng)度*/
          uint64_t alloc; /* 分配長(zhǎng)度 */
          unsigned char flags; /* 低三位表示類型,高五位未使用 */
          char buf[];
      };
      

      知識(shí)點(diǎn)!這個(gè)很關(guān)鍵!!
      __attribute__ ((__packed__))
      待會(huì)你會(huì)看到如下代碼:
      (s)-(sizeof(struct sdshdr##T))) 、s[-1]、(char*)s-sdsHdrSize(s[-1])
      這些指針之所以可以走位如此風(fēng)騷,都?xì)w功于 __attribute__ ((__packed__))

      這個(gè)命令的意思是 取消編譯階段的內(nèi)存優(yōu)化對(duì)齊功能.
      ps: 關(guān)于內(nèi)存補(bǔ)齊如果之前不知道,請(qǐng)自行百度。

      所以,該結(jié)構(gòu)在內(nèi)存中的結(jié)構(gòu)如下:

      ThirdPartyImage_140dc1f3.png

      這樣看,之前那些風(fēng)騷的走位就很明了了。

      // s減去sdshdr長(zhǎng)度 = 指向sdshdr結(jié)構(gòu)體的指針
      (s)-(sizeof(struct sdshdr##T))) 、
      // s前一個(gè)位置 = flags
      s[-1]
      // 與1相同效果
      (char*)s-sdsHdrSize(s[-1])
      

      有了上面的基礎(chǔ),看sds.c和sds.h里的代碼就已經(jīng)很容易了,我們重點(diǎn)看兩個(gè)函數(shù)

      1. 創(chuàng)建sds字符串
      sds sdsnewlen(const void *init, size_t initlen) {
          void *sh;
          sds s;
          /* 根據(jù)字符串的長(zhǎng)度來(lái)決定sds的類型 */
          char type = sdsReqType(initlen);
          /* 老五被歧視了 */
          if (type == SDS_TYPE_5 && initlen == 0) type = SDS_TYPE_8;
          /* 計(jì)算sdsHeader的長(zhǎng)度 */
          int hdrlen = sdsHdrSize(type);
          /* 對(duì)應(yīng)flags */
          unsigned char *fp; 
      
          /* 開(kāi)辟內(nèi)存空間,+1是為了最后放一個(gè)\0,兼容傳統(tǒng)C語(yǔ)言,入鄉(xiāng)隨俗 */
          sh = s_malloc(hdrlen+initlen+1);
          if (!init)
              memset(sh, 0, hdrlen+initlen+1);
          if (sh == NULL) return NULL;
          /* 這走位,指向字符串開(kāi)始的地方 */
          s = (char*)sh+hdrlen;
          /* 這走位,到flags了 */
          fp = ((unsigned char*)s)-1;
      
          /* 根據(jù)不同的類型,初始化sdsHeader */
          switch(type) {
              case SDS_TYPE_5: {
                  *fp = type | (initlen << SDS_TYPE_BITS);
                  break;
              }
              case SDS_TYPE_8: {
                  SDS_HDR_VAR(8,s);
                  sh->len = initlen;
                  sh->alloc = initlen;
                  *fp = type;
                  break;
              }
              case SDS_TYPE_16: {
                  SDS_HDR_VAR(16,s);
                  sh->len = initlen;
                  sh->alloc = initlen;
                  *fp = type;
                  break;
              }
              case SDS_TYPE_32: {
                  SDS_HDR_VAR(32,s);
                  sh->len = initlen;
                  sh->alloc = initlen;
                  *fp = type;
                  break;
              }
              case SDS_TYPE_64: {
                  SDS_HDR_VAR(64,s);
                  sh->len = initlen;
                  sh->alloc = initlen;
                  *fp = type;
                  break;
              }
          }
          /* 字符串賦值 */
          if (initlen && init)
              memcpy(s, init, initlen);
          s[initlen] = '\0';
          return s;
      }
      
      1. 動(dòng)態(tài)擴(kuò)展sds空間
      sds sdsMakeRoomFor(sds s, size_t addlen) {
          void *sh, *newsh;
          /* avail = alloc-len */
          size_t avail = sdsavail(s);
          size_t len, newlen;
          char type, oldtype = s[-1] & SDS_TYPE_MASK;
          int hdrlen;
      
          /* 若剩下的空間足夠,就不需要擴(kuò)了 */
          if (avail >= addlen) return s;
      
          len = sdslen(s);
          sh = (char*)s-sdsHdrSize(oldtype);
          newlen = (len+addlen);
          /* Redis認(rèn)為一旦被擴(kuò)容了,
           * 那這個(gè)字符串被再次擴(kuò)容的幾率就很大,所以會(huì)在此基礎(chǔ)上多加一些空間,
           * 防止頻繁擴(kuò)容 
           */
          if (newlen < SDS_MAX_PREALLOC)
              newlen *= 2;
          else
              newlen += SDS_MAX_PREALLOC;
          /* 重新計(jì)算type */
          type = sdsReqType(newlen);
      
          /* 老五又被歧視了 */
          if (type == SDS_TYPE_5) type = SDS_TYPE_8;
      
          hdrlen = sdsHdrSize(type);
          if (oldtype==type) {
              /* 當(dāng)原類型與新類型一致,則在原有基礎(chǔ)是realloc空間即可 */
              newsh = s_realloc(sh, hdrlen+newlen+1);
              if (newsh == NULL) return NULL;
              s = (char*)newsh+hdrlen;
          } else {
              /* 否則需要重新malloc一整塊空間,然后拷貝 */
              newsh = s_malloc(hdrlen+newlen+1);
              if (newsh == NULL) return NULL;
              memcpy((char*)newsh+hdrlen, s, len+1);
              s_free(sh);
              s = (char*)newsh+hdrlen;
              s[-1] = type;
              sdssetlen(s, len);
          }
          sdssetalloc(s, newlen);
          return s;
      }
      

      關(guān)注公眾號(hào):java寶典
      a

      posted on 2021-02-24 09:25  java寶典  閱讀(792)  評(píng)論(0)    收藏  舉報(bào)

      導(dǎo)航

      主站蜘蛛池模板: 无码熟妇人妻av在线电影| 两个人看的www免费视频中文| 亚洲一区二区三区在线观看精品中文| 亚洲激情国产一区二区三区| 亚洲精品中文字幕在线观| 少妇特黄a一区二区三区| 97人人添人人澡人人澡人人澡| 日本丰满人妻xxxxxhd| 粉嫩蜜臀av一区二区绯色| 女人色熟女乱| 中文国产成人精品久久不卡| 老司机性色福利精品视频| 久章草在线毛片视频播放| 欧美日韩国产图片区一区| 日日躁夜夜躁狠狠躁超碰97| 日韩在线视频一区二区三区| 精品超清无码视频在线观看| 女人与牲口性恔配视频免费| 国产精品自在自线视频| 久久天天躁夜夜躁狠狠综合| 国语自产少妇精品视频蜜桃| 少妇人妻真实偷人精品| 欧美人与动牲猛交A欧美精品 | 99福利一区二区视频| 狠狠色婷婷久久综合频道日韩| 日本高清在线观看WWW色| 久久国产精品色av免费看| 久久精品色一情一乱一伦| 天天操夜夜操| 一区二区福利在线视频| 中文字幕乱妇无码av在线| 男人狂桶女人出白浆免费视频| 精品国产乱码一区二区三区| 亚洲国产中文在线有精品| 午夜av福利一区二区三区| 国产福利姬喷水福利在线观看| 成人精品视频一区二区三区| 国产精品蜜臀av在线一区| 欧美黑人大战白嫩在线| 欧洲中文字幕国产精品| 熟女激情乱亚洲国产一区|