Exemple #1
0
int compareStringObjectsWithFlags(robj *a, robj *b, int flags) {
    serverAssertWithInfo(NULL,a,a->type == OBJ_STRING && b->type == OBJ_STRING);
    char bufa[128], bufb[128], *astr, *bstr;
    size_t alen, blen, minlen;

    if (a == b) return 0;
    if (sdsEncodedObject(a)) {
        astr = a->ptr;
        alen = sdslen(astr);
    } else {
        alen = ll2string(bufa,sizeof(bufa),(long) a->ptr);
        astr = bufa;
    }
    if (sdsEncodedObject(b)) {
        bstr = b->ptr;
        blen = sdslen(bstr);
    } else {
        blen = ll2string(bufb,sizeof(bufb),(long) b->ptr);
        bstr = bufb;
    }
    if (flags & REDIS_COMPARE_COLL) {
        return strcoll(astr,bstr);
    } else {
        int cmp;

        minlen = (alen < blen) ? alen : blen;
        cmp = memcmp(astr,bstr,minlen);
        if (cmp == 0) return alen-blen;
        return cmp;
    }
}
Exemple #2
0
int getDoubleFromObject(robj *o, double *target) {
    double value;
    char *eptr;

    if (o == NULL) {
        value = 0;
    } else {
        serverAssertWithInfo(NULL,o,o->type == OBJ_STRING);
        if (sdsEncodedObject(o)) {
            errno = 0;
            value = strtod(o->ptr, &eptr);
            if (isspace(((char*)o->ptr)[0]) ||
                eptr[0] != '\0' ||
                (errno == ERANGE &&
                    (value == HUGE_VAL || value == -HUGE_VAL || value == 0)) ||
                errno == EINVAL ||
                isnan(value))
                return VR_ERROR;
        } else if (o->encoding == OBJ_ENCODING_INT) {
            value = (long)o->ptr;
        } else {
            serverPanic("Unknown string encoding");
        }
    }
    *target = value;
    return VR_OK;
}
/*
 * 尝试从对象中取出 double 值
 *
 *  - 转换成功则将值保存在 *target 中,函数返回 REDIS_OK
 *
 *  - 否则,函数返回 REDIS_ERR
 */
int getDoubleFromObject(robj *o, double *target) {
    double value;
    char *eptr;

    if (o == NULL) {
        value = 0;

    } else {
        redisAssertWithInfo(NULL,o,o->type == REDIS_STRING);

        // 尝试从字符串中转换 double 值
        if (sdsEncodedObject(o)) {
            errno = 0;
            value = strtod(o->ptr, &eptr);
            if (isspace(((char*)o->ptr)[0]) ||
                eptr[0] != '\0' ||
                (errno == ERANGE &&
                    (value == HUGE_VAL || value == -HUGE_VAL || value == 0)) ||
                errno == EINVAL ||
                isnan(value))
                return REDIS_ERR;

        // INT 编码
        } else if (o->encoding == REDIS_ENCODING_INT) {
            value = (long)o->ptr;

        } else {
            redisPanic("Unknown string encoding");
        }
    }

    // 返回值
    *target = value;
    return REDIS_OK;
}
/*
 * 尝试从对象中取出 long double 值
 *
 *  - 转换成功则将值保存在 *target 中,函数返回 REDIS_OK
 *
 *  - 否则,函数返回 REDIS_ERR
 */
