Redis中关于sdshdr8 结构体的理解和使用

解析

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;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值