Redis开源代码读书笔记九(Object模块)

本文深入探讨了Redis中对象的多种类型、编码方式及内存优化策略,详细介绍了对象的基本接口、引用计数操作和创建、复制、解码等关键操作,同时提供了对象的复制、类型检查和值获取方法,以及LRU算法的应用。通过理解这些概念和接口,开发者能够更高效地使用Redis进行数据存储和处理。
摘要由CSDN通过智能技术生成

Object功能特性


==》支持REDIS_STRING、REDIS_LIST、REDIS_SET、REDIS_ZSET、REDIS_HASH对象类型

==》支持对象引用计数

==》支持对象内存优化

==》支持对象比较,复制,获取对象值等操作

==》支持LRU算法


/* Object types */
#define REDIS_STRING 0
#define REDIS_LIST 1
#define REDIS_SET 2
#define REDIS_ZSET 3
#define REDIS_HASH 4


Object类型和编码方式


==》REDIS_STRING, REDIS_ENCODING_EMBSTR
==》REDIS_STRING, REDIS_ENCODING_RAW
==》REDIS_STRING, REDIS_ENCODING_INT
==》REDIS_LIST, REDIS_ENCODING_LINKEDLIST
==》REDIS_LIST, REDIS_ENCODING_ZIPLIST
==》REDIS_SET,  REDIS_ENCODING_HT
==》REDIS_SET,  REDIS_ENCODING_INTSET
==》REDIS_HASH,  REDIS_ENCODING_ZIPLIST
==》REDIS_ZSET,  REDIS_ENCODING_SKIPLIST
==》REDIS_ZSET,  REDIS_ENCODING_ZIPLIST

/* Objects encoding. Some kind of objects like Strings and Hashes can be
 * internally represented in multiple ways. The 'encoding' field of the object
 * is set to one of this fields for this object. */
#define REDIS_ENCODING_RAW 0     /* Raw representation */
#define REDIS_ENCODING_INT 1     /* Encoded as integer */
#define REDIS_ENCODING_HT 2      /* Encoded as hash table */
#define REDIS_ENCODING_ZIPMAP 3  /* Encoded as zipmap */
#define REDIS_ENCODING_LINKEDLIST 4 /* Encoded as regular linked list */
#define REDIS_ENCODING_ZIPLIST 5 /* Encoded as ziplist */
#define REDIS_ENCODING_INTSET 6  /* Encoded as intset */
#define REDIS_ENCODING_SKIPLIST 7  /* Encoded as skiplist */
#define REDIS_ENCODING_EMBSTR 8  /* Embedded sds string encoding */


Object结构体

typedef struct redisObject {
    unsigned type:4;
    unsigned encoding:4;
    unsigned lru:REDIS_LRU_BITS; /* lru time (relative to server.lruclock) */
    int refcount;
    void *ptr;
} robj;

#define sdsEncodedObject(objptr) (objptr->encoding == REDIS_ENCODING_RAW || objptr->encoding == REDIS_ENCODING_EMBSTR)

从上述结构体按位构造的方式看,Redis程序是非常经济的一种对象模型,这也是内存数据库中操作大量对象所必须考虑的。


Object基本接口


5种基本对象内存释放接口

void freeStringObject(robj *o);
void freeListObject(robj *o);
void freeSetObject(robj *o);
void freeZsetObject(robj *o);
void freeHashObject(robj *o);

对象引用计数操作接口


2种不同入参的对象打包接口

void decrRefCount(robj *o);
void decrRefCountVoid(void *o);

增加对象引用计数

void incrRefCount(robj *o);

复位对象引用计数

robj *resetRefCount(robj *obj);

对象创建接口


robj *createObject(int type, void *ptr);
 --> REDIS_ENCODING_RAW, type
 
robj *createStringObject(char *ptr, size_t len);
 --> <REDIS_ENCODING_EMBSTR_SIZE_LIMIT> createEmbeddedStringObject
  --> REDIS_ENCODING_EMBSTR, REDIS_STRING
 --> <!REDIS_ENCODING_EMBSTR_SIZE_LIMIT> createRawStringObject
  --> REDIS_ENCODING_RAW, REDIS_STRING
 