int getLongDoubleFromObject(robj *o, long double *target) {
    long double value;
    char *eptr;

    if (o == NULL) {
        value = 0;
    } else {

        redisAssertWithInfo(NULL,o,o->type == REDIS_STRING);

        // RAW 编码,尝试从字符串中转换 long double
        if (sdsEncodedObject(o)) {
            errno = 0;
            value = strtold(o->ptr, &eptr);
            if (isspace(((char*)o->ptr)[0]) || eptr[0] != '\0' ||
                errno == ERANGE || isnan(value))
                return REDIS_ERR;

        // INT 编码,直接保存
        } else if (o->encoding == REDIS_ENCODING_INT) {
            value = (long)o->ptr;

        } else {
            redisPanic("Unknown string encoding");
        }
    }

    *target = value;
    return REDIS_OK;
}
int getLongLongFromObject(robj *o, long long *target) {
    long long value;
    char *eptr;

    if (o == NULL) {
        // o 为 NULL 时,将值设为 0 。
        value = 0;
    } else {

        // 确保对象为 REDIS_STRING 类型
        redisAssertWithInfo(NULL,o,o->type == REDIS_STRING);
        if (sdsEncodedObject(o)) {
            errno = 0;
            // T = O(N)
            value = strtoll(o->ptr, &eptr, 10);
            if (isspace(((char*)o->ptr)[0]) || eptr[0] != '\0' ||
                errno == ERANGE)
                return REDIS_ERR;
        } else if (o->encoding == REDIS_ENCODING_INT) {
            // 对于 REDIS_ENCODING_INT 编码的整数值
            // 直接将它的值保存到 value 中
            value = (long)o->ptr;
        } else {
            redisPanic("Unknown string encoding");
        }
    }

    // 保存值到指针
    if (target) *target = value;

    // 返回结果标识符
    return REDIS_OK;
}
//从对象中将字符串值转换为long double并存储在target中
int getLongDoubleFromObject(robj *o, long double *target) {
    long double value;
    char *eptr;

    if (o == NULL) {    //对象不存在
        value = 0;
    } else {
        serverAssertWithInfo(NULL,o,o->type == OBJ_STRING);

        //如果是字符串编码的两种类型
        if (sdsEncodedObject(o)) {
            errno = 0;
            value = strtold(o->ptr, &eptr); //将字符串转换为long double类型
            if (isspace(((char*)o->ptr)[0]) || eptr[0] != '\0' ||
                errno == ERANGE || isnan(value))    //转换失败返回-1
                return C_ERR;
        } else if (o->encoding == OBJ_ENCODING_INT) {   //整数编码
            value = (long)o->ptr;                       //保存整数值
        } else {
            serverPanic("Unknown string encoding");
        }
    }
    *target = value;        //将值存到传入参数中,返回0成功
    return C_OK;
}
Exemple #7
0
size_t stringObjectLen(robj *o) {
    serverAssertWithInfo(NULL,o,o->type == OBJ_STRING);
    if (sdsEncodedObject(o)) {
        return sdslen(o->ptr);
    } else {
        return sdigits10((long)o->ptr);
    }
}
Exemple #8
0
/* Compare the given object with the entry at the current position. */
int listTypeEqual(listTypeEntry *entry, robj *o) {
    if (entry->li->encoding == OBJ_ENCODING_QUICKLIST) {
        serverAssertWithInfo(NULL,o,sdsEncodedObject(o));
        return quicklistCompare(entry->entry.zi,o->ptr,sdslen(o->ptr));
    } else {
        serverPanic("Unknown list encoding");
    }
}
Exemple #9
0
size_t stringObjectLen(robj *o) {
    assert(o->type == OBJ_STRING);
    if (sdsEncodedObject(o)) {
        return sdslen(o->ptr);
    } else {
        return sdigits10((long)o->ptr);
    }
}
Exemple #10
0
//获取字符串的长度
size_t stringObjectLen(robj *o) {
    redisAssertWithInfo(NULL,o,o->type == REDIS_STRING);
    if (sdsEncodedObject(o)) {
        return sdslen(o->ptr);
    } else {
        char buf[32];
        return ll2string(buf,32,(long)o->ptr);
    }
}
//返回字符串对象的字符串长度
size_t stringObjectLen(robj *o) {
    serverAssertWithInfo(NULL,o,o->type == OBJ_STRING);

    //如果是字符串编码的两种类型
    if (sdsEncodedObject(o)) {
        return sdslen(o->ptr);
    } else {    //如果是整数编码类型
        return sdigits10((long)o->ptr); //计算出整数值的位数返回
    }
}
Exemple #12
0
/* Delegate writing an object to writing a bulk string or bulk long long.
 * This is not placed in rio.c since that adds the redis.h dependency. */
