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

经过短暂的休息,开始研究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点的时候,终于把这个函数给搞定了,累啊。

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

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

不努力能赚钱付按揭吗,不能!!!

 

 


 

 

转载于:https://my.oschina.net/qiangzigege/blog/169413

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值