解析
sdshdr8
#pragma pack(1)
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[];
};
1字节对齐,sdshdr8结构体有3个字节,即sizeof(sdshdr8) = 3。
zmalloc
Malloc一块内存时_mptr,前sizeof(size_t)字节,存储开辟内存的大小,从开辟内存_mptr + sizeof(size_t)为用户提供的数据空间。
zfree
对于 zmalloc开辟的一块数据 _fptr,释放时需要获取内存的首地址,即_fptr - sizeof(size_t)。
sdshdr结构体与robj结构体结合使用
int len = 5;
const char* ptr = "hello";
robj* o = (robj*)zmalloc(sizeof(robj) + sizeof(struct sdshdr8) + len + 1);
struct sdshdr8* sh = (sdshdr8*)(o + 1);
o->type = 0;
o->encoding = 8;
o->ptr = sh +1;
o->refcount = 1;
sh->len = len;
sh->alloc = len;
sh->flags = 1;
memcpy(sh->buf, ptr, len);
sh->buf[len] = '\0';
sds s = (sds)o->ptr;
size_t slen;
//slen = SDS_HDR(8, s)->len;
slen = ((struct sdshdr8*)((s)-(sizeof(struct sdshdr8))))->len;
zfree(o);
测试源码
#include <iostream>
typedef signed char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long long int64_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
#ifdef HAVE_MALLOC_SIZE
#define PREFIX_SIZE (0)
#else
#if defined(__sun) || defined(__sparc) || defined(__sparc__)
#define PREFIX_SIZE (sizeof(long long))
#else
#define PREFIX_SIZE (sizeof(size_t))
#endif
#endif
#pragma pack(1)
typedef struct _su
{
int32_t val;
double dvalue;
//void* key;
}su;
#define ZIPLIST_BYTES(zl) (*((uint32_t*)(zl)))
#define SDS_TYPE_MASK 7
#ifdef _MSC_VER
#define __attribute__(x)
#endif
typedef char* sds;
#pragma pack(1)
struct __attribute__((__packed__)) sdshdr5 {
unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
char buf[];
};
#pragma pack(1)
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[];
};
#pragma pack(1)
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[];
};
#pragma pack(1)
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[];
};
#pragma pack(1)
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[];
};
#pragma pack(1)
struct __attribute__((__packed__)) sdsdouble {
uint64_t len; /* used */
unsigned char flags; /* 3 lsb of type, 5 unused bits */
char buf[];
};
#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
#define SDS_HDR_VAR(T,s) struct sdshdr##T *sh = (struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T)));
#define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))))
#define SDS_TYPE_5_LEN(f) ((f)>>SDS_TYPE_BITS)
#define GET_INT32_VALUE(_ptr, _offet) (*(int32_t*)_ptr + _offet);
#define GET_DOUBLE_VALUE(val ,_ptr, _offet)\
do \
{\
memcpy((void*)&val, _ptr + _offet, sizeof(double));\
} while (0);\
#define SDS_HDR(T,s) ((struct sdshdr##T *)((s)-(sizeof(struct sdshdr##T))))
//前4个字节,保存长度
void* zmalloc(size_t size) {
void* ptr = malloc(size + PREFIX_SIZE);
*((size_t*)ptr) = size;
return (char*)ptr + PREFIX_SIZE;
}
static inline int sdsHdrSize(char type) {
switch (type & SDS_TYPE_MASK) {
case SDS_TYPE_5:
return sizeof(struct sdshdr5);
case SDS_TYPE_8:
return sizeof(struct sdshdr8);
case SDS_TYPE_16:
return sizeof(struct sdshdr16);
case SDS_TYPE_32:
return sizeof(struct sdshdr32);
case SDS_TYPE_64:
return sizeof(struct sdshdr64);
}
return 0;
}
typedef struct redisObject {
unsigned type : 4;
unsigned encoding : 4;
int refcount;
void* ptr;
} robj;
void sdsfree(sds s) {
if (s == NULL) return;
int n = s[-1] & SDS_TYPE_MASK;
//free((char*)s - sizeof(struct sdshdr8));
free((char*)s - sdsHdrSize(s[-1]));
}
void zfree(void* ptr) {
void* realptr;
realptr = (char*)ptr - PREFIX_SIZE;
free(realptr);
}
int main()
{
std::cout << "Hello World!\n";
/**************************数值数据解析****************************************/
su _s;
_s.val = 2;
_s.dvalue = 0.6666f;
char* _ptr = (char*)malloc(sizeof(su));
memcpy(_ptr, (void*)&_s, sizeof(su));
int32_t _val = (*(int32_t*)_ptr);
_val = GET_INT32_VALUE(_ptr, 0);
double _dval;
GET_DOUBLE_VALUE(_dval, _ptr, sizeof(int32_t));
//memcpy((void*)&_dval, _ptr + sizeof(int32_t),sizeof(double));
// double _dval = (*(double*)_ptr + sizeof(int32_t));
int _len = sizeof(sdsdouble);
/******************************************************************/
/***************************sdshdr8 结构体使用操作***************************************/
int len = 5;
const char* ptr = "hello";
robj* o = (robj*)zmalloc(sizeof(robj) + sizeof(struct sdshdr8) + len + 1);
struct sdshdr8* sh = (sdshdr8*)(o + 1);
o->type = 0;
o->encoding = 8;
o->ptr = sh +1;
o->refcount = 1;
sh->len = len;
sh->alloc = len;
sh->flags = 1;
memcpy(sh->buf, ptr, len);
sh->buf[len] = '\0';
sds s = (sds)o->ptr;
size_t slen;
//slen = SDS_HDR(8, s)->len;
slen = ((struct sdshdr8*)((s)-(sizeof(struct sdshdr8))))->len;
zfree(o);
/******************************************************************/
return 0;
}