int rioWriteBulkObject(rio *r, robj *obj) {
    /* Avoid using getDecodedObject to help copy-on-write (we are often
     * in a child process when this function is called). */
    if (obj->encoding == REDIS_ENCODING_INT) {
        return rioWriteBulkLongLong(r,(long)obj->ptr);
    } else if (sdsEncodedObject(obj)) {
        return rioWriteBulkString(r,obj->ptr,sdslen(obj->ptr));
    } else {
        redisPanic("Unknown string encoding");
    }
}
Exemple #13
0
/* Compare the given object with the entry at the current position. */
int listTypeEqual(listTypeEntry *entry, robj *o) {
    listTypeIterator *li = entry->li;
    if (li->encoding == REDIS_ENCODING_ZIPLIST) {
        redisAssertWithInfo(NULL,o,sdsEncodedObject(o));
        return ziplistCompare(entry->zi,o->ptr,sdslen(o->ptr));
    } else if (li->encoding == REDIS_ENCODING_LINKEDLIST) {
        return equalStringObjects(o,listNodeValue(entry->ln));
    } else {
        redisPanic("Unknown list encoding");
    }
}
//比较列表类型的entry结构与对象的entry节点的值是否等,相等返回1
int listTypeEqual(listTypeEntry *entry, robj *o) {
    //对列表对象编码为quicklist类型操作
    if (entry->li->encoding == OBJ_ENCODING_QUICKLIST) {
        //确保objptr的编码类型是简单动态字符串类型的RAW或EMBSTR
        serverAssertWithInfo(NULL,o,sdsEncodedObject(o));

        //比较listTypeEntry结构中的entry值和给定的对象的值
        return quicklistCompare(entry->entry.zi,o->ptr,sdslen(o->ptr));
    } else {
        serverPanic("Unknown list encoding");
    }
}
Exemple #15
0
void serverLogObjectDebugInfo(robj *o) {
    serverLog(LL_WARNING,"Object type: %d", o->type);
    serverLog(LL_WARNING,"Object encoding: %d", o->encoding);
    serverLog(LL_WARNING,"Object refcount: %d", o->refcount);
    if (o->type == OBJ_STRING && sdsEncodedObject(o)) {
        serverLog(LL_WARNING,"Object raw string len: %zu", sdslen(o->ptr));
        if (sdslen(o->ptr) < 4096) {
            sds repr = sdscatrepr(sdsempty(),o->ptr,sdslen(o->ptr));
            serverLog(LL_WARNING,"Object raw string content: %s", repr);
            sdsfree(repr);
        }
    }
}
Exemple #16
0
/* Check the length of a number of objects to see if we need to convert a
 * ziplist to a real hash. Note that we only check string encoded objects
 * as their string length can be queried in constant time. */
void hashTypeTryConversion(robj *o, robj **argv, int start, int end) {
    int i;

    if (o->encoding != REDIS_ENCODING_ZIPLIST) return;

    for (i = start; i <= end; i++) {
        if (sdsEncodedObject(argv[i]) &&
            sdslen(argv[i]->ptr) > server.hash_max_ziplist_value)
        {
            hashTypeConvert(o, REDIS_ENCODING_HT);
            break;
        }
    }
}
/*
 * 返回字符串对象中字符串值的长度
 */
