--- redis dynamic strings, lists, dictionaries (data structure)

SDS

Redis construct a simple dynamic strings, simple dynamic string, SDS, is used as the default string.

structure:

struct sdshdr{

// record the number of buf byte array has been used; int len

int free; // buf array unused number of bytes

char bug []; // byte array, for storing a string

}

The difference between the SDS and strings C

1: Get string length complexity

C language acquired by traversing the length of the string, SDS len field have specialized FIG. Are both time complexity is O (n), O (1)

2: to prevent buffer overflow

Dynamic modification of memory, check the required space is not enough memory to be expanded =

3: the number of memory reallocation when brought reduced modify the string

And pre-allocated space by an inert space releasing two methods

4: binary coding safer

 

List

List of nodes provides efficient rearrangement capability, and sequential access mode node, and the length of the list may be adjusted by adding, deleting nodes. Publish and subscribe, slow queries, the monitor also have used the list, and Redis server also uses the list to save the client state information, and use the client list to build the output buffer.

List node structure:

typedef struct listNode{

// front node

struct listNode * prev;

// rear node

struct listNode * next;

// node value

void * value;

} listNode;

The list structure:

typedef struct list{

// header node

listNode * head;

// footer node

listNode * tail;

// number of nodes included in the list

unsigned long len;

// node value copy function - copy the saved list node value

void * (* after) (void * ptr);

// node value release function - the release of stored value

void *(*free)(void *ptr);

// the value of the contrast function node - node list stored value and the other comparison input values ​​are equal

int (*match)(void *ptr,void *key);

}list;

List implementation characteristics:

1: double-ended: prev and next list node having a pointer, acquires front or rear of the complexity of the node is a node O (1)

2: Acyclic: next prev pointer table pointer and the tail node header node point NULL, NULL access to the list as the end point

3: Table band table pointer and a tail pointer: list structure by the pointer and the tail pointer head, the complexity of obtaining the header node and tail node table is O (1)

4: chain length counter with: len list attribute structure using the list node list held counts. Get the number of nodes complexity is O (1)

5: Polymorphism, list node using the node value stored by dup list structure, free, match node type value specified function, so the list can be used to hold a variety of different types of values

 

dictionary

Dictionary implemented as the underlying hash table, a hash table which may have a plurality of hash tables of nodes, each node only has a dictionary key pair.

Dictionary structure:

typedef struct dict {

// dictType structure is a pointer to the stored operation key set for a particular type of dictionaries of different functions.

dictType * type;

// private data

void * privdata;

// hash table

dictht ht[2];

When // rehash indexes, not in progress, a value of -1

int trehashind;

}

 

Hash table structure:

typedef struct dictht{

// hash table array

** dictEntry table;

// hash table size

unsigned long size;

// size of the hash mask table for calculating the index value is always equal to the size-1

unsigned long sizemask;

// number of nodes in the hash table has been held

Dictht};

 

Hash table node structure:

typedef struct dictEntry {

//key

void * key;

//value

union {

void * val; - Pointer

unit64_t u64; - type value

int64_t s64; - type value

} V;

// hash table points to the next node, forming a linked list. You can use the same key multiple hash values ​​to issues connected together to resolve the key conflict.

struct dictEntry * next;

DictEntry};

 

Structure type specific functions

typedef struct dictType{

// function to calculate a hash value

unsigned int (* hashFunction) (const void * key);

// copy function keys

void *(*keyDup) (void *privdata, const void*key);

// function to copy values

void *(valDup) (void * privdata, const void * obj);

// function ratio

int (*keyCompare) (void * privdata,const void*key1, const void*key2);

// destructor key

void (*keyDestructor) (void *privdata, void *key);

// destructor value

void (*valDestructor) (void *privdata, void *obj);

}

 

Hash Algorithm

When the key-value pairs to be added to the dictionary when the first key according to the calculated hash value and the index value, and then according to the index value, the hash table array containing the node hash table index into the named key-value pairs.

The method of calculating the hash value of the key, Redis hash value is calculated using the algorithm MurmurHash2

hash = dict->type->hashFunction(key);

Key index value calculation method

index = hash & dict->ht[x].sizemask;

 

Key Conflict

Redis hash table using an address chain key method to resolve the conflict, each node has a hash table next pointer, a plurality of one-way hash table nodes may be constituted by the next pointer linked list, it is assigned to the same multi-index nodes can use this one-way linked list. Since no nodes list dictEntry tail pointer linked list, so in order to speed, always add new nodes to the position in the list header, the complexity is O (1).

 

rehash (rehash)

When the stored hash table keys to too much or too little amount of time, in order to allow the load due to the (load factor) at a reasonable range, the size of the hash table need on the line expanded or contracted.

1: a dictionary HT [1] hash table allocates space: extended operation, the HT [1] a magnitude greater than or equal to the first power ht n [0] .used * 2 2. Shrinking operation, then the size of ht [1] is greater than or equal to the first ht [0] .used the n-th power of 2

2: ht all keys stored in the [0] to rehash re-compute the hash value and the index (and the key-value pair into ht [. 1] hash table specified position.

3: When ht [0] all the key-value pairs are migrated to ht [1] After the release of ht [0], the ht [1] is set to ht [0], and ht [1] to create a new blank Kazakhstan Greek table.

Load factor of the formula: load factor = ht [0] .used / ht [0] .size;

 

Progressive rehash

In order to avoid the impact on server performance rehash, in multiple servers, the progressive ht [0] key on the inside to slowly rehash ht [1].

1: To ht [1] allocate space for the dictionary also holds ht [0] and ht [1] two hash tables

2: maintaining an index in the dictionary counter variable rehashidx, is set to 0, it indicates the start rehash

3: During rehash, each time the dictionary to execute the operation and, incidentally, the ht [0] on rehashidx hash table index to all key-value pairs rehash ht [1], rehash after work is completed, the properties rehashidx value by 1;

4: With the implementation of dictionary operations, and ultimately all the keys of the city to rehash ht [1]. This is the value rehashidx property is set to -1, which means complete.

In the meantime, the dictionary to add new key-value pairs to save ht [1] in all, delete, search, update operations will be carried out on two hash tables.

 

 

 

 

Published 50 original articles · won praise 2 · Views 2296

Guess you like

Origin blog.csdn.net/eafun_888/article/details/104714510