国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Redis數(shù)據(jù)結(jié)構(gòu)二之SDS和雙向鏈表

這篇具有很好參考價值的文章主要介紹了Redis數(shù)據(jù)結(jié)構(gòu)二之SDS和雙向鏈表。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

本文首發(fā)于公眾號:Hunter后端
原文鏈接:Redis數(shù)據(jù)結(jié)構(gòu)二之SDS和雙向鏈表

這一篇筆記介紹一下 SDS(simple dynamic string)和雙向鏈表。

以下是本篇筆記目錄:

  1. SDS
    1. 常數(shù)復(fù)雜度獲取字符串長度
    2. 杜絕緩沖區(qū)溢出
    3. 減少修改字符串帶來的內(nèi)存重分配次數(shù)
    4. 二進(jìn)制安全
    5. 兼容C字符串函數(shù)
  2. 雙向鏈表

1、 SDS

SDS,simple dynamic string,即簡單動態(tài)字符串

SDS 在 Redis 2.9 版本中數(shù)據(jù)結(jié)構(gòu)如下:

struct sdshdr {
    int len;
    int free;
    char buf[];
};

在這個結(jié)構(gòu)中,len 表示 buf 數(shù)組中已使用字節(jié)的數(shù)量,free 表示 buf 數(shù)組中未使用字節(jié)的數(shù)量,buf 則表示是一個 char 類型的數(shù)組。

Redis 沒有復(fù)用 C字符串,有以下幾個方面的考慮和優(yōu)點。

1. 常數(shù)復(fù)雜度獲取字符串長度

C字符串并不記錄自身的長度信息,如果要獲取C字符串的長度,必須遍歷整個字符串然后計數(shù)。

SDS 結(jié)構(gòu)中有 len 屬性記錄 SDS 本身的長度,可以直接獲取。

2. 杜絕緩沖區(qū)溢出

因為 C字符串并不記錄自身的長度信息,在執(zhí)行某些操作,比如拼接字符串的時候,并不會自動查詢是否擁有足夠內(nèi)存,那么這個操作可能就會造成緩沖區(qū)溢出的問題

而 SDS 執(zhí)行相應(yīng)的字符串修改時,其 API 會先檢查 SDS 的空間是否需求,不滿足則會進(jìn)行擴(kuò)展,這個空間分配策略也就是下面要講的

3. 減少修改字符串帶來的內(nèi)存重分配次數(shù)

C字符串每次進(jìn)行字符串修改時,程序都需要手動進(jìn)行內(nèi)存重分配的操作,而 SDS 通過空間預(yù)分配和惰性空間釋放兩種策略對此進(jìn)行了優(yōu)化

空間預(yù)分配

當(dāng) SDS API 對一個 SDS 進(jìn)行修改并需要對 SDS 進(jìn)行空間擴(kuò)展時,程序不僅會為 SDS 分配修改所需要的空間,還會為其分配額外的未使用空間

如果修改之后,SDS 的長度,也就是結(jié)構(gòu)中的 len 屬性小于 1MB,那么程序會額外分配同樣大小的未使用空間,這個時候,len 屬性和 free 屬性將相同

如果修改之后,SDS 的長度,也就是結(jié)構(gòu)中的 len 屬性大于等于 1MB,那么程序會額外分配 1MB 的未使用空間

惰性空間釋放

當(dāng)需要對SDS保存的字符串進(jìn)行縮短時,程序并不會重新分配內(nèi)存來回收多出來的字節(jié),而是會使用 free 屬性將這些字節(jié)記錄下來,以備后面使用

4. 二進(jìn)制安全

C字符串保存的字符結(jié)尾都是以空字符結(jié)尾,所以字符串中間不能包含空字符,否則程序讀入空字符的時候就會被認(rèn)為是字符串結(jié)尾,因此C字符串只能保存文本數(shù)據(jù),不能保存圖片、音頻等這樣的二進(jìn)制數(shù)據(jù)

而 SDS 的 API 都是以處理二進(jìn)制的方式來處理 SDS 中存放在 buf 里的數(shù)據(jù),程序不會對數(shù)據(jù)做任何限制、過濾,所以 SDS 的 API 都是二進(jìn)制安全的

SDS 使用 len 屬性值而不是空字符串來判斷字符串是否結(jié)束

5. 兼容C字符串函數(shù)

雖然SDS的API都是二進(jìn)制安全的,但是仍然遵循C字符串以空字符結(jié)尾的慣例,而且在為 buf 數(shù)組分配空間的時候總是會多分配一個字節(jié)來容納這個空字符,所以保存文本數(shù)據(jù)的 SDS 可以重用一部分C中的函數(shù)

以下是 SDS 與 C字符串區(qū)別的總結(jié):

