自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Redis內(nèi)部數(shù)據(jù)結(jié)構(gòu)SDS詳解

存儲(chǔ) 存儲(chǔ)軟件 Redis
Redis是使用C寫(xiě)的,而C中根本不存在string,list,hash,set和zset這些數(shù)據(jù)類(lèi)型,那么C是如何將這些數(shù)據(jù)類(lèi)型實(shí)現(xiàn)出來(lái)的呢?我們從該篇開(kāi)始,就要開(kāi)始分析源碼啦??。

本文轉(zhuǎn)載自微信公眾號(hào)「 學(xué)習(xí)Java的小姐姐」,作者學(xué)習(xí)Java的小姐姐0618。轉(zhuǎn)載本文請(qǐng)聯(lián)系學(xué)習(xí)Java的小姐姐公眾號(hào)。

[[331487]]

前言

Redis是使用C寫(xiě)的,而C中根本不存在string,list,hash,set和zset這些數(shù)據(jù)類(lèi)型,那么C是如何將這些數(shù)據(jù)類(lèi)型實(shí)現(xiàn)出來(lái)的呢?我們從該篇開(kāi)始,就要開(kāi)始分析源碼啦??。

API使用

我們這篇來(lái)學(xué)習(xí)string的底層實(shí)現(xiàn),首先看下API的簡(jiǎn)單應(yīng)用,設(shè)置str1變量為helloworld,然后我們使用debug object +變量名的方式看下,注意標(biāo)紅的編碼為embstr。

如果我們將str2設(shè)置為helloworldhelloworldhelloworldhelloworldhell,字符長(zhǎng)度為44,再使用下debug object+變量名的方式看下,注意標(biāo)紅的編碼為embstr。

但是當(dāng)我們?cè)O(shè)置為helloworldhelloworldhelloworldhelloworldhello,字符長(zhǎng)度為45,再使用debug object+變量名的方式看下,注意標(biāo)紅的編碼為raw。

最后我們將str3設(shè)置為整數(shù)100,再使用debug object+變量名的方式看下,注意標(biāo)紅的編碼為int。

所以Redis的string類(lèi)型一共有三種存儲(chǔ)方式,當(dāng)字符串長(zhǎng)度小于等于44,底層采用embstr;當(dāng)字符串長(zhǎng)度大于44,底層采用raw;當(dāng)設(shè)置是整數(shù),底層則采用int。

embstr和raw的區(qū)別

所有類(lèi)型的數(shù)據(jù)結(jié)構(gòu)最外層都是RedisObject,這部分會(huì)說(shuō),先這樣大致了解下,因?yàn)檫@篇的重點(diǎn)不在這。如果字符串小于等于44,實(shí)際的數(shù)據(jù)和RedisObject在內(nèi)存中地址相鄰,如下圖。

如果字符串大于44,實(shí)際的數(shù)據(jù)和RedisObject在內(nèi)存中地址不相鄰,如下圖。

再次強(qiáng)調(diào),這些不重要,以后會(huì)講,現(xiàn)在提下,只是為了能讓Redis的String類(lèi)型有個(gè)大致了解,先從整體把握。我們今天要說(shuō)的其實(shí)是實(shí)際的數(shù)據(jù),即上圖指針指向的位置??。

SDSHdr的定義