size_t stringObjectLen(robj *o) {

    redisAssertWithInfo(NULL,o,o->type == REDIS_STRING);

    if (sdsEncodedObject(o)) {
        return sdslen(o->ptr);

    // INT 编码,计算将这个值转换为字符串要多少字节
    // 相当于返回它的长度
    } else {
        char buf[32];
        return ll2string(buf,32,(long)o->ptr);
    }
}
//根据flags比较两个字符串对象a和b,返回0表示相等,非零表示不相等
int compareStringObjectsWithFlags(robj *a, robj *b, int flags) {
    serverAssertWithInfo(NULL,a,a->type == OBJ_STRING && b->type == OBJ_STRING);
    char bufa[128], bufb[128], *astr, *bstr;
    size_t alen, blen, minlen;

    if (a == b) return 0;   //如果是同一对象直接返回

    //如果是指向字符串值的两种OBJ_ENCODING_EMBSTR或OBJ_ENCODING_RAW的两类对象
    if (sdsEncodedObject(a)) {
        astr = a->ptr;
        alen = sdslen(astr);    //获取字符串的长度
    } else {    //如果是整数类型的OBJ_ENCODING_INT编码
        alen = ll2string(bufa,sizeof(bufa),(long) a->ptr);  //转换为字符串
        astr = bufa;
    }
    //如果是指向字符串值的两种OBJ_ENCODING_EMBSTR或OBJ_ENCODING_RAW的两类对象
    if (sdsEncodedObject(b)) {
        bstr = b->ptr;
        blen = sdslen(bstr);    //获取字符串的长度
    } else {    //如果是整数类型的OBJ_ENCODING_INT编码
        blen = ll2string(bufb,sizeof(bufb),(long) b->ptr);  //转换为字符串
        bstr = bufb;
    }

    //以本地指定的字符次序进行比较
    if (flags & REDIS_COMPARE_COLL) {
        //strcoll()会依环境变量LC_COLLATE所指定的文字排列次序来比较两字符串
        return strcoll(astr,bstr);  //比较a和b的字符串对象,相等返回0
    } else {    //以二进制方式进行比较
        int cmp;

        minlen = (alen < blen) ? alen : blen;
        cmp = memcmp(astr,bstr,minlen);         //相等返回0,否则返回第一个字符串和第二个字符串的长度差
        if (cmp == 0) return alen-blen;
        return cmp;
    }
}
Exemple #19
0
/* Get a decoded version of an encoded object (returned as a new object).
 * If the object is already raw-encoded just increment the ref count. */
robj *getDecodedObject(robj *o) {
    robj *dec;

    if (sdsEncodedObject(o)) {
        return o;
    }
    if (o->type == OBJ_STRING && o->encoding == OBJ_ENCODING_INT) {
        char buf[32];

        ll2string(buf,32,(long)o->ptr);
        dec = createStringObject(buf,strlen(buf));
        return dec;
    } else {
        serverPanic("Unknown encoding type");
    }
}
//将对象是整型的解码为字符串并返回,如果是字符串编码则之间返回输入对象,只需增加引用计数
robj *getDecodedObject(robj *o) {
    robj *dec;

    if (sdsEncodedObject(o)) {  //如果是OBJ_ENCODING_RAW或OBJ_ENCODING_EMBSTR类型的对象
        incrRefCount(o);        //增加应用计数
        return o;
    }
    if (o->type == OBJ_STRING && o->encoding == OBJ_ENCODING_INT) { //如果是整数对象
        char buf[32];

        ll2string(buf,32,(long)o->ptr); //将整数转换为字符串
        dec = createStringObject(buf,strlen(buf));  //创建一个字符串对象
        return dec;
    } else {
        serverPanic("Unknown encoding type");
    }
}
Exemple #21
0
int getLongLongFromObject(robj *o, long long *target) {
    long long value;

    if (o == NULL) {
        value = 0;
    } else {
        serverAssertWithInfo(NULL,o,o->type == OBJ_STRING);
        if (sdsEncodedObject(o)) {
            if (string2ll(o->ptr,sdslen(o->ptr),&value) == 0) return C_ERR;
        } else if (o->encoding == OBJ_ENCODING_INT) {
            value = (long)o->ptr;
        } else {
            serverPanic("Unknown string encoding");
        }
    }
    if (target) *target = value;
    return C_OK;
}
Exemple #22
0
/* Get a decoded version of an encoded object (returned as a new object).
 * If the object is already raw-encoded just increment the ref count. */
