Data structure of MySQL source code interpretation - LF_HASH
MySQL implements a Lock Free hash structure called LF in the code_ Hash. Metadata_Lock depends on it. LF_ Hash has the following characteristics:
1. Dynamic expansion:
The number of buckets during initialization is 1 Each bucket has one element on average. Therefore, when the total number of elements exceeds the number of buckets, it will be automatically split. Double the number of buckets per split
2,Lock Free
lf_hash is implemented in Lock Free mode to ensure the safety of multithreading operation. lf_hash implements something called pin to ensure the security of multithreaded operation. lf_ All hash operations need to be protected by pins. So lf_hash provides functions to get and release pins. lf_hash maintains a dynamic array of pins.
3. Memory management
lf_ The memory of the hash element is lf_hash allocation and management. The user's data needs to be copied to LF_ In the element created by hash.
LF_ Basic structure of hash
lf_ The basic structure of hash has the following characteristics: all elements are maintained in a global sorting linked list, and all elements of the same bucket are arranged together. As shown in the figure below:
Element management
lf_ The element of the hash uses a continuous memory, which contains two parts of information:
- LF_SLIST linked list and hash related information
- User data is placed in LF_ After slist.
LF_SLIST
struct LF_SLIST { std::atomic<LF_SLIST *> link; /* a pointer to the next element in a listand a flag */ uint32 hashnr; /* reversed hash number, for sorting */ const uchar *key; size_t keylen; /* data is stored here, directly after the keylen. thus the pointer to data is (void*)(slist_element_ptr+1) */ };
- link: points to the next element in the linked list
- Hashnr: reverse value of hash
- Key: the pointer points to the key value
- keylen: the length of the key
LF_HASH
struct LF_HASH { LF_DYNARRAY array; /* hash itself */ LF_ALLOCATOR alloc; /* allocator for elements */ hash_get_key_function get_key; /* see HASH */ CHARSET_INFO *charset; /* see HASH */ lf_hash_func *hash_function; /* see HASH */ uint key_offset, key_length; /* see HASH */ uint element_size; /* size of memcpy'ed area on insert */ uint flags; /* LF_HASH_UNIQUE, etc */ std::atomic<int32> size; /* size of array */ std::atomic<int32> count; /* number of elements in the hash */ /** "Initialize" hook - called to finish initialization of object provided by LF_ALLOCATOR (which is pointed by "dst" parameter) and set element key from object passed as parameter to lf_hash_insert (pointed by "src" parameter). Allows to use LF_HASH with objects which are not "trivially copyable". NULL value means that element initialization is carried out by copying first element_size bytes from object which provided as parameter to lf_hash_insert. */ lf_hash_init_func *initialize; };
Array = dynamic array. All elements of hash are stored in the dynamic array.
alloc memory allocator, which requests memory space for hash elements
get_key , used to retrieve from LF_ Extract the key and key length from user data in hash
charset - the character set used to calculate the hash value
hash_function function to calculate hash value
key_offset = the offset of the key after the user data to the hash
key_length - the length of the key after the hash
element_size size of user data
flags
Size - the size of the array (the number of bucket s)
count counts the number of elements in the hash table
Initialize is used to initialize an object. When the incoming user data is not replicable, you can pass in the initialization function for initialization. When initialize is null, the user data will be copied (memcopy).
CURSOR
typedef struct { std::atomic<LF_SLIST *> *prev; LF_SLIST *curr, *next; } CURSOR;
Function introduction:
1,lf_hash_init2 initialize lf_hash.
2,LF_HASH_ Destroy LF_HASH,. .
3,lf_hash_insert inserts a new element into the hash table. It will copy the hashed user data instead of a pointer to the user data. Return value 0 failed to insert into memory 1, unique key conflict - 1 memory overflow
4,hash_key returns the pointer of the hash key and obtains the length of the hash key.
5,calc_hash} calculate hash value