reids源码-=>常用基类的函数

在netwoking  网络模块,redis服务端响应给客户端


/* -----------------------------------------------------------------------------
 * Higher level functions to queue data on the client output buffer.
 * The following functions are the ones that commands implementations will call.
 * -------------------------------------------------------------------------- */

void addReply(redisClient *c, robj *obj) {
    if (prepareClientToWrite(c) != REDIS_OK) return;

    /* This is an important place where we can avoid copy-on-write
     * when there is a saving child running, avoiding touching the
     * refcount field of the object if it's not needed.
     *
     * If the encoding is RAW and there is room in the static buffer
     * we'll be able to send the object to the client without
     * messing with its page. */
    if (sdsEncodedObject(obj)) {
        if (_addReplyToBuffer(c,obj->ptr,sdslen(obj->ptr)) != REDIS_OK)
            _addReplyObjectToList(c,obj);
    } else if (obj->encoding == REDIS_ENCODING_INT) {
        /* Optimization: if there is room in the static buffer for 32 bytes
         * (more than the max chars a 64 bit integer can take as string) we
         * avoid decoding the object and go for the lower level approach. */
        if (listLength(c->reply) == 0 && (sizeof(c->buf) - c->bufpos) >= 32) {
            char buf[32];
            int len;

            len = ll2string(buf,sizeof(buf),(long)obj->ptr);
            if (_addReplyToBuffer(c,buf,len) == REDIS_OK)
                return;
            /* else... continue with the normal code path, but should never
             * happen actually since we verified there is room. */
        }
        obj = getDecodedObject(obj);
        if (_addReplyToBuffer(c,obj->ptr,sdslen(obj->ptr)) != REDIS_OK)
            _addReplyObjectToList(c,obj);
        decrRefCount(obj);
    } else {
        redisPanic("Wrong obj->encoding in addReply()");
    }
}

在db.c的文件

/* High level Set operation. This function can be used in order to set
 * a key, whatever it was existing or not, to a new object.
 *
 * 1) The ref count of the value object is incremented.
 * 2) clients WATCHing for the destination key notified.
 * 3) The expire time of the key is reset (the key is made persistent). */
void setKey(redisDb *db, robj *key, robj *val) {
    if (lookupKeyWrite(db,key) == NULL) {
        dbAdd(db,key,val);
    } else {
        dbOverwrite(db,key,val);
    }
    incrRefCount(val);
    removeExpire(db,key);
    signalModifiedKey(db,key);
}

/*

* 为执行写入操作而取出键 key 在数据库 db 中的值。

* 和 lookupKeyRead 不同,这个函数不会更新服务器的命中/不命中信息。*

* 找到时返回值对象,没找到返回 NULL 。

*/

robj *lookupKeyWrite(redisDb *db, robj *key) {
    expireIfNeeded(db,key); // 删除过期键
    return lookupKey(db,key);// 查找并返回 key 的值对象
}
int expireIfNeeded(redisDb *db, robj *key) {
    mstime_t when = getExpire(db,key);// 取出键的过期时间
    mstime_t now;
// 没有过期时间
    if (when < 0) return 0; /* No expire for this key */

// 如果服务器正在进行载入,那么不进行任何过期检查
    /* Don't expire anything while loading. It will be done later. */
    if (server.loading) return 0;

    /* If we are in the context of a Lua script, we claim that time is
     * blocked to when the Lua script started. This way a key can expire
     * only the first time it is accessed and not in the middle of the
     * script execution, making propagation to slaves / AOF consistent.
     * See issue #1525 on Github for more information. */
    now = server.lua_caller ? server.lua_time_start : mstime();


当服务器运行在 replication 模式时   附属节点并不主动删除 key 它只返回一个逻辑上正确的返回值 真正的删除操作要等待主节点发来删除命令时才执行 从而保证数据的同步
    /* If we are running in the context of a slave, return ASAP:
     * the slave key expiration is controlled by the master that will
     * send us synthesized DEL operations for expired keys.
     *
     * Still we try to return the right information to the caller,
     * that is, 0 if we think the key should be still valid, 1 if
     * we think the key is expired at this time. */
    if (server.masterhost != NULL) return now > when;

// 运行到这里,表示键带有过期时间,并且服务器为主节点

    /* Return when this key has not expired */
    if (now <= when) return 0; // 如果未过期,返回 0

    /* Delete the key */
    server.stat_expiredkeys++;   //redis server 结构体 /* Number of expired keys */
    propagateExpire(db,key);
    notifyKeyspaceEvent(REDIS_NOTIFY_EXPIRED,
        "expired",key,db->id);
    return dbDelete(db,key);
}

猜你喜欢

转载自blog.csdn.net/weixin_36224759/article/details/81636808