robj *createRawStringObject(char *ptr, size_t len);
 --> REDIS_ENCODING_RAW, REDIS_STRING
 
robj *createEmbeddedStringObject(char *ptr, size_t len);
 --> REDIS_ENCODING_EMBSTR, REDIS_STRING

robj *createStringObjectFromLongLong(long long value);
 --> <0, REDIS_SHARED_INTEGERS> use shared.integers[]; REDIS_ENCODING_INT, REDIS_STRING
 --> <LONG_MIN, LONG_MAX> createObject, REDIS_ENCODING_INT, REDIS_STRING
 --> <LONG LONG> createObject,REDIS_ENCODING_RAW, REDIS_STRING

robj *createStringObjectFromLongDouble(long double value, int humanfriendly);
 --> createStringObject
  --> <REDIS_ENCODING_EMBSTR_SIZE_LIMIT> createEmbeddedStringObject
   --> REDIS_ENCODING_EMBSTR, REDIS_STRING
  --> <!REDIS_ENCODING_EMBSTR_SIZE_LIMIT> createRawStringObject
   --> REDIS_ENCODING_RAW, REDIS_STRING

robj *createListObject(void);
 --> listCreate
 --> createObject(REDIS_LIST, ...)
 --> REDIS_ENCODING_LINKEDLIST
 --> listSetFreeMethod(l,decrRefCountVoid)

robj *createZiplistObject(void);
 --> ziplistNew
 --> createObject(REDIS_LIST, ...)
 --> REDIS_ENCODING_ZIPLIST

robj *createSetObject(void);
 --> dictCreate
 --> createObject(REDIS_SET, ...)
 --> REDIS_ENCODING_HT

robj *createIntsetObject(void);
 --> intsetNew
 --> createObject(REDIS_SET, ...)
 --> REDIS_ENCODING_INTSET

robj *createHashObject(void);
 --> ziplistNew
 --> createObject(REDIS_HASH, ...)
 --> REDIS_ENCODING_ZIPLIST

robj *createZsetObject(void);
 --> dictCreate
 --> zslCreate
 --> createObject(REDIS_ZSET, ...)
 --> REDIS_ENCODING_SKIPLIST

robj *createZsetZiplistObject(void);
 --> ziplistNew
 --> createObject(REDIS_ZSET,...)
 --> REDIS_ENCODING_ZIPLIST
 


对象操作接口


复制字符串对象
robj *dupStringObject(robj *o);

判断robj是否是longlong对象,并反馈value
int isObjectRepresentableAsLongLong(robj *o, long long *llongval);

判断对象是否可以压缩空间,如果无法节省空间返回原对象
robj *tryObjectEncoding(robj *o);

对robj进行解码,如果无法解码则增加引用计数后返回
robj *getDecodedObject(robj *o);

获取当前对象长度
size_t stringObjectLen(robj *o);

获取longlong值
int getLongLongFromObject(robj *o, long long *target);

获取longdouble值
int getLongDoubleFromObject(robj *o, long double *target);

翻译编码方式
char *strEncoding(int encoding);

二进制方式比较两个字符串对象
int compareStringObjects(robj *a, robj *b);
 --> compareStringObjectsWithFlags(a,b,REDIS_COMPARE_BINARY)

采用目前区域的字符排列次序来比较字符串
int collateStringObjects(robj *a, robj *b);
 --> compareStringObjectsWithFlags(a,b,REDIS_COMPARE_COLL)

字符串对象对比,对compareStringObjects进行优化

int equalStringObjects(robj *a, robj *b);


获取LRU clock,用于LRU算法

unsigned long long estimateObjectIdleTime(robj *o);



redis客户端连接操作(略)


int checkType(redisClient *c, robj *o, int type);

int getLongFromObjectOrReply(redisClient *c, robj *o, long *target, const char *msg);

int getLongLongFromObjectOrReply(redisClient *c, robj *o, long long *target, const char *msg);

int getDoubleFromObjectOrReply(redisClient *c, robj *o, double *target, const char *msg);

int getLongDoubleFromObjectOrReply(redisClient *c, robj *o, long double *target, const char *msg);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值