First, the knowledge that needs to know beforehand
1, each database in the Redis, is stored by a REDISDB structure. Where Redisdb.id stores the number represented by the Redis database as an integer. Redisdb.dict stores all of the key-value pairs of the library data. Redisdb.expires holds the expiration time for each key.
2. When the Redis server initializes, 16 databases are allocated in advance (the number can be configured by configuration file), and all databases are saved to a member Redisserver.db array in the structure redisserver. When we choose the database select number, the program switches the database directly through Redisserver.db[number]. Sometimes when a program needs to know which database it is in, read the redisdb.id directly.
3. Now that we know that all the key values of a database are stored in redisdb.dict, we need to know the structure of the dict if we find the location of the key:
Copy Code code as follows:
typedef struct DICT {
Type-specific handler functions
Dicttype *type;
Private data for type-handling functions
void *privdata;
Hash Table (2)
Dictht ht[2];
A flag that records rehash progress, with a value of-1 indicating that rehash was not
int rehashidx;
Number of security iterators currently in operation
int iterators;
} dict;
As can be seen from the above structure, Redis's dictionary uses a hash table as its underlying implementation. The Dict type uses two pointers to the hash table, the No. 0 hash table (Ht[0]) is mainly used to store all the key values of the database, while the 1th hash table is mainly used for the rehash of the No. 0 hash table, rehash is usually triggered when adding new values, not too much to repeat here. So looking for a key in the Redis is actually a lookup operation on the ht[0] in the DICT structure.
4, since it is a hash, then we know there will be a hash collision, then when multiple key hashes for the same value how to do? Redis takes a linked list to store keys for multiple hash collisions. That is, when the list is found based on the hash value of the key, if the length of the list is greater than 1, then we need to walk through the linked list to find the key we are looking for. Of course, in general, the length of the linked list is 1, so the time complexity can be regarded as O (1).
Second, when Redis get a key, if found the location of the key.
With this knowledge, we can analyze Redis if a key is found in memory.
1, when you get a key, Redis first to determine whether the current library of the No. 0 hash table is empty, that is: if (dict->ht[0].size = = 0). Returns null directly if True.
2, to determine whether the No. 0 hash table needs rehash, because if the rehash, then two of the table may store the key. If rehash is in progress, a _dictrehashstep method is invoked, _dictrehashstep used to passively rehash the database dictionary and hashing dictionary, without repeating.
3, the calculation of hash table, according to the current dictionary and key for the calculation of the hash value.
4. Calculates the index value of the hash table based on the hash value and the current dictionary.
5, according to the index value in the hash table out of the list, traversing the list to find the key location. Generally, the length of the linked list is 1.
6, when Ht[0] after the search, and then the second rehash judgment, if not in rehashing, then directly end, otherwise ht[1] repeat 345 steps.
That's where we found the key in the middle of memory.