您的位置:首页 > 数据库 > Redis

Redis源码分析系列三:initServerConfig下半部分

2013-10-16 00:00 489 查看
经过短暂的休息,开始研究initServerConfig下半部分。

//开始研究下半部分

/* Replication related */
server.masterauth = NULL;//设置masterauth为NULL

server.masterhost = NULL;

server.masterport = 6379;

server.master = NULL;

server.cached_master = NULL;

server.repl_master_initial_offset = -1;

server.repl_state = REDIS_REPL_NONE;

server.repl_syncio_timeout = REDIS_REPL_SYNCIO_TIMEOUT;

server.repl_serve_stale_data = REDIS_DEFAULT_SLAVE_SERVE_STALE_DATA;

server.repl_slave_ro = REDIS_DEFAULT_SLAVE_READ_ONLY;

server.repl_down_since = 0; /* Never connected, repl is down since EVER. */

server.repl_disable_tcp_nodelay = REDIS_DEFAULT_REPL_DISABLE_TCP_NODELAY;

server.slave_priority = REDIS_DEFAULT_SLAVE_PRIORITY;

server.master_repl_offset = 0;

/* Replication partial resync backlog */
server.repl_backlog = NULL;
//设置repl_backlog为NULL

server.repl_backlog_size = REDIS_DEFAULT_REPL_BACKLOG_SIZE;

server.repl_backlog_histlen = 0;

server.repl_backlog_idx = 0;

server.repl_backlog_off = 0;

server.repl_backlog_time_limit = REDIS_DEFAULT_REPL_BACKLOG_TIME_LIMIT;
//设置repl_backlog_time_limit为 3600

server.repl_no_slaves_since = time(NULL);

//设置为当前时间

/* Client output buffer limits */
for (j = 0; j < REDIS_CLIENT_LIMIT_NUM_CLASSES; j++)
{
server.client_obuf_limits[j] = clientBufferLimitsDefaults[j];
//设置的三个成员分别如下所示:
// {0, 0, 0}, /* normal */
// {1024*1024*256, 1024*1024*64, 60}, /* slave */
//{1024*1024*32, 1024*1024*8, 60}
}

/* Double constants initialization */
R_Zero = 0.0;

R_PosInf = 1.0/R_Zero;
R_NegInf = -1.0/R_Zero;

R_Nan = R_Zero/R_Zero;

/* Command table -- we initiialize it here as it is part of the
* initial configuration, since command names may be changed via
* redis.conf using the rename-command directive. */

下面开始分析dictCreate函数:

这个函数不难,经过执行完后,任何一个 struct dict的变量都是如下所示,可以作为模板使用:

typedef struct dict

{
dictType *type; //(会变化) commandTableDictType
void *privdata; // NULL

dictht ht[2];
// ht[0]定义开始
/*
table = NULL;
size = 0;
sizemask = 0;
used = 0;
*/
// ht[0]定义结束

// ht[1]定义开始
/*
table = NULL;
size = 0;
sizemask = 0;
used = 0;
*/
// ht[1]定义结束
int rehashidx; /* rehashing not in progress if rehashidx == -1 */
// -1

int iterators; /* number of iterators currently running */
// 0
} dict;

然后继续看代码:

server.commands = dictCreate(&commandTableDictType,NULL);

//则commands就是上面的模板一样的变量

server.orig_commands = dictCreate(&commandTableDictType,NULL);

//同上

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~·

到了本部分最关键的函数 populateCommandTable();

在这个函数里,

首先看代码:

while(*f != '\0')
{
switch(*f)
{
case 'w': c->flags |= REDIS_CMD_WRITE; break;
case 'r': c->flags |= REDIS_CMD_READONLY; break;
case 'm': c->flags |= REDIS_CMD_DENYOOM; break;
case 'a': c->flags |= REDIS_CMD_ADMIN; break;
case 'p': c->flags |= REDIS_CMD_PUBSUB; break;
case 's': c->flags |= REDIS_CMD_NOSCRIPT; break;
case 'R': c->flags |= REDIS_CMD_RANDOM; break;
case 'S': c->flags |= REDIS_CMD_SORT_FOR_SCRIPT; break;
case 'l': c->flags |= REDIS_CMD_LOADING; break;
case 't': c->flags |= REDIS_CMD_STALE; break;
case 'M': c->flags |= REDIS_CMD_SKIP_MONITOR; break;
default: redisPanic("Unsupported command flag"); break;
}
f++;
}

//表示根据每个成员的第4个参数的值来确定当前成员的第5个成员的值,这个没什么好说的。

再看下面两行代码:

retval1 = dictAdd(server.commands, sdsnew(c->name), c);

retval2 = dictAdd(server.orig_commands, sdsnew(c->name), c);

可以看到2个函数都是一样的,只是参数不同,一个是server.commands,一个是server.orig_commands.

现在来分析下dictAdd函数的实现原理即可。

这里偷懒一下,我发现网上已经有个现成的讲解文章。

传送门: http://www.kuqin.com/database/20110904/264306.html

然后我的理解就是把它当做是一个命令的哈希表,存了2份而已。

然后后面肯定某个地方会通过哈希表找到这个命令。

思考:跟之前数组的方式有什么区别?

数组是顺序查找,哈希表是哈希查找,降低了一个数量级。比较快。

这里是为了提高效率,不用过于研究细节,不影响对整体的把握,具体请看传送门即可。

~~~

好,继续往下看

server.delCommand = lookupCommandByCString("del");
//redisCommandTable[7];

server.multiCommand = lookupCommandByCString("multi");
//redisCommandTable[7];

server.lpushCommand = lookupCommandByCString("lpush");
//redisCommandTable[18];

server.lpopCommand = lookupCommandByCString("lpop");
//redisCommandTable[23];

server.rpopCommand = lookupCommandByCString("rpop");
//redisCommandTable[22];

server.slowlog_log_slower_than = REDIS_SLOWLOG_LOG_SLOWER_THAN;
//设置为 10000

server.slowlog_max_len = REDIS_SLOWLOG_MAX_LEN;
//设置为 10000

/* Debugging */
server.assert_failed = "<no assertion failed>";
//设置为 10000

server.assert_file = "<no file>";
//设置为 10000

server.assert_line = 0;
//设置为 0

server.bug_report_start = 0;
// 0

server.watchdog_period = 0;
//设置为 0

到快到12点的时候,终于把这个函数给搞定了,累啊。

码农的春天什么时候到来?

休息片刻,继续往下执行!!!

不努力能赚钱付按揭吗,不能!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息