簡單動態字串
鍊錶字典
跳表整數集合
壓縮列表
物件redis 沒有直接使用 c 字串(即以空字元』\0』結尾的字元陣列)作為預設的字串表示,而是使用了sds。sds 是簡單動態字串(****** dynamic string)的縮寫。它是自己構建了一種名為 簡單動態字串(****** dynamic string,sds)的抽象型別,並將 sds 作為redis的預設字串表示。sds的定義如下:
struct sdshdr
其中,len 儲存了sds儲存字串的長度,buf 陣列用來儲存字串的每個元素,free記錄了 buf 陣列中未使用的位元組數量。sds的資料結構示意圖如下:
buf陣列的長度=free+len+1。sds在c字串的基礎上加入了free和len欄位,帶來了很多好處:
獲取字串長度時間複雜度降低
避免了緩衝區溢位
可以使用空間預分配策略
訪問二進位制資料
獲取字串長度sds是o(1)的時間複雜度,而 c字串是o(n)的時間複雜度。使用 c 字串的 api 時,如果字串長度增加(如 strcat 操作)而忘記重新分配記憶體,很容易造成緩衝區的溢位。而 sds 由於記錄了長度,相應的 api 在可能造成緩衝區溢位時會自動重新分配記憶體,杜絕了緩衝區溢位。修改字串時記憶體的重分配:對於 c 字串,如果要修改字串,必須要重新分配記憶體(先釋放再申請),因為如果沒有重新分配,字串長度增大時會造成記憶體緩衝區溢位,字串長度減小時會造成記憶體洩露。而對於 sds,由於可以記錄 len 和 free,因此解除了字串長度和空間陣列長度之間的關聯,可以在此 基礎上進行優化。空間預分配策略(即分配記憶體時比實際需要的多)使得字串長度增大時重新分配記憶體的概率大大減小。惰性空間釋放策略使得字串長度減小時重新分配記憶體的概率大大減小。sds 可以訪問二進位制資料,c 字串不可以。因為 c 字串以空字元作為字串結束的標,而對於 一些二進位制檔案(如等)。內容可能包括空字串,因此 c 字串無法正確訪問,而 sds 以字串長度 len 來作為字串結束標識,因此沒有這個問題。此外,由於 sds 中的 buf 仍然使用了 c 字串(即以』\0』結尾),因此 sds 可以使用 c 字串庫中的 部分函式。但是需要注意的是,只有當 sds 用來儲存文字資料時才可以這樣使用,在儲存二進位制資料時則不行 (』\0』不一定是結尾)。接下來我們說一下鍊錶,鍊錶在redis中的應用非常廣泛,列表(list)的底層實現之一就是雙向鍊錶。此外發布與訂閱、慢查詢、 監視器等功能也用到了鍊錶。其資料結構定義如下:
typedef struct listnode listnodetypedef struct list list;
資料結構示意圖如下:
redis鍊錶的優勢如下:
雙端無環帶鍊錶長度計數器
多型鍊錶具有前置節點和後置節點的引用,獲取這兩個節點時間複雜度都為o(1)。表頭節點的 prev 指標和表尾節點的 next 指標都指向 null,對鍊錶的訪問都是以 null 結束。通過 len 屬性獲取鍊錶長度的時間複雜度為 o(1)。鍊錶節點使用 void* 指標來儲存節點值,可以儲存各種不同型別的值。
C 字串到位元組陣列,位元組陣列轉整型
int num 12345 string num1 convert.tostring 12345,16 byte bytes bitconverter.getbytes num 將int32轉換為位元組陣列 num bitconverter.toint32 bytes,0 將位元組陣列內容再轉成in...
C 結構體和位元組陣列的轉換
c 結構體和位元組陣列的轉換 在寫c tcp通訊程式時,傳送資料時,只能傳送byte陣列,處理起來比較麻煩不說,如果是和vc6.0等寫的程式通訊的話,很多的都是傳送結構體,在vc6.0中可以很方便的把乙個char陣列轉換為乙個結構體,而在c 卻不能直接把byte陣列轉換為結構體,要在c 中傳送結構體...
C 結構體和位元組陣列的轉換
本文主要起源於專案從c 轉到c 時碰到的問題,即套接字傳送資訊時的型別轉換。在c 中,套接字傳送和接收的型別為字元陣列char,而char與結構體struct可以直接進行顯式轉換就可以 在c 中,sockets類和networkstream類傳送和接收的型別為位元組陣列byte,而它與結構體的轉換並...