標籤:style blog http color os 使用 ar strong for
sds動態字串資料結構如下:
1 typedef char *sds;2 3 struct sdshdr {4 int len;5 int free;6 char buf[];7 };
len記錄字串的長度,free記錄sds還剩餘的空間,buf指向儲存字元的空間。
對應的記憶體空間如:
例如最開始要存放字串“chenrancc”:
一般開始的時候會比初始字串多申請一個長度的空間放\0,如所示,對應的函數是sdsnewlen。
刪除後面的cc字元後:
刪除後面的cc字元後,空出兩個字元空間並不會回收,而是用free來記錄。如果要回收者兩個閒置空間,必須重新分配一個新的sds,做法是將原來的sds通過realloc重新分配成新的sds,對應的函數為sdsRemoveFreeSpace。如果要增加sds的空間,也是用同樣的方法通過realloc重新分配一個新的sds,對應的函數是sdsMakeRoomFor。
要回收sds所在的記憶體空間,可以通過函數sdsfree,它實際調用的是free函數。
除了上面提到的函數,sds中還定義了很多其它的函數來方便上層使用:
1 sds sdsnewlen(const void *init, size_t initlen); //用長度為initlen的字串建立sds 2 sds sdsempty(void); //建立一個長度為0的sds 3 sds sdsnew(const char *init); //用null結尾的字串建立sds 4 sds sdsdup(const sds s); //拷貝一個sds 5 void sdsfree(sds s); //釋放sds所佔的記憶體空間 6 void sdsupdatelen(sds s); //更新sds中的len為實際的字串長度 7 void sdsclear(sds s); //將sds中的字串為空白串 8 sds sdsMakeRoomFor(sds s, size_t addlen); //sds字串所佔空間增加addlen個字元(包括free所佔的字元) 9 sds sdsRemoveFreeSpace(sds s); //去除sds中閒置空間10 size_t sdsAllocSize(sds s); //擷取sds實際佔用空間的大小11 void sdsIncrLen(sds s, int incr); //sds實際字串的長度增加incr12 sds sdsgrowzero(sds s, size_t len); //將sds所佔的空間增加到len,增加的空間都清零13 sds sdscatlen(sds s, const void *t, size_t len); //sds末尾串連一個長度為len的字串14 sds sdscat(sds s, const char *t); //sds末尾串連一個以null結尾的字串15 sds sdscatsds(sds s, const sds t); //sds末尾串連另一個sds16 sds sdscpylen(sds s, const char *t, size_t len); //拷貝長度為len的字串到sds中17 sds sdscpy(sds s, const char *t); //拷貝以null結尾的字串到sds中18 sds sdscatvprintf(sds s, const char *fmt, va_list ap); //sds末尾串連一個由可變參數形成的字串19 sds sdscatprintf(sds s, const char *fmt, ...); //sds末尾串連一個由可變參數形成的字串20 sds sdstrim(sds s, const char *cset); //去除sds字串的前後字元,這些字元都是在cset中出現過的21 void sdsrange(sds s, int start, int end); //擷取sds字串的一個字串,start和end可以為負數,負數表示從後面往前面索引22 void sdstolower(sds s); //將sds字串中的字元設定為小寫23 void sdstoupper(sds s); //將sds字串中的字元設定為大寫24 int sdscmp(const sds s1, const sds s2); //比較兩個字串的大小25 sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count); //用字串sdp分割一個sds為多個sds26 void sdsfreesplitres(sds *tokens, int count); //釋放由函數sdssplitlen返回的sds數組空間27 sds sdsfromlonglong(long long value); //將long long類型的數字轉化為一個sds28 sds sdscatrepr(sds s, const char *p, size_t len); //sds末尾串連一個長度為len的字串,並且將其中的不可列印字元顯示出來29 int is_hex_digit(char c); //判斷一個字元釋放為16進位數字30 int hex_digit_to_int(char c); //將一個16進位數字轉化為整數31 sds *sdssplitargs(const char *line, int *argc); //將一個字串中用‘,"引用的字串組成多個sds32 sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen) //將sds中出現在from中的字元替換為to對應的字元33 sds sdsjoin(char **argv, int argc, char *sep); //將多個字串用分割符串連起來組成一個sds
View Code
sds和c++中的vector很類似,唯一不同的是vector在空間不夠的時候可以自動增加2倍的空間。
Redis的動態字串實現