C字符串 SDS
獲取字符串長度復(fù)雜度為 O(N) 獲取字符串長度復(fù)雜度為O(1)
API是不安全的,可能會造成緩沖區(qū)溢出 API是安全的,不會造成緩沖區(qū)溢出
修改字符串長度N次必須執(zhí)行N次內(nèi)存重分配 修改長度N次最多需要執(zhí)行N次內(nèi)存重分配
只能保存文本數(shù)據(jù) 可以保存文本或者二進(jìn)制數(shù)據(jù)
可以使用<string.h>庫中函數(shù) 可以使用部分

在之后的的 Redis 版本對 SDS 的結(jié)構(gòu)有過更新,將 free 屬性換成了 alloc,這個屬性表示的意思是分配的空間長度。和之前的 free 屬性比較,其關(guān)系是 alloc = free + len

2、 雙向鏈表

C 語言沒有鏈表這個結(jié)構(gòu),所以 Redis 自己設(shè)計了一個鏈表數(shù)據(jù)結(jié)構(gòu)。

在 Redis 中,鏈表節(jié)點的結(jié)構(gòu)擁有指向前置節(jié)點和后置節(jié)點的屬性。

鏈表結(jié)構(gòu)則包含鏈表表頭節(jié)點、表尾節(jié)點、節(jié)點長度等屬性,便于快速獲取鏈表相關(guān)信息。

雙向鏈表是列表對象的底層實現(xiàn)之一,什么情況下使用雙向鏈表作為列表對象的底層實現(xiàn)我們之后再介紹。

以下是鏈表節(jié)點的結(jié)構(gòu):

typedef struct listNode{
    // 前置節(jié)點
    struct listNode *prev;
    
    // 后置節(jié)點 
    struct listNode *next;
    
    // 節(jié)點值
    struct *value;

}listNode;

在鏈表節(jié)點中,擁有前置節(jié)點和后置節(jié)點的指針構(gòu)成雙向的鏈表。

以下是鏈表的結(jié)構(gòu):

typedef struct list{
    // 表頭節(jié)點
    listNode *head;
    
    // 表尾節(jié)點
    listNode *tail;
    
    // 鏈表包含的節(jié)點數(shù)量
    unsigned long len;
    
    ...
}list;

在鏈表結(jié)構(gòu)中,有表頭節(jié)點和表尾節(jié)點可快速定位到鏈表的頭部和尾部,以及用有 len 屬性表示鏈表包含的節(jié)點數(shù)量。

如果想獲取更多后端相關(guān)文章,可掃碼關(guān)注閱讀:
Redis數(shù)據(jù)結(jié)構(gòu)二之SDS和雙向鏈表文章來源地址http://www.zghlxwxcb.cn/news/detail-482376.html