robj *getDecodedObject(robj *o) {
    robj *dec;

    if (sdsEncodedObject(o)) {
        incrRefCount(o);
        return o;
    }
    if (o->type == OBJ_STRING && o->encoding == OBJ_ENCODING_INT) {
        char buf[32];

        ll2string(buf,32,(long)o->ptr);
        dec = createStringObject(buf,strlen(buf));
        return dec;
    } else {
        rr_log(RR_LOG_ERROR,"Unknown encoding type");
        return NULL;
    }
}
Exemple #23
0
/// 将STRING类型的obj以string编码返回
robj *getDecodedObject(robj *o) {
    robj *dec;

    /// 已经是RAW编码,直接返回
    if (sdsEncodedObject(o)) {
        incrRefCount(o);
        return o;
    }
    /// 将INT类型编码转为STRING编码并返回新的obj
    if (o->type == REDIS_STRING && o->encoding == REDIS_ENCODING_INT) {
        char buf[32];

        ll2string(buf,32,(long)o->ptr);
        dec = createStringObject(buf,strlen(buf));
        return dec;
    } else {
        redisPanic("Unknown encoding type");
    }
}
/* Get a decoded version of an encoded object (returned as a new object).
 *
 * 以新对象的形式,返回一个输入对象的解码版本(RAW 编码)。
 *
 * If the object is already raw-encoded just increment the ref count. 
 *
 * 如果对象已经是 RAW 编码的,那么对输入对象的引用计数增一,
 * 然后返回输入对象。
 */
robj *getDecodedObject(robj *o) {
    robj *dec;

    if (sdsEncodedObject(o)) {
        incrRefCount(o);
        return o;
    }

    // 解码对象,将对象的值从整数转换为字符串
    if (o->type == REDIS_STRING && o->encoding == REDIS_ENCODING_INT) {
        char buf[32];

        ll2string(buf,32,(long)o->ptr);
        dec = createStringObject(buf,strlen(buf));
        return dec;

    } else {
        redisPanic("Unknown encoding type");
    }
}
//从对象中将字符串值转换为long long并存储在target中
int getLongLongFromObject(robj *o, long long *target) {
    long long value;

    if (o == NULL) {    //对象不存在
        value = 0;
    } else {
        serverAssertWithInfo(NULL,o,o->type == OBJ_STRING);

         //如果是字符串编码的两种类型
        if (sdsEncodedObject(o)) {
             //转换失败发送-1,成功保存值到value中
            if (string2ll(o->ptr,sdslen(o->ptr),&value) == 0) return C_ERR;
        } else if (o->encoding == OBJ_ENCODING_INT) {   //整型编码
            value = (long)o->ptr;                       //保存整数值
        } else {
            serverPanic("Unknown string encoding");
        }
    }
    if (target) *target = value;        //将值存到传入参数中,返回0成功
    return C_OK;
}
Exemple #26
0
/* Create a new slowlog entry.
 * Incrementing the ref count of all the objects retained is up to
 * this function. */
