標籤:
redis使用sds代替char *字串,
其定義如下:
typedef char *sds;struct sdshdr { unsigned int len; unsigned int free; char buf[];};
sds指向了char 字串
sdshdr是字串頭
結構比較巧妙
使用char buf[]存放字串實際內容
注意char *buf和char buf[]是不同的
sizeof(sdshdr)等於8,而不是我以為的12
連續記憶體結構如下:
0----7 sdshdr
8----以後 sds ,同時也是buf位置
建立sds的方法
sds sdsnewlen(const void *init, size_t initlen) { struct sdshdr *sh; if (init) { sh = zmalloc(sizeof(struct sdshdr)+initlen+1); } else { sh = zcalloc(sizeof(struct sdshdr)+initlen+1); } if (sh == NULL) return NULL; sh->len = initlen; sh->free = 0; if (initlen && init) memcpy(sh->buf, init, initlen); sh->buf[initlen] = ‘\0‘; return (char*)sh->buf;}
釋放sds的方法
void sdsfree(sds s) { if (s == NULL) return; zfree(s-sizeof(struct sdshdr));}
注意sds指向的是實際的字串,而不是sdshdr。
在sds.c裡面有很多對sds字串進行處理的函數,(畢竟為了取代char *)
函數名稱 |
作用 |
複雜度 |
sdsnewlen |
建立一個指定長度的sds,接受一個指定的C字串作為初始化值 |
O(N) |
sdsempty |
建立一個只包含Null 字元串””的sds |
O(N) |
sdsnew |
根據給定的C字串,建立一個相應的sds |
O(N) |
sdsdup |
複製給定的sds |
O(N) |
sdsfree |
釋放給定的sds |
O(1) |
sdsupdatelen |
更新給定sds所對應的sdshdr的free與len值 |
O(1) |
sdsclear |
清除給定sds的buf,將buf初始化為””,同時修改對應sdshdr的free與len值 |
O(1) |
sdsMakeRoomFor |
對給定sds對應sdshdr的buf進行擴充 |
O(N) |
sdsRemoveFreeSpace |
在不改動sds的前提下,將buf的多餘空間釋放 |
O(N) |
sdsAllocSize |
計算給定的sds所佔的記憶體大小 |
O(1) |
sdsIncrLen |
對給定sds的buf的右端進行擴充或縮小 |
O(1) |
sdsgrowzero |
將給定的sds擴充到指定的長度,空餘的部分用\0進行填充 |
O(N) |
sdscatlen |
將一個C字串追加到給定的sds對應sdshdr的buf |
O(N) |
sdscpylen |
將一個C字串複製到sds中,需要依據sds的總長度來判斷是否需要擴充 |
O(N) |
sdscatprintf |
通過格式化輸出形式,來追加到給定的sds |
O(N) |
sdstrim |
對給定sds,刪除前端/後端在給定的C字串中的字元 |
O(N) |
sdsrange |
截取給定sds,[start,end]字串 |
O(N) |
sdscmp |
比較兩個sds的大小 |
O(N) |
sdssplitlen |
對給定的字串s按照給定的sep分隔字串來進行切割 |
O(N) |
Redis源碼閱讀-sds字串源碼閱讀