美文网首页
redis1-sds

redis1-sds

作者: modou1618 | 来源:发表于2019-01-31 16:54 被阅读0次
  • sds用于存储字符串的结构体,

  • 几种不同的存储结构, 类型值如下。

#define SDS_TYPE_5  0
#define SDS_TYPE_8  1
#define SDS_TYPE_16 2
#define SDS_TYPE_32 3
#define SDS_TYPE_64 4
#define SDS_TYPE_MASK 7
#define SDS_TYPE_BITS 3
  • 根据字符串长度分配不同格式的sds结构。
static inline char sdsReqType(size_t string_size) {
    if (string_size < 1<<5)
        return SDS_TYPE_5;
    if (string_size < 1<<8)
        return SDS_TYPE_8;
    if (string_size < 1<<16)
        return SDS_TYPE_16;
#if (LONG_MAX == LLONG_MAX)
    if (string_size < 1ll<<32)
        return SDS_TYPE_32;
    return SDS_TYPE_64;
#else
    return SDS_TYPE_32;
#endif
}
  • 使用存储结构中的flags前3位存储类型信息。
    字符串长度小于32时,使用sdshdr5结构体存储,使用flags后5位存储长度。
    其他几种结构体格式都相同,只是存储长度len和已使用长度alloc的类型不同,可表示的长度对应不同。
struct __attribute__ ((__packed__)) sdshdr5 {
    unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {
    uint8_t len; /* used */
    uint8_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr16 {
    uint16_t len; /* used */
    uint16_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {
    uint32_t len; /* used */
    uint32_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {
    uint64_t len; /* used */
    uint64_t alloc; /* excluding the header and null terminator */
    unsigned char flags; /* 3 lsb of type, 5 unused bits */
    char buf[];
};
  • __attribute__ ((__packed__)) 表示结构体编译时不做对齐优化,使用原始长度存储
  • 分配sds结构体,返回给使用方的是实际存储数据的buf[]的地址。
  • 通过字符串地址查询sds分配的空间长度,通过SDS_HDR(T,s)获取指定类型结果的结构体地址。
    len,alloc的查询和修改都是通过偏移量获取实际地址后修改。
#define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))))
#define SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS)

static inline size_t sdslen(const sds s) {
    unsigned char flags = s[-1];
    switch(flags&SDS_TYPE_MASK) {
        case SDS_TYPE_5:
            return SDS_TYPE_5_LEN(flags);
        case SDS_TYPE_8:
            return SDS_HDR(8,s)->len;
        case SDS_TYPE_16:
            return SDS_HDR(16,s)->len;
        case SDS_TYPE_32:
            return SDS_HDR(32,s)->len;
        case SDS_TYPE_64:
            return SDS_HDR(64,s)->len;
    }
    return 0;
}

相关文章

  • redis1-sds

    sds用于存储字符串的结构体, 几种不同的存储结构, 类型值如下。 根据字符串长度分配不同格式的sds结构。 使用...

网友评论

      本文标题:redis1-sds

      本文链接:https://www.haomeiwen.com/subject/yziksqtx.html