日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

redis学习 -- 简单动态字符串

發布時間:2023/11/27 生活经验 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 redis学习 -- 简单动态字符串 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Redis沒有使用C語言字符串的形式,通過’\0’作為結尾,而是使用了簡單動態字符串(simple dynamic string)。
當Redis使用的字符串不需要修改字符串的內容的時候,可以使用C語言提供的字符串,當需要修改內容的時候就使用的是簡單動態字符串。Redis鍵值對的操作中,都是使用的簡單動態字符串的方式。

這里可以把簡單動態字符串理解成一個對象,這個對象的底層保存著一個字符串。

SDS定義

在sds.h/sdshdr結構體中定義了SDS的值

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

如果我們使用SDS定義一個SDS內容為“Redis”的對象,則組織結構如下圖所示

  • free屬性值為0,表示這個SDS沒有分配任何沒有使用的空間。
  • len屬性的值是5,表示這個SDS保存了一個五字節長的字符串。
  • buf屬性是一個char類型的數組,數組里面保存了字符串的值,并且以’\0’結束。

SDS和C字符串的區別和優勢

常數時間復雜度獲取字符串長度

C字符串獲取字符串長度需要遍歷,耗時。
SDS記錄了長度,可以在O(1)的時間復雜度獲取字符串長度。

杜絕緩沖區溢出

在C語言中使用strcat(dest, src)的時候,用戶自身需要保證dest的空間要大于拼接之后的內存空間。但是很多時候由于疏忽導致內存溢出。SDS解決了這個問題,使用SDS的APIsdscat的時候,他會進行檢測空間大小是否能夠滿足拼接之后的字符串大小。如果不能,他會重新開辟一個拼接后的大度的二倍的字符串空間。

減少修改字符串時帶來的內存重分配次數

C語言中,使用strcat的時候,用戶需要手動開辟空間,然后使用函數進行字符串的拼接。頻繁的申請空間是一個耗時的操作。但是Redis是一個數據庫,很可能會有頻繁的改變數據的操作,所以Redis不能容忍這種問題的出現,于是SDS的結構體中,喲一個free的屬性,這個是用來記錄未使用的空間的,實現了空間的預分配和惰性空間釋放兩種優化策略。

  1. 空間預分配
    當使用SDS的一個API的時候,程序不僅會開辟足夠容納數據的空間,還會額外的開辟未使用的空間。
    額外的未使用的空間的開辟,由如下的方式進行決定:
    如果程序需要使用的SDS的len長度小于1M的話,程序會開辟和len長度一樣大小的free空間。
    如果修改之后的len長度大于1M的話,程序會分配free為1M的空間。
    另外上面的兩種方式還會多分配一個自己的空間,用于存放’\0’。
    補充一點:只要當需要擴充內存空間的時候,才需要開辟。

  2. 惰性空間釋放
    當SDS需要使用API去釋放空間的時候,這個時候原有字符串會修改,但是開辟的空間并沒有釋放掉,而是將字符串向前移動,用free記錄未使用的空間大小。

二進制安全

SDS底層通過二進制的方式來保存數據。
Redis不僅可以保存文本數據,還可以保存二進制數據。
即使是文本數據,也是轉化成二進制數據保存的。

兼容部分C字符串函數

雖然是通過二進制保存數據,但是為了能夠兼容string的使用,保存了字符串的一些特性。

SDS API

SDS主要的API如下表

函數作用時間復雜度
sdsnew創建一個包含C字符串的SDSO(N),N為給定的字符串的長度
sdsempty創建一個不包含任何內容的空SDSO(1)
sdsfree釋放給定的SDSO(N),N為被釋放的SDS的長度
sdslen返回SDS的已經使用空間字節數O(1),通過讀取對象的len值直接獲取
sdsavail返回SDS未使用的空間字節數O(1),通過讀取對象的free的值獲取
sdsdup創建一個SDS的副本O,N是給定的SDS的長度
stdclear清空SDS保存的字符串內容O(1),由于惰性空間釋放,只改變了對象的len值
stscat將給定C字符串拼接都SDS字符串的末尾O(N),N為被拼接的字符串的長度
sdscatsds將給定的SDS拼接到另一個SDS字符串的末尾O,N為被拼接的SDS字符串的長度
sdscpy將給定的C字符串復制到SDS里面,覆蓋原有的字符串O(N),N為被復制的C字符串的長度
sdsgrowzero用空字符串將SDS擴展到給定長度O(N),N為擴展新增的字節數
sdssrange保留SDS給定區間的數據,不再全進的數據會被覆蓋或者是清除O(N),N為被保留數據的字節數
sdstrin接受一個SDS和一個C字符串作為參數,從SDS左右兩端移除所有在C字符串中出現過的字符串O(M*N),M為SDS的長度,N為給定C字符串的長度
sdscmp對比兩個SDS字符串是否相同O(N),N為兩個SDS中較短的那個SDS的長度

總結

以上是生活随笔為你收集整理的redis学习 -- 简单动态字符串的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。