slowlogEntry *slowlogCreateEntry(robj **argv, int argc, long long duration) {
    slowlogEntry *se = zmalloc(sizeof(*se));
    int j, slargc = argc;

    if (slargc > SLOWLOG_ENTRY_MAX_ARGC) slargc = SLOWLOG_ENTRY_MAX_ARGC;
    se->argc = slargc;
    se->argv = zmalloc(sizeof(robj*)*slargc);
    for (j = 0; j < slargc; j++) {
        /* Logging too many arguments is a useless memory waste, so we stop
         * at SLOWLOG_ENTRY_MAX_ARGC, but use the last argument to specify
         * how many remaining arguments there were in the original command. */
        if (slargc != argc && j == slargc-1) {
            se->argv[j] = createObject(OBJ_STRING,
                sdscatprintf(sdsempty(),"... (%d more arguments)",
                argc-slargc+1));
        } else {
            /* Trim too long strings as well... */
            if (argv[j]->type == OBJ_STRING &&
                sdsEncodedObject(argv[j]) &&
                sdslen(argv[j]->ptr) > SLOWLOG_ENTRY_MAX_STRING)
            {
                sds s = sdsnewlen(argv[j]->ptr, SLOWLOG_ENTRY_MAX_STRING);

                s = sdscatprintf(s,"... (%lu more bytes)",
                    (unsigned long)
                    sdslen(argv[j]->ptr) - SLOWLOG_ENTRY_MAX_STRING);
                se->argv[j] = createObject(OBJ_STRING,s);
            } else {
                se->argv[j] = argv[j];
                incrRefCount(argv[j]);
            }
        }
    }
    se->time = time(NULL);
    se->duration = duration;
    se->id = server.slowlog_entry_id++;
    return se;
}
Exemple #27
0
void _prezAssertPrintClientInfo(prezClient *c) {
    int j;

    bugReportStart();
    prezLog(PREZ_WARNING,"=== ASSERTION FAILED CLIENT CONTEXT ===");
    //prezLog(PREZ_WARNING,"client->flags = %d", c->flags);
    prezLog(PREZ_WARNING,"client->fd = %d", c->fd);
    prezLog(PREZ_WARNING,"client->argc = %d", c->argc);
    for (j=0; j < c->argc; j++) {
        char buf[128];
        char *arg;

        if (c->argv[j]->type == PREZ_STRING && sdsEncodedObject(c->argv[j])) {
            arg = (char*) c->argv[j]->ptr;
        } else {
            snprintf(buf,sizeof(buf),"Object type: %d, encoding: %d",
                c->argv[j]->type, c->argv[j]->encoding);
            arg = buf;
        }
        prezLog(PREZ_WARNING,"client->argv[%d] = \"%s\" (refcount: %d)",
            j, arg, c->argv[j]->refcount);
    }
}
Exemple #28
0
void prezLogObjectDebugInfo(robj *o) {
    prezLog(PREZ_WARNING,"Object type: %d", o->type);
    prezLog(PREZ_WARNING,"Object encoding: %d", o->encoding);
    prezLog(PREZ_WARNING,"Object refcount: %d", o->refcount);
    if (o->type == PREZ_STRING && sdsEncodedObject(o)) {
        prezLog(PREZ_WARNING,"Object raw string len: %zu", sdslen(o->ptr));
        if (sdslen(o->ptr) < 4096) {
            sds repr = sdscatrepr(sdsempty(),o->ptr,sdslen(o->ptr));
            prezLog(PREZ_WARNING,"Object raw string content: %s", repr);
            sdsfree(repr);
        }
    } /*else if (o->type == PREZ_LIST) {
        prezLog(PREZ_WARNING,"List length: %d", (int) listTypeLength(o));
    } else if (o->type == PREZ_SET) {
        prezLog(PREZ_WARNING,"Set size: %d", (int) setTypeSize(o));
    } else if (o->type == PREZ_HASH) {
        prezLog(PREZ_WARNING,"Hash size: %d", (int) hashTypeLength(o));
    } else if (o->type == PREZ_ZSET) {
        prezLog(PREZ_WARNING,"Sorted set size: %d", (int) zsetLength(o));
        if (o->encoding == PREZ_ENCODING_SKIPLIST)
            prezLog(PREZ_WARNING,"Skiplist level: %d", (int) ((zset*)o->ptr)->zsl->level);
    } */
}
Exemple #29
0
unsigned int
dictEncObjHash(const void *key) {
    robj *o = (robj*) key;

    if (sdsEncodedObject(o)) {
        return dictGenHashFunction(o->ptr, sdslen((sds)o->ptr));
    } else {
        if (o->encoding == OBJ_ENCODING_INT) {
            char buf[32];
            int len;

            len = ll2string(buf,32,(long)o->ptr);
            return dictGenHashFunction((unsigned char*)buf, len);
        } else {
            unsigned int hash;

            o = getDecodedObject(o);
            hash = dictGenHashFunction(o->ptr, sdslen((sds)o->ptr));
            decrRefCount(o);
            return hash;
        }
    }
}
Exemple #30
0
int getLongLongFromObject(robj *o, long long *target) {
    long long value;
    char *eptr;

    if (o == NULL) {
        value = 0;
    } else {
        redisAssertWithInfo(NULL,o,o->type == REDIS_STRING);
        if (sdsEncodedObject(o)) {
            errno = 0;
            value = strtoll(o->ptr, &eptr, 10);
            if (isspace(((char*)o->ptr)[0]) || eptr[0] != '\0' ||
                errno == ERANGE)
                return REDIS_ERR;
        } else if (o->encoding == REDIS_ENCODING_INT) {
            value = (long)o->ptr;
        } else {
            redisPanic("Unknown string encoding");
        }
    }
    if (target) *target = value;
    return REDIS_OK;
}