其實(shí)的數(shù)據(jù)并不是直接存儲(chǔ),也有封裝,看下面的代碼就知道分為五種,分別是sdshdr5,sdshdr8,sdshdr16,sdshdr32,sdshdr64。sdshdr5和另外四種的區(qū)別比較明顯,sdshrd5其實(shí)對(duì)內(nèi)存空間的更加節(jié)約。其他四種乍一看都差不多,包括已用長(zhǎng)度len,總長(zhǎng)度alloc,標(biāo)記flags(感覺(jué)沒(méi)啥用,要是有知道的小伙伴,歡迎指教),實(shí)際數(shù)據(jù)buf。

  1. //定義五種不同的結(jié)構(gòu)體,sdshdr5,sdshdr8, sdshdr16,sdshdr32,sdshdr64 
  2. struct __attribute__ ((__packed__)) sdshdr5 { 
  3.     unsigned char flags; // 8位的標(biāo)記 
  4.     char buf[];//實(shí)際數(shù)據(jù)的指針 
  5. }; 
  6. struct __attribute__ ((__packed__)) sdshdr8 { 
  7.     uint8_t len; /* 已使用長(zhǎng)度 */ 
  8.     uint8_t alloc; /* 總長(zhǎng)度*/ 
  9.     unsigned char flags; 
  10.     char buf[]; 
  11. }; 
  12. struct __attribute__ ((__packed__)) sdshdr16 { 
  13.     uint16_t len; 
  14.     uint16_t alloc; 
  15.     unsigned char flags; 
  16.     char buf[]; 
  17. }; 
  18. struct __attribute__ ((__packed__)) sdshdr32 { 
  19.     uint32_t len; 
  20.     uint32_t alloc; 
  21.     unsigned char flags; 
  22.     char buf[]; 
  23. }; 
  24. struct __attribute__ ((__packed__)) sdshdr64 { 
  25.     uint64_t len; 
  26.     uint64_t alloc; 
  27.     unsigned char flags; 
  28.     char buf[]; 
  29. }; 

SDS具體邏輯圖

假設(shè)我們?cè)O(shè)置某個(gè)字符串為hello,那么他SDS的可用長(zhǎng)度len為8,已用長(zhǎng)度len為6,如下圖。注意:Redis會(huì)根據(jù)具體的字符長(zhǎng)度,選擇相應(yīng)的sdshdr,但是各個(gè)類(lèi)型都差不多,所以下圖加簡(jiǎn)單畫(huà)了。

SDS的優(yōu)勢(shì)

我們可以看到是對(duì)字符數(shù)組的再封裝,但是為什么呢,直接使用字符數(shù)組不是更簡(jiǎn)單嗎?這要從C和Java語(yǔ)言的根本區(qū)別說(shuō)起。

更快速的獲取字符串長(zhǎng)度

我們都知道Java的字符串有提供length方法,列表有提供size方法,我們可以直接獲取大小。但是C卻不一樣,更偏向底層實(shí)現(xiàn),所以沒(méi)有直接的方法使用。這樣就帶來(lái)一個(gè)問(wèn)題,如果我們想要獲取某個(gè)數(shù)組的長(zhǎng)度,就只能從頭開(kāi)始遍歷,當(dāng)遇到第一個(gè)'\0'則表示該數(shù)組結(jié)束。這樣的速度太慢了,不能每次因?yàn)橐@取長(zhǎng)度就變量數(shù)組。所以設(shè)計(jì)了SDS數(shù)據(jù)結(jié)構(gòu),在原來(lái)的字符數(shù)組外面增加總長(zhǎng)度,和已用長(zhǎng)度,這樣每次直接獲取已用長(zhǎng)度即可。復(fù)雜度為O(1)。

數(shù)據(jù)安全,不會(huì)截?cái)?/strong>

如果傳統(tǒng)字符串保存圖片,視頻等二進(jìn)制文件,中間可能出現(xiàn)'\0',如果按照原來(lái)的邏輯,會(huì)造成數(shù)據(jù)丟失。所以可以用已用長(zhǎng)度來(lái)表示是否字符數(shù)組已結(jié)束。

SDS關(guān)鍵代碼分析

獲取常見(jiàn)值(抽象出常見(jiàn)方法)

