In Redis, The EverythingisObject data structure uses the robj structure to represent all data objects. It can be viewed as a MetaData (MetaData) of various structured data, this object is encapsulated, transmitted, transformed, and encoded, but the object itself is very simple. Its type definition is as follows: 1 typedefstructredisObject {un
Everything is the Object data structure. In Redis, The robj structure is used to represent all data objects. It can be viewed as a MetaData (MetaData) of different types of structured data, this object is encapsulated, transmitted, transformed, and encoded, but the object itself is very simple. Its type definition is as follows: 1 typedef struct redisObject {un
Everything is Object
Data Structure
In Redis, The robj structure is used to represent all data objects. It can be considered as a MetaData (MetaData)
Different types of structured data are encapsulated, transmitted, transformed, and encoded through the object, but the object itself is very simple.
Its type is defined as follows:
1 typedef struct redisObject {unsigned storage: unsigned encoding: unsigned lru: refcount;} robj;
The type field indicates the data type, which has the following definitions:
REDIS_STRING // string
REDIS_LIST // linked list
REDIS_SET // set
REDIS_ZSET // sorted set
REDIS_HASH // HASH structure (Note: This is different from the hash table in the traditional sense (such as stl: hash_map). The HASH here only has the syntax of field hash)
REDIS_VMPOINTER // VM pointer (indicating that data is under VM management)
The encoding field indicates the data encoding method, which has the following definitions:
REDIS_ENCODING_RAW // The original encoding, which is an original string.
REDIS_ENCODING_INT // INT-type encoding, which encodes numeric strings into this format
REDIS_ENCODING_HT // hash table encoding, which is managed in the dict structure in the source code
REDIS_ENCODING_ZIPMAP // streamline the hash structure of the encoding to save memory.
REDIS_ENCODING_LINKEDLIST // bidirectional linked list
REDIS_ENCODING_ZIPLIST // simplified encoded linked list, saving more memory
REDIS_ENCODING_INTSET // a short encoding set, which saves more memory.
REDIS_ENCODING_SKIPLIST //
The refcount field indicates the reference count of the object. Each time a reference is made, the count is incremented by 1. Each time a reference is removed, the count is reduced by 1. If it is reduced to 0, the memory of the object is released.
Procedure
In Redis source code, a large number of robj pointers are passed between functions.
The following describes how to operate robj using redis to process the "set" command.
1. parse the command cache in ProcessInlineBuffer and ProcessMultiBulkBUffer
It is usually separated by spaces. Each character block is encoded as an independent robj object.
Objects are stored in the argc array in the redisClient structure and provided to subsequent functions.
InlineBuffer: corresponds to the Redis single-line command
MultiBulkBuffer: corresponds to multi-line commands
2. ProcessCommand parses the command and then distributes the function.
The processing flow enters the specific command processing function
3. setCommand is the processing function corresponding to the "set" command.
This function is very simple. Website space mainly serves as a command access function.
It will perform an attempted encoding conversion on obj-val. In this example, it will try to convert the val object to an INT type object.
After the conversion is complete, enter the internal sharing Function setGenericCommand processing process
4. setGenericCommand:
Add a kv key-value pair to the namespace corresponding to the connection (that is, a dict structure)
Corresponding to the dict structure, the specific semantics of the insert operation is defined by a global dictType:
1 dictType commandTableDictType = {NULL, NULL, dictSdsKeyCompare, dictSdsDestructor, dictRedisObjectDestructor };
According to the operation definition, after the ratio is executed
Obj-key copies the original string and adds the pointer to dict (the copy operation is implemented in the dbAdd function)
Obj-val directly adds the pointer to dict, and adds the refcount of the object to 1 (the reference operation is implemented in the setKey function)
5. After the entire process is completed, release the argc object array in redisClient.
In this example, the result is:
Obj-key reference count minus 1, and the final value is 0, causing the object to be deleted
Obj-val: The reference count minus 1, and the final value is 1. This object continues to exist in the global key dict table.
Continue to the previous "set" command to give a preliminary understanding of object encoding conversion in redis for further commands.
In, note that in the appendCommand, the value of the obj-val object needs to be changed, causing the obj-val to be decoded from the INT encoding status to the RAW encoding status.
A temporary object obj-decoded is generated during decoding.
Merge a temporary object with obj-append and assign the merged value to obj-val.
Reference counting variables in php
It is a good idea to manage the lifetime of an object by referencing the count. The above two figures show how redis manages the life and death of objects through reference counting.
Similar practices are available in many dynamic languages.
For example, in PHP, variables are represented in the following structure:
1 struct _ zval_struct {zend_uint refcount; zend_uchar type; zend_uchar is_ref ;}; 7 typedef struct _ zval_struct zval;
Value is a pointer of the zvalue_value type.
Zvalue_value is a union structure that integrates different types of data into the same structure.
1 typedef union _ zvalue_value {dval; {5 char * val; 6int len; HashTable * ht; zend_object_value obj;} zvalue_value;
We can see that there are two reference counts for variables in PHP.
1. refcount
2. is_ref: indirect reference count. The number of times that a reference is assigned increases.
These two values exist because the variables in PHP have the concept of reference. The Hong Kong virtual host involves several important principles:
1. zero value copy: When a value is assigned to a variable, a new variable is not copied. Instead, a reference is directly added to the zval structure and the reference count is added to the refcount variable.
However, the assignment of custom class objects is different from that of common variables. By default, a reference is assigned, causing the count to be added to is_ref.
I think this is a messy part of the PHP language design.
2. copy when writing: variable changes will lead to variable separation, resulting in copying a new variable