小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

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

 路人甲Java 2022-03-17

SDS(simple dynamic string),簡(jiǎn)單動(dòng)態(tài)字符串。s同時(shí)它被稱為 Hacking String。hack 的地方就在 sds 保存了字符串的長(zhǎng)度以及剩余空間。sds 的實(shí)現(xiàn)在 sds.c 中。

C語(yǔ)言字符串使用長(zhǎng)度為n+1的字符數(shù)組來(lái)表示長(zhǎng)度為n的字符串,并且字符數(shù)組的最后一個(gè)元素總是空字符'\0',這樣的方式存儲(chǔ),時(shí)存在安全隱患的,并且它不能滿足效率方面的需求。

因此Redis沒(méi)有使用C原生的string而是自己構(gòu)建了SDS。在Redis里,C語(yǔ)言字符串只用于一些無(wú)須對(duì)字符串值進(jìn)行修改的地方,比如:日志。

在Redis中,包含字符串值的鍵值對(duì)都是使用SDS實(shí)現(xiàn)的,除此之外,SDS還被用于AOF緩沖區(qū)、客戶端狀態(tài)的輸入緩沖區(qū)。

SDS定義

struct sdshdr{
     //字節(jié)數(shù)組
     char buf[]; 
     //buf數(shù)組中已使用字節(jié)數(shù)量
     int len;
     //buf數(shù)組中未使用字節(jié)數(shù)量
     int free;
}

如上圖所示,len表示該SDS保存了一個(gè)6字節(jié)長(zhǎng)度(不包含結(jié)束符)的字符串,free表示該SDS還有6個(gè)字節(jié)的未使用空間,buf是一個(gè)char類型的數(shù)組 ,保存了該SDS所存儲(chǔ)的字符串值。

高效

相比C語(yǔ)言字符串,使獲取字符串長(zhǎng)度時(shí)間復(fù)雜度降為O(1)而C原生的獲取長(zhǎng)度為O(N) 遍歷整個(gè)數(shù)組。

安全

同時(shí)SDS杜絕緩沖區(qū)溢出,不會(huì)像C那樣造成數(shù)組數(shù)據(jù)不安全,絕對(duì)不會(huì)越界。

當(dāng)需要對(duì)SDS進(jìn)行修改時(shí),API會(huì)先檢查SDS當(dāng)前剩余空間是否滿足修改之后所需的空間,如果不滿足的話API會(huì)自動(dòng)將SDS的空間擴(kuò)展至足夠用的空間然后才進(jìn)行下一步操作,所以SDS不會(huì)出現(xiàn)緩沖區(qū)溢出問(wèn)題。

減少內(nèi)存分配

C語(yǔ)言字原生符串底層是使用一個(gè)n+1個(gè)字符長(zhǎng)度的char類型數(shù)據(jù)實(shí)現(xiàn)的,所以每次增長(zhǎng)或縮短一個(gè)原生字符串,程序都要對(duì)這個(gè)字符串?dāng)?shù)組進(jìn)行一次內(nèi)存重分配操作:

同時(shí)因?yàn)閮?nèi)存重分配涉及復(fù)雜的算法,并且可能需要執(zhí)行系統(tǒng)調(diào)用,所以它通常是一個(gè)比較耗時(shí)的操作。Redis經(jīng)常被用于速度要求嚴(yán)苛、數(shù)據(jù)被頻繁修改的場(chǎng)合,如果每次修改字符串都需要執(zhí)行一次內(nèi)存重分配的話,那么對(duì)于性能會(huì)造成很大影響。

SDS 在分配了內(nèi)存之后(往往空間會(huì)存在盈余,也就是空間的預(yù)分配),然后自己通過(guò)len 和 free 來(lái)維護(hù)已使用的和未使用的內(nèi)存,不再依賴系統(tǒng)來(lái)重新劃分,這樣能有效的提升性能。

空間預(yù)分配

用于字符串增長(zhǎng)操作,當(dāng)字符串增長(zhǎng)時(shí),程序會(huì)先檢查需不需要對(duì)SDS空間進(jìn)行擴(kuò)展,如果需要擴(kuò)展,程序不僅會(huì)為SDS分配修改所必要的空間,還會(huì)為SDS分配額外的未使用空間,額外分配的未使用空間公式如下:

SDS空間 < 1MB

如果對(duì)SDS修改之后,SDS的長(zhǎng)度(修改之后len屬性的值)小于1MB,那么則分配和len屬性同樣大小的未使用空間,這時(shí)SDS的len屬性和free屬性的值相同。如:如果修改之后SDS的len將變?yōu)?0字節(jié),那么程序也會(huì)分配10字節(jié)的未使用空間,SDS的buf數(shù)組實(shí)際長(zhǎng)度變?yōu)?0 + 10 + 1 = 21(額外一個(gè)字節(jié)用于保存結(jié)束符\n)

SDS空間 > 1MB

如果對(duì)SDS修改之后,SDS的長(zhǎng)度大于等于1MB,那么程序會(huì)分配1MB的未使用空間。如:修改之后的len將變?yōu)?0MB,那么程序會(huì)分配1MB的未使用空間,SDS的bug數(shù)組長(zhǎng)度為10MB + 1MB + 1byte

SDS空間 > 512MB

Game over~ 報(bào)錯(cuò)!

惰性空間釋放

用于優(yōu)化SDS的字符串收縮操作,當(dāng)字符串收縮時(shí),程序不會(huì)立即執(zhí)行內(nèi)存重分配來(lái)回收收縮后內(nèi)存多出來(lái)的空間,而是使用free屬性記錄下來(lái),以備將來(lái)使用。

通過(guò)空間預(yù)分配,Redis可以減少連續(xù)執(zhí)行字符串增長(zhǎng)操作所需的內(nèi)存重分配次數(shù),通過(guò)惰性空間釋放,SDS避免了縮短字符串時(shí)所需的內(nèi)存重分配操作,并為將來(lái)由可能的增長(zhǎng)操作提供了優(yōu)化。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多