到了這里,關(guān)于Redis數(shù)據(jù)結(jié)構(gòu)二之SDS和雙向鏈表的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 數(shù)據(jù)結(jié)構(gòu) - 雙向鏈表

    數(shù)據(jù)結(jié)構(gòu) - 雙向鏈表

    文章目錄 目錄 文章目錄 前言 一、什么是雙向鏈表? 雙向鏈表有什么優(yōu)勢? 二、雙向鏈表的設(shè)計和實現(xiàn) 1.設(shè)計思想 尾增 : 在鏈表的末尾添加新的元素 ?頭插 : 在鏈表頭部插入節(jié)點 ?刪除 : 根據(jù)val的值刪除節(jié)點 ?查找 : 根據(jù)索引的值查找并返回節(jié)點 總結(jié) 大家好,今天給大家講解

    2024年02月09日
    瀏覽(28)
  • 數(shù)據(jù)結(jié)構(gòu)---雙向鏈表

    單向鏈表:一塊內(nèi)存指向下一個內(nèi)存。 單鏈表存在一些缺陷: 1.查找速度慢。 2.不能從后往前找。 3.找不到前驅(qū)。 鏈表的結(jié)構(gòu)分為8種: 1.單向和雙向 2.帶頭和不帶頭 帶頭的鏈表有一個帶哨兵位的頭結(jié)點,這個節(jié)點不存儲有效數(shù)據(jù)。 好處 :尾插更方便,不需要二級指針了,

    2024年02月02日
    瀏覽(25)
  • 數(shù)據(jù)結(jié)構(gòu)雙向鏈表

    數(shù)據(jù)結(jié)構(gòu)雙向鏈表

    Hello,好久不見,今天我們講鏈表的雙向鏈表,這是一個很厲害的鏈表,帶頭雙向且循環(huán),學(xué)了這個鏈表,你會發(fā)現(xiàn)順序表的頭插頭刪不再是一個麻煩問題,單鏈表的尾插尾刪也變得簡單起來了,那廢話不多說,讓我們開始我們的學(xué)習(xí)吧! 首先我們要了解它的物理和邏輯結(jié)構(gòu)

    2024年02月11日
    瀏覽(25)
  • 數(shù)據(jù)結(jié)構(gòu)-雙向鏈表

    數(shù)據(jù)結(jié)構(gòu)-雙向鏈表

    在單鏈表那一篇博客中介紹了單鏈表和雙向鏈表的優(yōu)缺點,所以此篇博客直接分享怎樣實現(xiàn)一個帶頭雙向循環(huán)鏈表。 單鏈表博客: 首先我們需要寫一個結(jié)構(gòu)體,雙向帶頭鏈表的話需要一個前驅(qū)指針prev和一個后驅(qū)指針next,前驅(qū)指針的作用是方便找尾節(jié)點,因為頭節(jié)點的prev指

    2024年02月05日
    瀏覽(44)
  • 數(shù)據(jù)結(jié)構(gòu)—雙向鏈表

    數(shù)據(jù)結(jié)構(gòu)—雙向鏈表

    目錄 1.? 鏈表的種類 2.? 最實用的兩種鏈表類型 3.? 實現(xiàn)雙向帶頭循環(huán)鏈表 ? ? ? ? ? ? ? ? ? 3.1 創(chuàng)建頭節(jié)點 ????????3.2 實現(xiàn)雙向循環(huán)功能—返回頭指針 ????????3.3? 尾插?? ????????3.4 頭插 ????????3.5 尾刪 ????????3.6 頭刪 4.? 實現(xiàn)兩個重要接口函數(shù) ?

    2023年04月23日
    瀏覽(28)
  • 數(shù)據(jù)結(jié)構(gòu)——雙向鏈表

    數(shù)據(jù)結(jié)構(gòu)——雙向鏈表

    ??系列專欄:??數(shù)據(jù)結(jié)構(gòu) ?? ?歡迎關(guān)注:??點贊??收藏??留言 ?? 博客主頁:??_麥麥_的博客_CSDN博客-領(lǐng)域博主 ??如果我們都不能夠擁有黑夜,又該怎樣去仰望星空? ? 目錄 一、前言 二、正文——雙向鏈表的實現(xiàn) 2.1模塊化 2.2 數(shù)據(jù)類型與結(jié)構(gòu)體定義 ?2.3鏈表的初始化

    2024年02月02日
    瀏覽(26)
  • 數(shù)據(jù)結(jié)構(gòu)——實現(xiàn)雙向鏈表

    數(shù)據(jù)結(jié)構(gòu)——實現(xiàn)雙向鏈表

    怎么說呢?光乍一聽名字好像很難的樣子是吧,那如果你這樣認(rèn)為的話,可就要讓你大跌眼鏡了哦,其實雙向帶頭循環(huán)鏈表從操作和理解上來說都是要易于單項不帶頭不循環(huán)鏈表(俗稱單鏈表)的。 咱們就來見識見識吧!希望真的能讓你們“大跌眼鏡”哈! 雙向帶頭循環(huán)鏈

    2024年02月07日
    瀏覽(22)
  • 【數(shù)據(jù)結(jié)構(gòu)】鏈表的分類和雙向鏈表

    【數(shù)據(jù)結(jié)構(gòu)】鏈表的分類和雙向鏈表

    本篇是基于上篇單鏈表所作,推薦與上篇配合閱讀,效果更加 http://t.csdnimg.cn/UhXEj 鏈表的結(jié)構(gòu)非常多樣,以下情況組合起來就有8種(2 x 2 x 2)鏈表結(jié)構(gòu): 我們一般叫這個頭為哨兵位 我們上回講的單鏈表就是不帶頭單項不循環(huán)鏈表。 今天我們要講帶頭雙向循環(huán)的鏈表。 不過

    2024年01月25日
    瀏覽(26)
  • 數(shù)據(jù)結(jié)構(gòu)入門 — 鏈表詳解_雙向鏈表

    數(shù)據(jù)結(jié)構(gòu)入門 — 鏈表詳解_雙向鏈表

    數(shù)據(jù)結(jié)構(gòu)入門 — 雙向鏈表詳解 博客主頁鏈接:https://blog.csdn.net/m0_74014525 關(guān)注博主,后期持續(xù)更新系列文章 文章末尾有源碼 *****感謝觀看,希望對你有所幫助***** 第一篇:數(shù)據(jù)結(jié)構(gòu)入門 — 鏈表詳解_單鏈表 第二篇:數(shù)據(jù)結(jié)構(gòu)入門 — 鏈表詳解_雙向鏈表 第三篇:數(shù)據(jù)結(jié)構(gòu)入門

    2024年02月11日
    瀏覽(19)
  • 數(shù)據(jù)結(jié)構(gòu):詳解【鏈表】的實現(xiàn)(單向鏈表+雙向鏈表)

    數(shù)據(jù)結(jié)構(gòu):詳解【鏈表】的實現(xiàn)(單向鏈表+雙向鏈表)

    1.順序表的問題和思考 問題: 中間/頭部的插入刪除,時間復(fù)雜度為O(N)。 增容需要申請新空間,拷貝數(shù)據(jù),釋放舊空間,會有不小的消耗。 增容一般是呈2倍的增長,勢必會有一定的空間浪費(fèi)。例如當(dāng)前容量為100,滿了以后增容到200,我們再繼續(xù)插入了5個數(shù)據(jù),后面沒有數(shù)據(jù)

    2024年03月26日
    瀏覽(36)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包