设为首页 加入收藏

TOP

Redis源码整体运行流程详解(六)
2014-11-24 00:37:24 来源: 作者: 【 】 浏览:15
Tags:Redis 源码 整体 运行 流程 详解
\r\nbar\r\n" return REDIS_OK; } c->multibulklen = ll;//得到指令参数个数 /* Setup argv array on client structure */ if (c->argv) zfree(c->argv); c->argv = zmalloc(sizeof(robj*) * c->multibulklen);//申请参数内存空间 } redisAssertWithInfo(c,NULL,c->multibulklen > 0); /** 开始抽取字符串 querybuf = "*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n" pos = 4 */ while(c->multibulklen) { /* Read bulk length if unknown */ if (c->bulklen == -1) {//参数的长度为-1,这里用来处理每个参数的字符串长度值 /**newline = "\r\nSET\r\n$3\r\nfoo\r\n$3\r\nbar\r\n"*/ newline = strchr(c->querybuf+pos,'\r'); if (newline == NULL) { if (sdslen(c->querybuf) > REDIS_INLINE_MAX_SIZE) { addReplyError(c,"Protocol error: too big bulk count string"); setProtocolError(c,0); } break; } /* Buffer should also contain \n */ if (newline-(c->querybuf) > ((signed)sdslen(c->querybuf)-2)) break; //每个字符串以$开头,后面的数字表示其长度 if (c->querybuf[pos] != '$') { addReplyErrorFormat(c, "Protocol error: expected '$', got '%c'", c->querybuf[pos]); setProtocolError(c,pos); return REDIS_ERR; } //得到字符串的长度值,ll ok = string2ll(c->querybuf+pos+1,newline-(c->querybuf+pos+1),&ll); if (!ok || ll < 0 || ll > 512*1024*1024) { addReplyError(c,"Protocol error: invalid bulk length"); setProtocolError(c,pos); return REDIS_ERR; } //pos = 8 pos += newline-(c->querybuf+pos)+2;//跳过\r\n "SET\r\n$3\r\nfoo\r\n$3\r\nbar\r" if (ll >= REDIS_MBULK_BIG_ARG) {//字符串长度超过1024*32,需要扩展 size_t qblen; /* If we are going to read a large object from network * try to make it likely that it will start at c->querybuf * boundary so that we can optimize object creation * avoiding a large copy of data. */ /** sdsrange(querybuf,pos,-1)是将[pos,len-1]之间的字符串使用memmove前移, 然后后面的直接截断 */ sdsrange(c->querybuf,pos,-1);//"SET\r\n$3\r\nfoo\r\n$3\r\nbar\r" pos = 0; qblen = sdslen(c->querybuf); /* Hint the sds library about the amount of bytes this string is * going to contain. */ if (qblen < ll+2)//这里只会到最后一个字符串才可能为True,并且数据不完整,数据不完整是由于redis使用非阻塞的原因 c->querybuf = sdsMakeRoomFor(c->querybuf,ll+2-qblen); } c->bulklen = ll; } /* Read bulk argument */ //读取参数,没有\r\n表示数据不全,也就是说服务器接收到的数据不完整 if (sdslen(c->querybuf)-pos < (unsigned)(c->bulklen+2)) { /* Not enough data (+2 == trailing \r\n) */ break; } else {//数据完整 /* Optimization: if the buffer contains JUST our bulk element * instead of creating a new object by *copying* the sds we * just use the current sds string. */ if (pos == 0 && c->bulklen >= REDIS_MBULK_BIG_ARG && (signed) sdslen(c->querybuf) == c->bulklen+2) {//数据刚好完整,那么就直接使用c->querybuf,然后清空querybuf,注意这里只可能在最后一个字符串才可能出现 c->argv[c->argc++] = createObject(REDIS_STRING,c->querybuf); sdsIncrLen(c->querybuf,-2); /* remove CRLF */ c->querybuf = sdsempty(); /* Assume that if we saw a fat argument we'll see another one * likely... */ c->querybuf = sdsMakeRoomFor(c->querybuf,c->bulklen+2); pos = 0; } else { //抽取出具体的字符串,比如SET,建立一个stringObject c->argv[c->argc++] = createStringObject(c->querybuf+pos,c->bulklen); pos += c->bulklen+2;//跳过\r\n } c->bulklen = -1; c->multibulklen--; } } /** 由于采用的是非阻塞读取客户端数据的方式,那么如果c->multibulklen != 0,那么就表示 数据没有接收完全,首先需要将当前的querybuf数据截断 */ /* Trim to pos */ if (pos) sdsrange(c->querybuf,pos,-1); /* We're done when c->multibulk == 0 */ if (c->multibulklen == 0) return REDIS_OK; /* Still not read to process the command */ return R
首页 上一页 3 4 5 6 7 下一页 尾页 6/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇 面试-数据库性能(索引) 下一篇存储方式与介质对性能的影响

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: