fablefe 发表于 2015-7-21 08:03:28

【redis源码】(二)Sds

  Sds为redis的字符串操作函数,主要依赖于Zmalloc,直接贴代码
  Sds.h


View Code


1 #ifndef __SDS_H
2 #define __SDS_H
3
4 #include
5 #include
6
7 typedef char *sds;
8
9
10 //可变长度结构体,sizeof(sdshdr)=8
11 struct sdshdr {
12   int len;
13   int free;
14   char buf[];
15 };
16
17 sds sdsnewlen(const void *init, size_t initlen);
18 sds sdsnew(const char *init);
19 sds sdsempty();
20 size_t sdslen(const sds s);
21 sds sdsdup(const sds s);
22 void sdsfree(sds s);
23 size_t sdsavail(sds s);
24 sds sdsgrowzero(sds s, size_t len);
25 sds sdscatlen(sds s, void *t, size_t len);
26 sds sdscat(sds s, char *t);
27 sds sdscpylen(sds s, char *t, size_t len);
28 sds sdscpy(sds s, char *t);
29
30 sds sdscatvprintf(sds s, const char *fmt, va_list ap);
31 #ifdef __GNUC__
32 sds sdscatprintf(sds s, const char *fmt, ...)
33   __attribute__((format(printf, 2, 3)));
34 #else
35 sds sdscatprintf(sds s, const char *fmt, ...);
36 #endif
37
38 sds sdstrim(sds s, const char *cset);
39 sds sdsrange(sds s, int start, int end);
40 void sdsupdatelen(sds s);
41 int sdscmp(sds s1, sds s2);
42 sds *sdssplitlen(char *s, int len, char *sep, int seplen, int *count);
43 void sdsfreesplitres(sds *tokens, int count);
44 void sdstolower(sds s);
45 void sdstoupper(sds s);
46 sds sdsfromlonglong(long long value);
47 sds sdscatrepr(sds s, char *p, size_t len);
48 sds *sdssplitargs(char *line, int *argc);
49
50 #endif
  Sds.c


View Code


1 //是否在内存申请失败时发出SIGABRT信号
2 #define SDS_ABORT_ON_OOM
3
4 #include "sds.h"
5 #include
6 #include
7 #include
8 #include
9 #include "zmalloc.h"
10
11
12 //当内存申请失败时发出SIGABRT信号
13 static void sdsOomAbort(void) {
14   fprintf(stderr,"SDS: Out Of Memory (SDS_ABORT_ON_OOM defined)\n");
15   abort();
16 }
17
18 //初始化存储长度为initlen的sds结构体,返回sds中buf字段的指针
19 sds sdsnewlen(const void *init, size_t initlen) {
20   struct sdshdr *sh;
21   //8 + initlen + 1 = sizeof(int) + sizeof(int) + sizeof('\0')
22   sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
23 #ifdef SDS_ABORT_ON_OOM
24   if (sh == NULL) sdsOomAbort();
25 #else
26   if (sh == NULL) return NULL;
27 #endif
28   sh->len = initlen;
29   sh->free = 0;
30   if (initlen) {
31         if (init) memcpy(sh->buf, init, initlen);
32         else memset(sh->buf,0,initlen);
33   }
34   sh->buf = '\0';
35   return (char*)sh->buf;
36 }
37
38 //初始化一个字符串为空的sds中buf字段的指针
39 sds sdsempty(void) {
40   return sdsnewlen("",0);
41 }
42
43 //将一个char *转化成sds结构,得到sds中buf字段的指针
44 sds sdsnew(const char *init) {
45   size_t initlen = (init == NULL) ? 0 : strlen(init);
46   return sdsnewlen(init, initlen);
47 }
48
49 //根据buf的指针-8得到sds结构体的指针,得到len字段
50 size_t sdslen(const sds s) {
51   struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
52   return sh->len;
53 }
54
55 //复制一个sds字符串
56 sds sdsdup(const sds s) {
57   return sdsnewlen(s, sdslen(s));
58 }
59
60 //释放sds字符串所在的整个sdshdr的结构体的内存空间
61 void sdsfree(sds s) {
62   if (s == NULL) return;
63   zfree(s-sizeof(struct sdshdr));
64 }
65
66 //得到sds结构的可用长度,即s->len - strlen(s->buff)
67 size_t sdsavail(sds s) {
68   struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
69   return sh->free;
70 }
71
72 //当sds字符串操作后,更新sds结构体中的len信息
73 void sdsupdatelen(sds s) {
74   struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
75   int reallen = strlen(s);
76   sh->free += (sh->len-reallen);
77   sh->len = reallen;
78 }
79
80 //另外在sds s串中申请长度为addlen长度的空间
81 static sds sdsMakeRoomFor(sds s, size_t addlen) {
82   struct sdshdr *sh, *newsh;
83   size_t free = sdsavail(s);
84   size_t len, newlen;
85
86   if (free >= addlen) return s;
87   len = sdslen(s);
88   sh = (void*) (s-(sizeof(struct sdshdr)));
89   newlen = (len+addlen)*2; //多申请些,以防止短时内再次申请 ? 有点不明白为什么这么做
90   newsh = zrealloc(sh, sizeof(struct sdshdr)+newlen+1);
91 #ifdef SDS_ABORT_ON_OOM
92   if (newsh == NULL) sdsOomAbort();
93 #else
94   if (newsh == NULL) return NULL;
95 #endif
96
97   newsh->free = newlen - len;
98   return newsh->buf;
99 }
100
101 /* Grow the sds to have the specified length. Bytes that were not part of
102* the original length of the sds will be set to zero. */
103 //扩容s所能容纳的字符串的长度到len
104 sds sdsgrowzero(sds s, size_t len) {
105   struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
106   size_t totlen, curlen = sh->len;
107
108   if (len = '0' && c = 'a' && c = 'A' && c0)
619
620         sdsfree(y);
621         sdsfree(x);
622         x = sdsnew("bar");
623         y = sdsnew("bar");
624         test_cond("sdscmp(bar,bar)", sdscmp(x,y) == 0)
625
626         sdsfree(y);
627         sdsfree(x);
628         x = sdsnew("aar");
629         y = sdsnew("bar");
630         test_cond("sdscmp(bar,bar)", sdscmp(x,y) < 0)
631   }
632   test_report()
633 }
634 #endif
  哦了,越看越费力,基础很差~路漫漫~加油
页: [1]
查看完整版本: 【redis源码】(二)Sds