设为首页 收藏本站
查看: 1196|回复: 0

[经验分享] 【redis源码】(二)Sds

[复制链接]

尚未签到

发表于 2015-7-21 08:03:28 | 显示全部楼层 |阅读模式
  Sds为redis的字符串操作函数,主要依赖于Zmalloc,直接贴代码
  Sds.h


DSC0000.gif DSC0001.gif 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[initlen] = '\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' && c  0)
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、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-88829-1-1.html 上篇帖子: Redis.py客户端的命令总结【一】 下篇帖子: Redis Java客户端Jedis入门
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表