Open address lock-free hash table maintenance method and system based on random atomic protection
By adopting lock-free operation and Epoch method in the open address hash table, the concurrency efficiency problem of Cuckoo hash table in multi-core environment is solved, efficient multi-core processing and memory security release are achieved, and the overall performance of the system is improved.
Patent Information
- Application Number
- CN202310458077.2
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- Filing Date
- 2023-04-25
- Publication Date
- 2025-10-17
- Estimated Expiration
- 2043-04-25
AI Technical Summary
Existing open address hash tables have difficulty achieving efficient lock-free concurrent operations in a multi-core processor environment. Especially in the Cuckoo hash structure, the overhead and conflict problems caused by the locking mechanism affect the efficiency of multi-core processors.
A lock-free operation method is adopted, two different hash functions are used to calculate bucket positions, and atomic instructions and memory reclaimers are combined to achieve lock-free concurrency control of query, update, delete and add operations. The random atomic protection mechanism is used to reduce conflicts between threads, and the Epoch method is introduced to ensure the thread safety of memory release.
In a multi-core environment, the concurrent processing efficiency of the hash table is improved, the pointer protection conflicts between threads are reduced, the overall throughput of the system is improved, and the safe release of memory and the efficiency of operations are ensured.
Smart Images

Figure CN116644064B_ABST
Abstract
Description
TECHNICAL FIELD
[0001] The present application aims at a set of practical concurrent control methods for open address hash table, to significantly improve the multi-core processing efficiency of open address hash table based on lock-free concurrent control under the premise of ensuring the worst complexity of open address hash table as O(1) through lock-free method; the invention patent gives a set of high-concurrency multi-thread twin bucket sharing method for general open address hash table-Cuckoo hashing, which is suitable for general open address hash table of multiple slots, to safely protect the data validity of element kicking out process in twin bucket and the efficiency of slot use in a lock-free manner; a safe and reliable memory release protection mechanism is introduced, and a lock-free open hash memory KeyValue storage system with high efficiency and reliability is given, which can effectively improve the problem of insufficient concurrent acceleration ability of existing open address storage system based on lock mechanism in multi-core environment. BACKGROUND
[0002] As an efficient random access structure of memory data, hash table is widely used in computer data-intensive applications, such as operating system kernel data management, file system object fast positioning, database memory storage, computer network packet exchange, Internet activity information maintenance and data security password exchange, etc. Hash table usually contains a hash bucket array for indexing object position and a hash function (or a group of hash functions) for random hashing. The basic structure of the stored data includes a key (Key) for uniquely identifying a certain data object and an object entity (Value). As a random access data structure, hash table operations include insert, delete, modify and point query (Lookup / Find). These operations all need to give the key of the object to be defined. The processing flow of hash table is to first convert the request key based on the predefined hash function into a fixed-length identification code, and then locate it in the bucket through the identification code, and access the object in memory based on the pointer in the bucket. Since the hash function cannot uniformly map the key space to the bucket index, one of the difficulties of hash table processing is that some elements in the bucket cannot be indexed directly through the bucket pointer, i.e. the address conflict problem. The general approach is to maintain a linked list structure for each bucket, and index any number of bucket elements in the form of a linked list (or dynamic array). This approach is simple and practical, but has the problem of high overhead of linked list access or dynamic array maintenance. In practical applications, open address space hash table is widely used, and this method only maintains objects (or their pointers) in the bucket, and ensures the efficiency of bucket element access through the predefined hash function detection order.
[0003] The commonly used open address hash strategies are: 1) linear probing (Linear Probing) hash method: when the bucket mapped by the newly inserted Key is occupied, the next nearest bucket is found in sequence to perform insertion; when querying, scanning starts from the mapped bucket until the given Key or an empty bucket position is found; 2) quadratic probing (Quadratic Probing) hash method: when the bucket mapped by the newly inserted Key is occupied, the next empty bucket is found at a quadratic interval (such as interval 1 2 , 2 2 , 3 2 , 4 2 , …, k 2 ) to perform insertion; when querying, the Key or empty bucket is found in the same order to return; 3) doubling probing (Doubling Probing) hash method: define two hash functions, calculate the position of the target bucket based on the combination of the two hash functions, and find the empty bucket to complete the insertion; when querying, the same strategy is used to find the required Key; 4) Hopscotch Hash hash: by defining a maximum width H, it is guaranteed that each object is maintained within its subsequent H buckets; if the subsequent H buckets have no free positions, then a certain strategy is used to free up positions (by kicking out the object to a certain empty bucket in its subsequent H) ; when querying, the worst time complexity of the Hopscotch Hash method is H; 5) Robin hood hash: similar to twin hash, but by comparing the current object probing times and the object probing times to decide which object to kick out, this method can use bidirectional probing to reduce the time complexity of kicking out and querying; 6) twin (2-choice) hash: by defining two hash functions, the object is stored in the bucket with fewer elements; when querying, the given Key is found in both buckets; 7) Cuckoo hash: multiple hash functions (usually two) are used, the first hash position is calculated first, if the position is occupied, the second position is enabled; if both positions are occupied by other elements, one of them (usually the object in the first position) is selected to kick out to make room for the new object; when querying, as long as the given Key is maintained in one of the buckets, it is returned, otherwise it needs to be searched in the second bucket. Cuckoo hash has the characteristics of high bucket utilization and low time complexity of kicking out and querying, and is widely used. The core of the patent given in this patent is the bucket object lock-free kicking out strategy, which can be applied to general open address hash tables that need to kick out objects.
[0004] Modern computers are limited by the development of CPU frequency, and generally use multi-core architecture, which means that shared data structures should consider more concurrent performance; at the same time, the speed difference between main memory and CPU cache requires core data structures to access memory as little as possible. Years of evolution of Cuckoo Hash structure makes each bucket generally contain a slot array with an adaptive cache cascade width (usually 256 bits on 64-bit computers), and each slot points to a Key corresponding value storage location. Considering that 64-bit computers (32-bit or other special architectures with similar address space design) use 48-bit as the address space, the high 16 bits of each address in the slot array can be used to store the Tag information of a Key, to ensure that based on the high 16 bits of the address in the slot, most of the Keys that do not meet the conditions can be efficiently filtered (with a 1 / 2 16
[0005] In summary, open address hash table has the worst constant time access complexity and efficient bucket utilization, and is widely used. In order to achieve efficient bucket utilization, some objects need to be kicked out between different hash functions in a certain strategy, and the kicking out process is a great challenge for lock-free access. At present, there is no lock-free processing method in academia and industry that can efficiently support multi-thread concurrent processing on multi-slot Cuckoo Hash table. This patent is aimed at open address hash table, and gives three groups of core algorithms to improve the efficiency of multi-core concurrent processing in big data environment: 1) read-write lock-free operation can support efficient Key-Value concurrent operation by using Tag filtering; 2) lock-free kicking out core algorithm ensures thread safety of update and query in the kicking out process; 3) thread-safe memory recycling algorithm uses Epoch method to guarantee the thread safety of object release. Based on these optimization strategies and algorithms, the patent gives a set of open address hash lock-free processing system. SUMMARY
[0006] The application patent provides a set of thread-safe lock-free access control methods for open address hash tables under a multi-core architecture, and gives a method for eliminating redundant storage and thread data safety recycling in combination with Cuckoo hash tables. The method can support open address space storage systems. The patent gives a lock-free optimization core method of the storage system, and gives general data structure and algorithm description in combination with key processing procedures. The application patent first takes the general data structure of Cuckoo hash as an example, gives the top-level algorithm of the storage optimization method, and describes the algorithm details of three core links respectively. The method can not only complete the lock-free access optimization for Cuckoo hash, but also is applicable to other open address hash table structures which need to perform object kicking based on dynamic path search. The application patent further gives a KeyValue multithreaded storage system based on the strategy, and gives design and system implementation description of the memory organization method and thread configuration process of the storage system.
[0007] The following technical solutions are specifically adopted:
[0008] An open address lock-free hash table maintenance method and storage system based on random atomic protection, comprising a query target Key:
[0009] Two different hash functions are used to calculate two different bucket position hash values of the target Key and register, and the hash values include hash value one and hash value two;
[0010] An atomic instruction load is used to sequentially traverse the slot position in the bucket corresponding to the hash value one;
[0011] First comparison and second comparison are performed, wherein the first comparison is the matching degree of the address high bit of the slot position in the bucket corresponding to the hash value one and the hash value one, and the second comparison is the key stored in the hash table and the target Key; and:
[0012] The second comparison is performed only when the first comparison result is consistent;
[0013] When the second comparison result is consistent, a copy storage entity is executed;
[0014] When any comparison is inconsistent, the comparison fails, and the traversal is continued.
[0015] As a preferred, if no valid storage object is returned after traversing all slot positions in the bucket corresponding to the hash value one, an atomic instruction load is used to sequentially traverse the slot position in the bucket corresponding to the hash value two, and first comparison and second comparison are performed, wherein the first comparison is the matching degree of the address high bit of the slot position in the bucket corresponding to the hash value one and the hash value one, and the second comparison is the stored key and the given Key; and:
[0016] The second comparison is performed only when the first comparison result is consistent;
[0017] Copy the storage entity when the second comparison result is consistent;
[0018] When any comparison is inconsistent, the comparison fails, and the traversal continues.
[0019] As a preferred, if the comparison of all slots in the two bucket positions corresponding to hash value one and hash value two respectively fails, the query is missing;
[0020] Use the memory recycler to protect the query pointer before the query; if the given Key is not found and there is another thread setting redo, re-search.
[0021] As a preferred, it also includes updating the target Key:
[0022] Search for the target Key, and:
[0023] Search for the target Key, use the CAS instruction to exchange the new storage body to the position slot, and put the old storage body into the memory recycler;
[0024] If the target Key has not been searched, perform the step of adding the target Key.
[0025] As a preferred, it also includes deleting the target Key:
[0026] After searching for the target Key, use the CAS instruction to clear the target slot.
[0027] As a preferred, it also includes adding the target Key:
[0028] Search for the target Key, and:
[0029] Search for the target Key, and perform the step of updating the target Key;
[0030] If the target Key has not been searched, according to whether the two target buckets have empty slots, perform the step of exchanging the new entity into the empty slot through CAS, or perform the step of repeating the Key detection after kicking out the Key to generate an empty slot and then exchanging the new entity into the empty slot through CAS.
[0031] As a preferred, the specific operation of kicking out the Key is:
[0032] Perform a breadth-first algorithm to calculate the kicking-out path;
[0033] Move the Key from the tail of the path to the head of the path in turn, and perform the target position saving, flag kicking-out marking, target slot copying, redo operation setting, and empty kicking-out marking operation in turn when moving.
[0034] As a preferred, the specific operation of repeating the Key detection is:
[0035] Scan the number of identical Keys in the two buckets corresponding to the Key,
[0036] According to the comparison result, it is determined whether to perform a detection pass or to delete redundant copies.
[0037] As a preference, the snapshot is scanned and the number of target Keys is recorded as count; and it is determined whether there is a kick-out mark on the object, if there is, the kick-out Key step is called, otherwise, according to the count, three situations are determined:
[0038] a. If the count is 1, there is no duplicate Key, and the detection pass is passed;
[0039] b. If the count is 0, there is no duplicate Key, and the storage entity of the Key successfully inserted at present has been deleted; the detection pass is passed;
[0040] c. If the count is greater than 1, there are more than one Key objects stored in the same pair of buckets at present, and the redundant copies are deleted; the CAS is used to delete the duplicate Key in the search order; and then the checking process is performed again.
[0041] An open address lock-free hash table maintenance system based on random atomic protection, comprising
[0042] A target Key query module is configured to query whether a target Key is in the hash table and obtain the Value corresponding to the Key; if the target Key is in the hash table, the Value corresponding to the target Key is returned, and if the target Key is not in the hash table, a missing is returned.
[0043] A target Key update module is configured to update the old Value of a target Key to a new Value in the hash table; after the update, the query of the target Key returns the new Value
[0044] A target Key addition module is configured to add a target Key and the Value corresponding to the Key to the hash table; the subsequent query operation of the target Key can return the Value corresponding to the target Key.
[0045] A target Key deletion module is configured to delete an original target Key in the hash table; after the deletion, the query operation of the Key returns a missing.
[0046] The present application has the following advantages: 1) all operations based on open address space have the characteristics of lock-free parallel operation, can efficiently utilize multi-core architecture to improve the overall throughput of the system, is suitable for open address hash table with multiple slots in the bucket, and can effectively improve the parallel efficiency of the operation by utilizing the characteristics of low kick-out rate in practice; 2) the kick-out operation adopts a help strategy, which can ensure that the entire system operates normally when the kick-out thread is abnormal or dies due to application reasons, and the random hash protection operation pointer is used between the kick-out and other operations, which can effectively reduce the pointer protection conflict between the kick-out thread and the read-write thread; 3) since each insertion thread itself can ensure that the current insertion does not have redundant objects, all read and update operations can adopt the first hit method, and after the first hit of the current Key, the objects stored in other slots in the bucket are scanned; 4) the update operation adopts a replacement strategy, and based on the epoch optimization, the memory conflict generated by global epoch rotation can be reduced under the premise of ensuring thread safety of the memory release. The above lock-free thread safety strategy realizes a memory key value storage system based on the Cuckoo hash table, and the implementation method and thread safety guarantee strategy can be used for other open address hash tables with kick-out operations. BRIEF DESCRIPTION OF DRAWINGS
[0047] Figure 1 A is a simple single-slot Cuckoo hash table, B is a multi-slot double-hash separated Cuckoo hash table, and C is a double-hash multi-bucket shared storage Cuckoo hash table.
[0048] Figure 2 It is a schematic diagram of multiple update operations on a typical shared variable.
[0049] Figure 3 It is a schematic diagram of object storage entities of the Cuckoo hash table maintained on the slot. The 64-bit address stored on each slot is divided into Tag information, address information and flag bit.
[0050] Figure 4 It is the process of breadth-first search of a kick-out path, and figure C gives the search result of the kick-out path.
[0051] Figure 5 It is a schematic diagram of the kick-out process, which includes the redo search and setting process, and gives the operation process of the helper kick-out (Helper).
[0052] Figure 6 It is a flowchart of read operation protection of the current operation and checking and redoing.
[0053] Figure 7 It is a schematic diagram of the random hash method to reduce the atomic operation conflict of the registered address and detection process.
[0054] Figure 8 Flow for checking duplicate Key and its corresponding operation after insertion operation
[0055] Figure 9 For the epoch-based memory protection core data structure, each thread has a local epoch and a memory package, and a unique global epoch is globally shared
[0056] Figure 10 For the processing flow of the epoch memory protection, the read thread needs to call startOp before accessing the pointer, and endOp is executed after accessing the pointer; the update thread needs to execute deallocate to try to release the pointer when discarding a pointer.
[0057] Figure 11 For the database cache system structure diagram.
[0058] Figure 12 For the KeyValue storage system structure diagram. DETAILED DESCRIPTION
[0059] The application will be further described below in conjunction with the drawings and specific embodiments.
[0060] I. First, the invention points of the application are introduced:
[0061] An open address lock-free hash table maintenance method based on random atomic protection (referred to as "open address lock-free hash table") provides a lock-free processing framework for all hash access interfaces based on open address space hash table. The method assumes that the hash table structure provides multiple storage locations for each Key, takes the slot (pointer storage location of the execution object storage entity) as the core operation object, and optimizes the lock-free operation for addition, deletion, modification and query.
[0062] The hash table body of the application is a single table multi-bucket structure, as shown in Figure 1 C. It uses a hash table to store data, and in a table body, two different hash functions are used to index the same Key into two different buckets. Each bucket has multiple slot positions to place the Key. The structure of the table body is shown in Figure 3 Each slot position is 64 bits long, and the high 16 bits are tag to speed up the access to the Key. When performing the kick-out, the high 16 bits are thread id, which is used for the index of the kick-out information. The remaining 48 bits are used to index the KeyValue entity. The remaining 1 bit is used to identify whether it is being kicked out.
[0063] Given multiple threads, the implementation steps of the four typical operations are as follows.
[0064] Embodiment 1, this embodiment relates to a query operation, as shown inFigure 6 As shown, mainly includes:
[0065] Step 1, calculate two hash values h1, h2 of given Key
[0066] Step 2, register hash value h1 in the shared atomic variable of the current thread, and sequentially traverse the i-th slot of the bucket corresponding to h1 using atomic instruction load
[0067] a. If the address high 16 of slot i of bucket x matches h1, read the storage entity from its low 48-bit pointer, and compare the stored key with the given Key
[0068] b. If the stored key in a and the given Key are equal, copy the storage entity and return
[0069] c. If the Tag or the stored key in a is not equal to the given Key, increment i to scan the next one
[0070] Step 3, if h1 does not return a valid storage object, process the slot corresponding to h2 according to steps a-c
[0071] The memory reclaimer protection pointer is called before step 2 of the query process, and the b / c operations of steps 2 and 3 involve releasing the protection pointer, which is given in the memory reclamation details later; if the given Key is not found and there is another thread setting redo, jump to step 1 to redo.
[0072] Embodiment 2, this embodiment relates to update operation, such as Figure 2 As shown, mainly includes:
[0073] Step 1, create a new storage entity to accommodate the new Value, and calculate two hash values h1, h2 of the given Key
[0074] Step 2, register hash value h1 in the shared atomic variable of the current thread, and sequentially traverse the i-th slot of the bucket corresponding to h1 using atomic instruction load
[0075] a. If the address high 16 of slot i of bucket x matches h1, read the storage entity from its low 48-bit pointer, and compare the stored key with the given Key
[0076] b. If the stored key in a and the given Key are equal, execute CAS instruction to exchange the new storage body to position slot i
[0077] c. If the Tag or the stored key in a is not equal to the given Key, increment i to scan the next one
[0078] Step 3, if h1 does not find the storage entity corresponding to the Key, process the slot corresponding to h2 according to steps a-c
[0079] Step 4, if there is no storage entity corresponding to the Key in h1 and h2, handle the slots in the two buckets according to their occupancy
[0080] a. If there is an empty slot in the two buckets, and the new entity is exchanged to the slot through CAS
[0081] b. If there is no empty slot in the two buckets, then a vacant position is created in the two buckets through the kick-out algorithm (details of the algorithm are given in the kick-out section of the subsequent content of the patent) to accommodate the new storage entity
[0082] Step 5, check the redo flag at the beginning of step 4 (no Key found) above, if other threads set redo, then jump to step 1 to redo. If the above process fails, then jump to step 1 to re-execute the update; if it succeeds, then put the old address obtained by CAS into the memory recycler to complete the operation.
[0083] Embodiment 3, this embodiment relates to the deletion operation, mainly including:
[0084] Similar to the above update operation, for the sake of clear algorithm description, the complete algorithm is given as follows:
[0085] Step 1, calculate the two hash values h1 and h2 of the given Key
[0086] Step 2, register the hash value h1 in the shared atomic variable of the current thread, and use the atomic instruction load to sequentially traverse the i-th slot of the bucket corresponding to h1
[0087] a. If the address of slot i of bucket x matches h1 in the high 16 bits, then read the storage entity from the low 48-bit pointer, and compare the stored Key with the given Key
[0088] b. If the stored Key in a is equal to the given Key, then execute the CAS instruction to exchange the null pointer to the position slot i, and call the memory recycler to release the original storage entity
[0089] c. If the Tag or the stored Key in a is not equal to the given Key, then increment i to scan the next one
[0090] Step 3, if no storage entity corresponding to the Key is found in h1, then handle the slots corresponding to h2 according to steps a-c
[0091] Step 4, if there is no storage entity corresponding to the Key in h1 and h2, if other threads set redo, then return to step 1 to redo; otherwise, return that the Key does not exist
[0092] Embodiment 4, this embodiment relates to the addition operation, mainly including:
[0093] The operation is consistent with the update operation algorithm in implementation, and can be implemented by using the update algorithm. When the execution semantics of the update algorithm is addition (i.e. before returning insertion success from step 4 thereof), the repeated Key detection algorithm is executed.
[0094] As an embodiment, during the update (insertion) operation, if it is determined that the Key does not exist and there is no empty slot in the two twin buckets to store the new storage entity, the eviction operation needs to be executed. The eviction process is as follows:
[0095] Step 1. Considering that the 47-bit address space can describe the protection address space of the IA64-bit operating system, the 0th bit of the address is used to indicate whether a slot is currently in the evicted state
[0096] Step 2. If all slots of the buckets corresponding to the two sets of hash values h1 and h2 corresponding to a Key are occupied, a Breath-First Search (BFS) algorithm is executed to recursively search from the bucket of h1 to find a twin bucket in which the Key can be removed
[0097] a. First, scan the Key in each slot of the bucket corresponding to h1
[0098] b. Calculate the twin bucket number of each Key in turn, and check whether the twin bucket has an empty slot
[0099] c. If the twin bucket of any Key has an empty slot, record the path from the root to the empty slot to represent the order of Key eviction
[0100] d. If the current layer of BFS still has no empty slot, the path level is incremented and the recursion search is performed in step a, until the path position is found
[0101] e. If d reaches a maximum layer limit and still has no empty slot, the rehash process is executed
[0102] Step 3. According to the path found in step 2.d, the eviction process is executed from bottom to top, and each time the target position saving, the eviction flag setting, the target slot copying, the redo operation setting and the eviction flag clearing are executed in turn, as follows:
[0103] a. Considering that the thread Ti is evicted from the slot i in the source bucket s to the slot j in the target bucket t, first, t and j are copied to the shared variables of the thread
[0104] b. The storage entity entry information entry of slot i is read using load, and then the 0th bit of the address of slot i of bucket s is set to 1 and the high 16 bits are set to the ID of the current thread, indicating that the slot is being kicked out by the specified thread ID
[0105] c. The entry of slot i of bucket s is copied to slot j of bucket t
[0106] d. Scan all other threads except the thread T, to see if there is any thread whose registered hash value on its shared protection variable is equal to the hash value of the current kicked out Key, set the redo flag of the thread with equal hash value to true, and trigger the redo operation when the thread cannot find its required Key
[0107] e. Empty the slot i of the bucket s after scanning the hash value of all threads, and return to the previous level to continue the kicking out process
[0108] wherein, the registered hash value in step d and the previous four types of algorithm description step 2 is used to ensure that the current but not kicking out operation does not cross with other read operations (if there is a cross, the read operation is redone), so that the query hit does not occur due to the current kicking operation. In order to reduce the conflict of the registration operation of other threads and the load and store of the kicking operation here, the patent particularly gives a kind of random atomic protection method based on the implementation of the above step d, as follows:
[0109] a. The registration of hash value is first allocated a plurality of protection positions locally
[0110] b. When protecting a certain hash value h1, the hash is randomly mapped to one of the protection positions according to a predefined method
[0111] c. When the thread tries to load the protection hash of other threads, the position mapped by the hash of the kicked out Key is calculated according to the same mapping method, and then the load is executed to complete the matching determination of a pile of hash values
[0112] Step 4, after completing the kicking out from bottom to top based on step 2.d, the bucket corresponding to the hash value h1 of the entry Key will appear an empty slot, and the algorithm tries to insert the storage entity of the Key into the empty slot, if the CAS insertion is successful, the whole insertion process is completed; otherwise, the whole insertion process is redone.
[0113] The following situation can be avoided in this process: before a thread T1 inserts the Key, the scanning of the bucket of h1 does not find the Key, but finds at least two empty slots in the bucket; before T1 scans the bucket of h2, a slot of h2 is Key, but another thread T2 kicks the Key to the bucket of h1 at this time. In this process, T1 scans the bucket of h2 and does not find the Key (in fact, when T1 scans h2, the Key has been kicked to the h1 bucket by T2), if the redo is not performed, T1 will finally insert the Key into one slot of the h1 bucket, so that T1 and T2 each insert an object (both are Key) into h2 and h1, resulting in redundancy.
[0114] As an embodiment, during the update operation, if it is found that the lowest bit of a slot is marked as "being kicked out" before the update operation at any time, the above kicking out process is directly called to try to "help" the marked thread to do the "kicking out" operation. The help kicking out operation is to ensure that when the kicking out thread is abnormally suspended, other threads can still normally advance, so as to improve the robustness of the system. The implementation of the "help kicking out" process is only executed from step 3 of the above algorithm, and steps 3.a-b are replaced by:
[0115] a`: load the entry value in the slot, if the 0th bit of the entry is 1, trigger the kicking out b`: determine the target slot information of the current kicking out through the high Target Slot bit of the entry. At the same time, the information of the target bucket of the kicking out can be confirmed through the hash value calculation of the target bucket.
[0116] The subsequent operation starts from step 3.c, which is consistent with the previous normal kicking out process.
[0117] As an embodiment, during the update operation, if the insertion operation (or the update operation with insertion semantics) is completed, the thread needs to perform a duplicate detection process to ensure that any Key appears only once. Assuming that the two hash values h1 and h2 of a given Key, the no-lock operation can cause the same Key to appear more than once as follows.
[0118] Example of the situation where the problem occurs: a thread T1 inserts a Key before scanning the h1 and h2 buckets, and does not find the Key, so it decides to insert the Key into a certain empty slot; thereafter, a thread T2 deletes (or kicks out) an object in the h1 bucket, which vacates a slot before T1 inserts; before T1 performs the insertion, another thread T3 scans the h1 and h2 buckets before inserting the Key, and also does not find the Key and decides to insert the Key in the bucket vacated by T2, thereby causing the Key to have two copies, resulting in redundancy.
[0119] This kind of situation is more common in the context of frequent deletion and parallel update: when any two threads T1 and T2 need to update a Key, one of the threads (such as T1) performs CAS after determining the target slot, at which time the state of the bucket changes, which can cause T2 to locate to a different empty slot, thereby causing T1 and T2 to both insert (move) the Key successfully, thereby causing the Key to have redundant copies. This kind of situation does not exist in the serial context or the bucket locking strategy, but only in the no-lock context, and certain strategies need to be adopted to avoid it in order to save bucket resources and not lose the update of the Key. One method to avoid is: after each
[0120] The duplicate detection process for the current inserted Key is as follows:
[0121] Step 1: After completing the insertion semantics, any thread T1 enters the duplicate Key detection process
[0122] Step 2, scan the two buckets according to the two hash values h1 and h2 of the Key calculated at the time of insertion, and record the contents in a local array, called snapshot. (If h1 and h2 only check one bucket)
[0123] Step 3, check the redo flag to ensure that there is no kickout during the scanning process.
[0124] Step 4, scan the snapshot and record the number of target Keys as count. And judge whether there is a kickout mark on the object, if there is, call the help kickout process, if not, according to the count, judge the possible three situations:
[0125] a. If count is 1, it means there is no duplicate Key, the detection is passed
[0126] b. If count is 0, it means not only there is no duplicate Key, but also the storage entity of the Key successfully inserted at present has been deleted; the detection is passed.
[0127] c. If count is greater than 1, it means that there are more than 1 Key object storage entities on the same pair of buckets at present (the scanning in step 2 above does not consider the slot marked as being kicked out). At this time, it is necessary to consider deleting the redundant copies. Use CAS to delete the duplicate Key with the search order later. Then recheck the process.
[0128] Step 4, the exit condition of the operation is that any Key has at most one storage copy on a pair of storage buckets. When and only when the current insertion operation detects that this condition is met, the operation returns normally.
[0129] As an embodiment, in the process of the update operation, the entity address in the given slot is protected before any read operation starts, and in the update, the old storage entity needs to be released. The memory reclaimer on which these protections depend is based on the epoch idea: any global epoch promotion needs the local epoch and the current epoch of all threads to be the same, that is, all threads have read all the objects accessed at least in the current epoch (the operation of updating the current local epoch is after reading is completed).
[0130] Based on the above idea, two modifications are made to the traditional epoch memory protection for efficiency considerations: each thread passes the private epoch of other threads, and at any time, if the local epoch of other threads is higher than the local epoch of the current thread, the thread starts from thread 0 and re-scans; batch operation detection, that is, each thread does not detect all other threads after each operation, but detects other threads after continuous reading multiple times to reduce the read-write conflict overhead of private epoch between threads. Given the memory cache and epoch atomic variable of each thread, the execution process is as follows:
[0131] Step 1, before the thread starts reading the object, first read the global epoch, if the global epoch is greater than the private count, it means that other threads have updated the global epoch, at this time the current thread executes the following operation to release the local hanging memory pointer:
[0132] a. Point the current memory package pointer to the next package
[0133] b. Traverse the objects in the current memory package and release all the pointers in it in turn
[0134] c. Complete the release and return
[0135] Step 2, read the global epoch and overwrite it to the local epoch copy
[0136] Step 3, loop to view the local epoch shared variable of other threads and do corresponding operations according to different situations:
[0137] a. If the other epoch shared variable is the same as the global epoch read by the current thread, loop to view all other threads and increment the global epoch;
[0138] b. In the scanning process in a, if the local epoch shared variable of any thread is smaller than the global epoch read by the current thread, it means that one thread has not advanced to the current epoch, and the current thread returns directly
[0139] Step 4, after the current thread completes reading, copy the global epoch value read previously to the local epoch shared variable to complete the reading operation.
[0140] After any write operation completes access to a pointer, the pointer removed from the global data structure cannot be accessed thereafter, and the thread that removed the pointer directly places the pointer in its current memory package, and waits for a reading opportunity to release all pointer objects in the memory package (as described in the memory package release process in step 1 above).
[0141] So far, the process of the lock-free open address hash table operation is given, and four types of operations are based on three core processes to ensure lock-free operation, safe kick-out, no redundant objects and memory-safe release.
[0142] Embodiment 5, the following is a specific implementation method using the above core invention points.
[0143] The scheme given by the application is applicable to the index scene of memory entities, and using the application can achieve lock-free parallel operation characteristics of all operations based on open address space, and can efficiently utilize multi-core architecture to improve the overall throughput of the system.
[0144] As an embodiment, the hash table maintenance method involved in the application can be applied to a database cache system.
[0145] The database cache system can use the index memory entity in the hash table to cooperate with the memory recycler and the memory manager to perform cache management of the memory entity. Using a network or a function API interface, the database application is called to cache the database object and speed up the database access, which includes four key steps:
[0146] Step 1, using a network or an API interface to obtain query return information of a database, and retaining the information in a memory manager;
[0147] Step 2, placing the index in the memory manager into a hash table;
[0148] Step 3, when a query for a Key in the database arrives, first query the hash table of the database cache system, if it can be hit, directly return the query content from the memory manager;
[0149] Step 4, if the query of step 2.3 is not hit, then request the corresponding data from the database application.
[0150] As another embodiment, the hash table maintenance method involved in the application can also be applied to a KeyValue storage system.
[0151] Including four key steps, as follows:
[0152] Step 1, using a network or an API interface to obtain a request operation;
[0153] Step 2, for a read request, directly query the hash table to obtain the result and return;
[0154] Step 3, for a write request, first write the write request into a persistent log, and then write into the hash table in memory;
[0155] Step 4, when the persistent log is too long, merge it into a checkpoint to reduce the recovery time after a crash.
[0156] Embodiment 6, the present application also relates to a random atomic protection-based open address lock-free hash table maintenance system, comprising
[0157] Query target Key module: configured to query whether a target Key is in the hash table and obtain the Value corresponding to the Key; if the target Key is in the hash table, the Value corresponding to the target Key is returned; if the target Key is not in the hash table, a missing is returned;
[0158] Update target Key module: configured to update the old Value of the target Key to a new Value in the hash table; the query of the target Key after the update returns the new Value
[0159] Add target Key module: configured to add a target Key and the Value corresponding to the Key into the hash table; the subsequent query operation of the target Key can return the Value corresponding to the target Key;
[0160] Delete target Key module: configured to delete the original target Key in the hash table; the query operation of the Key after the deletion returns a missing.
[0161] The above are only some embodiments of the present application, and are not used to limit the protection scope of the present application. Therefore, any modification, equivalent replacement, improvement, etc. made within the spirit and principle of the present application shall be included in the protection scope of the present application.
Claims
1. A method for maintaining an open address lock-free hash table based on random atomic protection, characterized in that: Including query target Key: Use two different hash functions to calculate and register two different bucket hash values of the target key, the hash values including hash value 1 and hash value 2; Use the atomic instruction load to traverse the slots in the bucket corresponding to the hash value one in sequence; Perform a first comparison and a second comparison, where the first comparison is the match between the high bit of the address of the slot corresponding to the bucket of hash value one and hash value one, and the second comparison is the match between the key stored in the hash table and the target key; and: If and only if the results of the first comparison are consistent, then the second comparison is performed; If the second comparison result is consistent, copy the storage entity; If any comparison is inconsistent, the comparison fails and the traversal continues; If no valid storage object is returned after traversing all the slots in the bucket corresponding to hash value 1, the atomic instruction load is used to traverse the slots in the bucket corresponding to hash value 2 in sequence, and perform the first comparison and the second comparison. The first comparison is the match between the high bit of the address of the slot in the bucket corresponding to hash value 1 and hash value 1, and the second comparison is the match between the stored key and the given key. and: If and only if the first comparison results are consistent, then the second comparison is performed; If the second comparison result is consistent, copy the storage entity; If any comparison is inconsistent, the comparison fails and the traversal continues; If the comparison of all slots in the two buckets corresponding to hash value 1 and hash value 2 fails, the query is missing; Use the memory collector to protect the query pointer before querying; if the given key is not found and other threads set redo, search again.
2. The method for maintaining an open address lock-free hash table based on random atomic protection according to claim 1, characterized in that: It also includes updating the target key: Search for the target key, and: After searching for the target key, use the CAS instruction to swap the new storage body to the location slot and put the old storage body into the memory reclaimer; If the target key has not been found, proceed to the step of adding a new target key.
3. The method for maintaining an open address lock-free hash table based on random atomic protection according to claim 1, characterized in that: It also includes deleting the target key: After searching for the target key, use the CAS instruction to clear the target slot.
4. The method for maintaining an open address lock-free hash table based on random atomic protection according to claim 1, characterized in that: Also includes new target keys: Search for the target key, and: Search for the target key and execute the update target key step; If the target key has not been found, the new entity will be swapped to the empty slot through CAS based on whether there are empty slots in the two target buckets, or the key will be kicked out to create an empty slot, and the new entity will be swapped to the empty slot through CAS and then duplicate key detection will be performed.
5. The method for maintaining an open address lock-free hash table based on random atomic protection according to claim 4, characterized in that: The specific operations for kicking out a key are: Execute the breadth-first algorithm to calculate the kick-out path; Move the key from the end of the path to the beginning of the path. When moving, save the target position, mark the kick mark, copy the target slot, set the redo operation, and clear the kick mark.
6. The method for maintaining an open address lock-free hash table based on random atomic protection according to claim 4, characterized in that: The specific operations of duplicate key detection are: Scan the number of identical keys in the two buckets corresponding to the key. Based on the comparison results, you can choose to perform a check or delete unnecessary copies.
7. The method for maintaining an open address lock-free hash table based on random atomic protection according to claim 4, characterized in that: Scan the snapshot and record the number of target keys as count; then determine whether there is a kick mark on the object. If so, call the kick key step. Otherwise, determine three situations based on count: a. If count is 1, there is no duplicate key and the test passes; b. If count is 0, there is no duplicate key, and the storage entity of the currently inserted key has been deleted; the test passes; c. If count is greater than 1, there are more than one object storage entity with the same key in the same bucket pair. Delete the extra copies. Use CAS to delete duplicate keys at the end of the search order; then retry the check process.
8. An open address lock-free hash table maintenance system based on random atomic protection, used to implement the open address lock-free hash table maintenance method based on random atomic protection according to any one of claims 1 to 7, characterized in that: include Query target key module: It is configured to query whether a target key is in the hash table and obtain the value corresponding to the key; If the target key is in the hash table, the value corresponding to the target key is returned. If the target key is not in the hash table, the missing value is returned. Update target key module: configured to update the old value of the target key to the new value in the hash table; After the update, the query for the target Key returns the new Value Add target key module: It is configured to add a target key and the value corresponding to the key to the hash table; subsequent query operations on the target key can return the value corresponding to the target key; Delete target key module: It is configured to delete the original target key in the hash table; after deletion, the query operation on the key will return missing.
Citation Information
Patent Citations
Dynamic hash table operation method based on hybrid DRAM-NVM memory
CN111459846A
Cuckoo hash optimization method based on coroutine
CN114116727A