在sds.h中寫(xiě)了一些常見(jiàn)方法,比如計(jì)算sds的長(zhǎng)度(即sdshdr的len),計(jì)算sds的空閑長(zhǎng)度(即sdshdr的可用長(zhǎng)度alloc-已用長(zhǎng)度len),計(jì)算sds的可用長(zhǎng)度(即sdshdr的alloc)等等。但是大家有沒(méi)有疑問(wèn),這不是一行代碼搞定的事嗎,為啥要抽象出方法呢?那么問(wèn)題在于在上面,我們有將sdshdr分為五種類(lèi)型,分別是sdshdr5,sdshdr8,sdshdr16,sdshdr32,sdshdr64。那么我們?cè)趯?shí)際使用的時(shí)候,想要區(qū)分當(dāng)前是哪個(gè)類(lèi)型,并取其相應(yīng)字段或設(shè)置相應(yīng)字段。

  1. //計(jì)算sds對(duì)應(yīng)的字符串長(zhǎng)度,其實(shí)上取得是字符串所對(duì)應(yīng)的哪種sdshdr的len值 
  2. static inline size_t sdslen(const sds s) { 
  3.     // 柔性數(shù)組不占空間,所以倒數(shù)第二位的是flags 
  4.     unsigned char flags = s[-1]; 
  5.     //flags與上面定義的宏變量7做位運(yùn)算 
  6.     switch(flags&SDS_TYPE_MASK) { 
  7.         case SDS_TYPE_5://0 
  8.             return SDS_TYPE_5_LEN(flags); 
  9.         case SDS_TYPE_8://1 
  10.             return SDS_HDR(8,s)->len;//取上面結(jié)構(gòu)體sdshdr8的len 
  11.         case SDS_TYPE_16://2 
  12.             return SDS_HDR(16,s)->len; 
  13.         case SDS_TYPE_32://3 
  14.             return SDS_HDR(32,s)->len; 
  15.         case SDS_TYPE_64://5 
  16.             return SDS_HDR(64,s)->len; 
  17.     } 
  18.     return 0; 
  19. //計(jì)算sds對(duì)應(yīng)的空余長(zhǎng)度,其實(shí)上是alloc-len 
  20. static inline size_t sdsavail(const sds s) { 
  21.     unsigned char flags = s[-1]; 
  22.     switch(flags&SDS_TYPE_MASK) { 
  23.         case SDS_TYPE_5: { 
  24.             return 0; 
  25.         } 
  26.         case SDS_TYPE_8: { 
  27.             SDS_HDR_VAR(8,s); 
  28.             return sh->alloc - sh->len; 
  29.         } 
  30.         case SDS_TYPE_16: { 
  31.             SDS_HDR_VAR(16,s); 
  32.             return sh->alloc - sh->len; 
  33.         } 
  34.         case SDS_TYPE_32: { 
  35.             SDS_HDR_VAR(32,s); 
  36.             return sh->alloc - sh->len; 
  37.         } 
  38.         case SDS_TYPE_64: { 
  39.             SDS_HDR_VAR(64,s); 
  40.             return sh->alloc - sh->len; 
  41.         } 
  42.     } 
  43.     return 0; 
  44. //設(shè)置sdshdr的len 
  45. static inline void sdssetlen(sds s, size_t newlen) { 
  46.     unsigned char flags = s[-1]; 
  47.     switch(flags&SDS_TYPE_MASK) { 
  48.         case SDS_TYPE_5: 
  49.             { 
  50.                 unsigned char *fp = ((unsigned char*)s)-1; 
  51.                 *fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS); 
  52.             } 
  53.             break; 
  54.         case SDS_TYPE_8: 
  55.             SDS_HDR(8,s)->len = newlen; 
  56.             break; 
  57.         case SDS_TYPE_16: 
  58.             SDS_HDR(16,s)->len = newlen; 
  59.             break; 
  60.         case SDS_TYPE_32: 
  61.             SDS_HDR(32,s)->len = newlen; 
  62.             break; 
  63.         case SDS_TYPE_64: 
  64.             SDS_HDR(64,s)->len = newlen; 
  65.             break; 
  66.     } 
  67. //給sdshdr的len添加多少大小 
  68. static inline void sdsinclen(sds s, size_t inc) { 
  69.     unsigned char flags = s[-1]; 
  70.     switch(flags&SDS_TYPE_MASK) { 
  71.         case SDS_TYPE_5: 
  72.             { 
  73.                 unsigned char *fp = ((unsigned char*)s)-1; 
  74.                 unsigned char newlen = SDS_TYPE_5_LEN(flags)+inc; 
  75.                 *fp = SDS_TYPE_5 | (newlen << SDS_TYPE_BITS); 
  76.             } 
  77.             break; 
  78.         case SDS_TYPE_8: 
  79.             SDS_HDR(8,s)->len += inc; 
  80.             break; 
  81.         case SDS_TYPE_16: 
  82.             SDS_HDR(16,s)->len += inc; 
  83.             break; 
  84.         case SDS_TYPE_32: 
  85.             SDS_HDR(32,s)->len += inc; 
  86.             break; 
  87.         case SDS_TYPE_64: 
  88.             SDS_HDR(64,s)->len += inc; 
  89.             break; 
  90.     } 
  91. //獲取sdshdr的總長(zhǎng)度 
  92. static inline size_t sdsalloc(const sds s) { 
  93.     unsigned char flags = s[-1]; 
  94.     switch(flags&SDS_TYPE_MASK) { 
  95.         case SDS_TYPE_5: 
  96.             return SDS_TYPE_5_LEN(flags); 
  97.         case SDS_TYPE_8: 
  98.             return SDS_HDR(8,s)->alloc; 
  99.         case SDS_TYPE_16: 
  100.             return SDS_HDR(16,s)->alloc; 
  101.         case SDS_TYPE_32: 
  102.             return SDS_HDR(32,s)->alloc; 
  103.         case SDS_TYPE_64: 
  104.             return SDS_HDR(64,s)->alloc; 
  105.     } 
  106.     return 0; 
  107. //設(shè)置sdshdr的總長(zhǎng)度 
  108. static inline void sdssetalloc(sds s, size_t newlen) { 
  109.     unsigned char flags = s[-1]; 
  110.     switch(flags&SDS_TYPE_MASK) { 
  111.         case SDS_TYPE_5: 
  112.             /* Nothing to do, this type has no total allocation info. */ 
  113.             break; 
  114.         case SDS_TYPE_8: 
  115.             SDS_HDR(8,s)->alloc = newlen; 
  116.             break; 
  117.         case SDS_TYPE_16: 
  118.             SDS_HDR(16,s)->alloc = newlen; 
  119.             break; 
  120.         case SDS_TYPE_32: 
  121.             SDS_HDR(32,s)->alloc = newlen; 
  122.             break; 
  123.         case SDS_TYPE_64: 
  124.             SDS_HDR(64,s)->alloc = newlen; 
  125.             break; 
  126.     } 

創(chuàng)建對(duì)象

我們通過(guò)sdsnew方法來(lái)創(chuàng)建對(duì)象,顯示通過(guò)判斷init是否為空來(lái)確定初始大小,接著調(diào)用方法sdsnew(這邊方法名一樣,但是參數(shù)不一樣,其為方法的重載),先根據(jù)長(zhǎng)度確定類(lèi)型(上面有提過(guò)五種類(lèi)型,不記得的可以往上翻),然后根據(jù)類(lèi)型分配相應(yīng)的內(nèi)存資源,最后追加C語(yǔ)言的結(jié)尾符'\0'。

  1. sds sdsnew(const char *init) { 
  2.     size_t initlen = (init == NULL) ? 0 : strlen(init); 
  3.     return sdsnewlen(init, initlen); 
  4.  
  5. sds sdsnewlen(const void *init, size_t initlen) { 
  6.     void *sh; 
  7.     sds s; 
  8.     char type = sdsReqType(initlen);//根據(jù)長(zhǎng)度確定類(lèi)型 
  9.     /*空字符串,用sdshdr8,這邊是經(jīng)驗(yàn)寫(xiě)法,當(dāng)想構(gòu)造空串是為了放入超過(guò)32長(zhǎng)度的字符串 */ 
  10.     if (type == SDS_TYPE_5 && initlen == 0) type = SDS_TYPE_8; 
  11.     int hdrlen = sdsHdrSize(type);//到下一個(gè)方法,已經(jīng)把他們放在一起了 
  12.     unsigned char *fp; /* flags pointer. */ 
  13.  
  14.     //分配內(nèi)存 
  15.     sh = s_malloc(hdrlen+initlen+1); 
  16.     if (!init) 
  17.         memset(sh, 0, hdrlen+initlen+1); 
  18.     if (sh == NULLreturn NULL
  19.     s = (char*)sh+hdrlen; 
  20.     fp = ((unsigned char*)s)-1; 
  21.     //根據(jù)不同的類(lèi)型,創(chuàng)建不同結(jié)構(gòu)體,調(diào)用SDS_HDR_VAR函數(shù) 
  22.     //為不同的結(jié)構(gòu)體賦值,如已用長(zhǎng)度len,總長(zhǎng)度alloc 
  23.     switch(type) { 
  24.         case SDS_TYPE_5: { 
  25.             *fp = type | (initlen << SDS_TYPE_BITS); 
  26.             break; 
  27.         } 
  28.         case SDS_TYPE_8: { 
  29.             SDS_HDR_VAR(8,s); 
  30.             sh->len = initlen; 
  31.             sh->alloc = initlen; 
  32.             *fp = type; 
  33.             break; 
  34.         } 
  35.         case SDS_TYPE_16: { 
  36.             SDS_HDR_VAR(16,s); 
  37.             sh->len = initlen; 
  38.             sh->alloc = initlen; 
  39.             *fp = type; 
  40.             break; 
  41.         } 
  42.         case SDS_TYPE_32: { 
  43.             SDS_HDR_VAR(32,s); 
  44.             sh->len = initlen; 
  45.             sh->alloc = initlen; 
  46.             *fp = type; 
  47.             break; 
  48.         } 
  49.         case SDS_TYPE_64: { 
  50.             SDS_HDR_VAR(64,s); 
  51.             sh->len = initlen; 
  52.             sh->alloc = initlen; 
  53.             *fp = type; 
  54.             break; 
  55.         } 
  56.     } 
  57.     if (initlen && init) 
  58.         memcpy(s, init, initlen); 
  59.     //最后追加'\0' 
  60.     s[initlen] = '\0'
  61.     return s; 
  62.  
  63. //根據(jù)實(shí)際字符長(zhǎng)度確定類(lèi)型 
  64. static inline char sdsReqType(size_t string_size) { 
  65.     if (string_size < 1<<5) 
  66.         return SDS_TYPE_5; 
  67.     if (string_size < 1<<8) 
  68.         return SDS_TYPE_8; 
  69.     if (string_size < 1<<16) 
  70.         return SDS_TYPE_16; 
  71. #if (LONG_MAX == LLONG_MAX) 
  72.     if (string_size < 1ll<<32) 
  73.         return SDS_TYPE_32; 
  74. #endif 
  75.     return SDS_TYPE_64; 

刪除

String類(lèi)型的刪除并不是直接回收內(nèi)存,而是修改字符,讓其為空字符,這其實(shí)是惰性釋放,等待將來(lái)使用。在調(diào)用sdsempty方法時(shí),再次調(diào)用上面的sdsnewlen方法。

  1. /*修改sds字符串使其為空(零長(zhǎng)度)。 
  2.  
  3. *但是,所有現(xiàn)有緩沖區(qū)不會(huì)被丟棄,而是設(shè)置為可用空間 
  4.  
  5. *這樣,下一個(gè)append操作將不需要分配到 
  6.  
  7. *當(dāng)要縮短SDS保存的字符串時(shí),程序并不立即使用內(nèi)存充分配來(lái)回收縮短后多出來(lái)的字節(jié),并等待將來(lái)使用。*/ 
  8. void sdsclear(sds s) { 
  9.     sdssetlen(s, 0); 
  10.     s[0] = '\0'
  11.  
  12. sds sdsempty(void) { 
  13.     return sdsnewlen("",0); 

添加字符(擴(kuò)容)重點(diǎn)!!!

添加字符串,sdscat輸入?yún)?shù)為sds和字符串t,首先調(diào)用sdsMakeRoomFor擴(kuò)容方法,再追加新的字符串,最后添加上結(jié)尾符'\0'。我們來(lái)看下擴(kuò)容方法里面是如何實(shí)現(xiàn)的?第一步先調(diào)用常見(jiàn)方法中的sdsavail方法,獲取還剩多少空閑空間。如果空閑空間大于要添加的字符串t的長(zhǎng)度,則直接返回,不想要擴(kuò)容。如果空閑空間不夠,則想要擴(kuò)容。第二步判斷想要擴(kuò)容多大,這邊有分情況,如果目前的字符串小于1M,則直接擴(kuò)容雙倍,如果目前的字符串大于1M,則直接添加1M。第三個(gè)判斷添加字符串之后的數(shù)據(jù)類(lèi)型還是否和原來(lái)的一致,如果一致,則沒(méi)啥事。如果不一致,則想要新建一個(gè)sdshdr,把現(xiàn)有的數(shù)據(jù)都挪過(guò)去。

這樣是不是有點(diǎn)抽象,舉個(gè)例子,現(xiàn)在str的字符串為hello,目前是sdshdr8,總長(zhǎng)度50,已用6,空閑44?,F(xiàn)在想要添加長(zhǎng)度為50的字符t,第一步想要看下是否要擴(kuò)容,50明顯大于44,需要擴(kuò)容。第二步擴(kuò)容多少,str的長(zhǎng)度小于1M,所以擴(kuò)容雙倍,新的長(zhǎng)度為50*2=100。第三步50+50所對(duì)應(yīng)sdshdr類(lèi)型還是sdshdr8嗎?明顯還是sdshdr8,所以不要數(shù)據(jù)遷移,還在原來(lái)的基礎(chǔ)上添加t即可。

  1. sds sdscat(sds s, const char *t) { 
  2.     return sdscatlen(s, t, strlen(t)); 
  3.  
  4. sds sdscatlen(sds s, const void *t, size_t len) { 
  5.     //調(diào)用sds.h里面的sdslen,即取已用長(zhǎng)度 
  6.     size_t curlen = sdslen(s); 
  7.     //擴(kuò)容方法 
  8.     s = sdsMakeRoomFor(s,len); 
  9.     if (s == NULLreturn NULL
  10.     memcpy(s+curlen, t, len); 
  11.     sdssetlen(s, curlen+len); 
  12.     s[curlen+len] = '\0'
  13.     return s; 
  14.  
  15. sds sdsMakeRoomFor(sds s, size_t addlen) { 
  16.     void *sh, *newsh; 
  17.     //調(diào)用sds.h,獲取空閑長(zhǎng)度alloc 
  18.     size_t avail = sdsavail(s); 
  19.     size_t len, newlen; 
  20.     char type, oldtype = s[-1] & SDS_TYPE_MASK; 
  21.     int hdrlen; 
  22.  
  23.    //空閑長(zhǎng)度大于需要增加的,不需要擴(kuò)容,直接返回 
  24.     if (avail >= addlen) return s; 
  25.  
  26. //調(diào)用sds.h里面的sdslen,即取可用長(zhǎng)度 
  27.     len = sdslen(s); 
  28.  
  29.     sh = (char*)s-sdsHdrSize(oldtype); 
  30.     //len加上要添加的大小 
  31.     newlen = (len+addlen); 
  32.  
  33.     //#define SDS_MAX_PREALLOC (1024*1024) 
  34.     //當(dāng)新長(zhǎng)度小于 1024*1024,直接擴(kuò)容兩倍 
  35.     if (newlen < SDS_MAX_PREALLOC) 
  36.         newlen *= 2; 
  37.     else //當(dāng)新長(zhǎng)度大于 1024*1024,加2014*1024 
  38.         newlen += SDS_MAX_PREALLOC; 
  39.  
  40. //根據(jù)長(zhǎng)度計(jì)算新的類(lèi)型 
  41.     type = sdsReqType(newlen); 
  42.  
  43.     /* Don't use type 5: the user is appending to the string and type 5 is 
  44.      * not able to remember empty space, so sdsMakeRoomFor() must be called 
  45.      * at every appending operation. */ 
  46.     if (type == SDS_TYPE_5) type = SDS_TYPE_8; 
  47.  
  48. //獲取不同結(jié)構(gòu)體的頭部大小 
  49.     hdrlen = sdsHdrSize(type); 
  50.     //如果類(lèi)型一樣,直接使用原地址,長(zhǎng)度加上就行 
  51.     if (oldtype==type) { 
  52.         newsh = s_realloc(sh, hdrlen+newlen+1); 
  53.         if (newsh == NULLreturn NULL
  54.         s = (char*)newsh+hdrlen; 
  55.     } else {//如果類(lèi)型不一樣,重新開(kāi)辟內(nèi)存,把原來(lái)的數(shù)據(jù)復(fù)制過(guò)去 
  56.         newsh = s_malloc(hdrlen+newlen+1); 
  57.         if (newsh == NULLreturn NULL
  58.         memcpy((char*)newsh+hdrlen, s, len+1); 
  59.         s_free(sh); 
  60.         s = (char*)newsh+hdrlen; 
  61.         s[-1] = type; 
  62.         sdssetlen(s, len); 
  63.     } 
  64.     //設(shè)置新的總長(zhǎng)度 
  65.     sdssetalloc(s, newlen); 
  66.     return s; 
  67.  
  68. //計(jì)算不同類(lèi)型的結(jié)構(gòu)體的大小 
  69. static inline int sdsHdrSize(char type) { 
  70.     switch(type&SDS_TYPE_MASK) { 
  71.         case SDS_TYPE_5: 
  72.             return sizeof(struct sdshdr5); 
  73.         case SDS_TYPE_8: 
  74.             return sizeof(struct sdshdr8); 
  75.         case SDS_TYPE_16: 
  76.             return sizeof(struct sdshdr16); 
  77.         case SDS_TYPE_32: 
  78.             return sizeof(struct sdshdr32); 
  79.         case SDS_TYPE_64: 
  80.             return sizeof(struct sdshdr64); 
  81.     } 
  82.     return 0; 

總結(jié)

該篇主要講了Redis的底層實(shí)現(xiàn)SDS,包括SDS是什么,與傳統(tǒng)的C語(yǔ)言相比的優(yōu)勢(shì),具體的邏輯圖,常見(jiàn)的方法(包括創(chuàng)建,刪除,擴(kuò)容等)。同時(shí)也知道了Redis的embstr和raw的區(qū)別。

如果覺(jué)得寫(xiě)得還行,麻煩給個(gè)贊??,您的認(rèn)可才是我寫(xiě)作的動(dòng)力!

如果覺(jué)得有說(shuō)的不對(duì)的地方,歡迎評(píng)論指出。

好了,拜拜咯。

 

責(zé)任編輯:武曉燕 來(lái)源: 學(xué)習(xí)Java的小姐姐
相關(guān)推薦

2019-03-07 15:43:22

Redis數(shù)據(jù)SDS

2023-01-09 08:42:04

String數(shù)據(jù)類(lèi)型

2019-10-29 08:59:16

Redis底層數(shù)據(jù)

2023-11-12 21:49:10

Redis數(shù)據(jù)庫(kù)

2020-07-14 08:53:43

Redis數(shù)據(jù)存儲(chǔ)

2024-01-26 06:42:05

Redis數(shù)據(jù)結(jié)構(gòu)

2019-06-12 22:51:57

Redis軟件開(kāi)發(fā)

2019-04-17 15:35:37

Redis數(shù)據(jù)庫(kù)數(shù)據(jù)結(jié)構(gòu)

2019-09-02 09:48:39

Redis數(shù)據(jù)結(jié)構(gòu)對(duì)象

2025-01-07 08:00:00

有序集合數(shù)據(jù)結(jié)構(gòu)

2021-05-21 08:31:09

數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)樹(shù)

2021-06-08 06:01:00

C++數(shù)據(jù)結(jié)構(gòu)向量和數(shù)組

2021-08-29 07:41:48

數(shù)據(jù)HashMap底層

2024-08-12 16:09:31

2020-10-21 12:45:12

Redis數(shù)據(jù)結(jié)構(gòu)

2019-09-27 08:53:47

Redis數(shù)據(jù)C語(yǔ)言

2011-03-31 15:41:51

Cacti數(shù)據(jù)表結(jié)構(gòu)

2023-10-31 08:51:25

數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)數(shù)據(jù)

2021-08-31 07:36:22

LinkedListAndroid數(shù)據(jù)結(jié)構(gòu)

2019-09-18 08:31:47

數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)