• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the openHiTLS project.
3  *
4  * openHiTLS is licensed under the Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *
8  *     http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  * See the Mulan PSL v2 for more details.
14  */
15 
16 #include "hitls_build.h"
17 #ifdef HITLS_BSL_HASH
18 
19 #include "securec.h"
20 #include "bsl_sal.h"
21 #include "list_base.h"
22 #include "bsl_errno.h"
23 #include "bsl_err_internal.h"
24 #include "hash_local.h"
25 #include "bsl_hash.h"
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif /* __cplusplus */
30 
31 #define BSL_CSTL_HASH_OPTION3 3
32 #define BSL_CSTL_HASH_OPTION2 2
33 #define BSL_CSTL_HASH_OPTION1 1
34 
35 struct BSL_HASH_TagNode {
36     ListRawNode node; /**< Linked list node */
37     uintptr_t key;    /**< Key or address for storing the key */
38     uintptr_t value;  /**< value or address for storing the value */
39 };
40 
41 typedef struct BSL_HASH_TagNode BSL_HASH_Node;
42 
43 struct BSL_HASH_Info {
44     ListDupFreeFuncPair keyFunc;       /**< key Copy and release function pair */
45     ListDupFreeFuncPair valueFunc;     /**< value Copy and release function pair */
46     BSL_HASH_MatchFunc matchFunc;      /**< matching function */
47     BSL_HASH_CodeCalcFunc hashFunc;    /**< hash function */
48     uint32_t bucketSize;               /**< hash table size */
49     uint32_t hashCount;                /**< number of entries in the hash table */
50     RawList listArray[0];              /**< linked list control block array*/
51 };
52 
53 /* murmurhash algorithm */
54 /* define constants */
55 #define HASH_VC1 0xCC9E2D51
56 #define HASH_VC2 0x1B873593
57 #define HASH_HC1 0xE6546B64
58 #define HASH_HC2 0x85EBCA6B
59 #define HASH_HC3 0xC2B2AE35
60 #define HASH_HC4 5
61 
62 #define CHAR_BIT 8
63 #define CHAR_FOR_PER_LOOP 4
64 #define HASH_V_ROTATE 15
65 #define HASH_H_ROTATE 13
66 #define SYS_BUS_WIDTH sizeof(uint32_t)
67 #define HASH_SEED 0x3B9ACA07 /* large prime 1000000007. The seed can be random or specified. */
68 
69 enum BSL_CstlByte {
70     ONE_BYTE = 1,
71     TWO_BYTE = 2,
72 };
73 
74 enum BSL_CstlShiftBit { SHIFT8 = 8, SHIFT13 = 13, SHIFT16 = 16, SHIFT24 = 24 };
75 
BSL_HASH_Rotate(uint32_t v,uint32_t offset)76 static uint32_t BSL_HASH_Rotate(uint32_t v, uint32_t offset)
77 {
78     return ((v << offset) | (v >> (SYS_BUS_WIDTH * CHAR_BIT - offset)));
79 }
80 
BSL_HASH_MixV(uint32_t v)81 static uint32_t BSL_HASH_MixV(uint32_t v)
82 {
83     uint32_t res = v;
84     res = res * HASH_VC1;
85     res = BSL_HASH_Rotate(res, HASH_V_ROTATE);
86     res = res * HASH_VC2;
87 
88     return res;
89 }
90 
BSL_HASH_MixH(uint32_t h,uint32_t v)91 static uint32_t BSL_HASH_MixH(uint32_t h, uint32_t v)
92 {
93     uint32_t res = h;
94 
95     res ^= v;
96     res = BSL_HASH_Rotate(res, HASH_H_ROTATE);
97     res = res * HASH_HC4 + HASH_HC1;
98 
99     return res;
100 }
101 
BSL_HASH_CodeCalc(void * key,uint32_t keySize)102 uint32_t BSL_HASH_CodeCalc(void *key, uint32_t keySize)
103 {
104     uint8_t *tmpKey = (uint8_t *)key;
105     uint32_t i = 0;
106     uint32_t v;
107     uint32_t h = HASH_SEED;
108     uint8_t c0, c1, c2, c3;
109     uint32_t tmpLen = keySize - keySize % CHAR_FOR_PER_LOOP;
110 
111     while ((i + CHAR_FOR_PER_LOOP) <= tmpLen) {
112         c0 = tmpKey[i++];
113         c1 = tmpKey[i++];
114         c2 = tmpKey[i++];
115         c3 = tmpKey[i++];
116 
117         v = (uint32_t)c0 | ((uint32_t)c1 << SHIFT8) | ((uint32_t)c2 << SHIFT16) | ((uint32_t)c3 << SHIFT24);
118         v = BSL_HASH_MixV(v);
119         h = BSL_HASH_MixH(h, v);
120     }
121 
122     v = 0;
123 
124     switch (keySize & BSL_CSTL_HASH_OPTION3) {
125         case BSL_CSTL_HASH_OPTION3:
126             v ^= ((uint32_t)tmpKey[i + TWO_BYTE] << SHIFT16);
127             /* (keySize % 4) is equals 3, fallthrough, other branches are the same. */
128             /* fall-through */
129         case BSL_CSTL_HASH_OPTION2:
130             v ^= ((uint32_t)tmpKey[i + ONE_BYTE] << SHIFT8);
131             /* fall-through */
132         case BSL_CSTL_HASH_OPTION1:
133             v ^= tmpKey[i];
134             v = BSL_HASH_MixV(v);
135             h ^= v;
136             break;
137         default:
138             break;
139     }
140 
141     h ^= h >> SHIFT16;
142 
143     h *= HASH_HC2;
144     h ^= h >> SHIFT13;
145     h *= HASH_HC3;
146     h ^= h >> SHIFT16;
147 
148     return h;
149 }
150 
151 /* internal function definition */
BSL_HASH_HookRegister(BSL_HASH_Hash * hash,BSL_HASH_CodeCalcFunc hashFunc,BSL_HASH_MatchFunc matchFunc,ListDupFreeFuncPair * keyFunc,ListDupFreeFuncPair * valueFunc)152 static void BSL_HASH_HookRegister(BSL_HASH_Hash *hash, BSL_HASH_CodeCalcFunc hashFunc,
153     BSL_HASH_MatchFunc matchFunc, ListDupFreeFuncPair *keyFunc, ListDupFreeFuncPair *valueFunc)
154 {
155     ListDupFreeFuncPair *hashKeyFunc = &hash->keyFunc;
156     ListDupFreeFuncPair *hashValueFunc = &hash->valueFunc;
157 
158     if (hashFunc == NULL) {
159         hash->hashFunc = BSL_HASH_CodeCalcInt;
160     } else {
161         hash->hashFunc = hashFunc;
162     }
163 
164     if (matchFunc == NULL) {
165         hash->matchFunc = BSL_HASH_MatchInt;
166     } else {
167         hash->matchFunc = matchFunc;
168     }
169 
170     if (keyFunc == NULL) {
171         hashKeyFunc->dupFunc = NULL;
172         hashKeyFunc->freeFunc = NULL;
173     } else {
174         hashKeyFunc->dupFunc = keyFunc->dupFunc;
175         hashKeyFunc->freeFunc = keyFunc->freeFunc;
176     }
177 
178     if (valueFunc == NULL) {
179         hashValueFunc->dupFunc = NULL;
180         hashValueFunc->freeFunc = NULL;
181     } else {
182         hashValueFunc->dupFunc = valueFunc->dupFunc;
183         hashValueFunc->freeFunc = valueFunc->freeFunc;
184     }
185 }
186 
BSL_HASH_IterEndGet(const BSL_HASH_Hash * hash)187 static inline BSL_HASH_Iterator BSL_HASH_IterEndGet(const BSL_HASH_Hash *hash)
188 {
189     return (BSL_HASH_Iterator)(uintptr_t)(&hash->listArray[hash->bucketSize].head);
190 }
191 
BSL_HASH_NodeCreate(const BSL_HASH_Hash * hash,uintptr_t key,uint32_t keySize,uintptr_t value,uint32_t valueSize)192 static BSL_HASH_Node *BSL_HASH_NodeCreate(
193     const BSL_HASH_Hash *hash, uintptr_t key, uint32_t keySize, uintptr_t value, uint32_t valueSize)
194 {
195     uintptr_t tmpKey;
196     uintptr_t tmpValue;
197     BSL_HASH_Node *hashNode = NULL;
198     void *tmpPtr = NULL;
199 
200     hashNode = (BSL_HASH_Node *)BSL_SAL_Malloc(sizeof(BSL_HASH_Node));
201     if (hashNode == NULL) {
202         return NULL;
203     }
204 
205     if (hash->keyFunc.dupFunc != NULL) {
206         tmpPtr = hash->keyFunc.dupFunc((void *)key, keySize);
207         tmpKey = (uintptr_t)tmpPtr;
208         if (tmpKey == (uintptr_t)NULL) {
209             BSL_SAL_FREE(hashNode);
210             return NULL;
211         }
212     } else {
213         tmpKey = key;
214     }
215 
216     if (hash->valueFunc.dupFunc != NULL) {
217         tmpPtr = hash->valueFunc.dupFunc((void *)value, valueSize);
218         tmpValue = (uintptr_t)tmpPtr;
219         if (tmpValue == (uintptr_t)NULL) {
220             if (hash->keyFunc.freeFunc != NULL) {
221                 hash->keyFunc.freeFunc((void *)tmpKey);
222             }
223 
224             BSL_SAL_FREE(hashNode);
225             return NULL;
226         }
227     } else {
228         tmpValue = value;
229     }
230 
231     hashNode->key = tmpKey;
232     hashNode->value = tmpValue;
233 
234     return hashNode;
235 }
236 
BSL_HASH_FindNode(const RawList * list,uintptr_t key,BSL_HASH_MatchFunc matchFunc)237 static BSL_HASH_Node *BSL_HASH_FindNode(const RawList *list, uintptr_t key, BSL_HASH_MatchFunc matchFunc)
238 {
239     BSL_HASH_Node *hashNode = NULL;
240     ListRawNode *rawListNode = NULL;
241 
242     for (rawListNode = ListRawFront(list); rawListNode != NULL; rawListNode = ListRawGetNext(list, rawListNode)) {
243         hashNode = BSL_CONTAINER_OF(rawListNode, BSL_HASH_Node, node);
244         if (matchFunc(hashNode->key, key)) {
245             return hashNode;
246         }
247     }
248 
249     return NULL;
250 }
251 
BSL_HASH_Front(const BSL_HASH_Hash * hash)252 static BSL_HASH_Iterator BSL_HASH_Front(const BSL_HASH_Hash *hash)
253 {
254     uint32_t i = 0;
255     const RawList *list = NULL;
256     ListRawNode *rawListNode = NULL;
257 
258     while (i < hash->bucketSize) {
259         list = &hash->listArray[i];
260         rawListNode = ListRawFront(list);
261         if (rawListNode != NULL) {
262             return BSL_CONTAINER_OF(rawListNode, BSL_HASH_Node, node);
263         }
264 
265         i++;
266     }
267 
268     return BSL_HASH_IterEndGet(hash);
269 }
270 
BSL_HASH_Next(const BSL_HASH_Hash * hash,BSL_HASH_Iterator hashNode)271 static BSL_HASH_Iterator BSL_HASH_Next(const BSL_HASH_Hash *hash, BSL_HASH_Iterator hashNode)
272 {
273     uint32_t i;
274     uint32_t hashCode;
275     const RawList *list = NULL;
276     ListRawNode *rawListNode = NULL;
277 
278     hashCode = hash->hashFunc(hashNode->key, hash->bucketSize);
279     if (hashCode >= hash->bucketSize) {
280         return BSL_HASH_IterEndGet(hash);
281     }
282 
283     list = hash->listArray + hashCode;
284     rawListNode = ListRawGetNext(list, &hashNode->node);
285     if (rawListNode != NULL) {
286         return BSL_CONTAINER_OF(rawListNode, BSL_HASH_Node, node);
287     }
288 
289     for (i = hashCode + 1; i < hash->bucketSize; ++i) {
290         list = &hash->listArray[i];
291         rawListNode = ListRawFront(list);
292         if (rawListNode != NULL) {
293             return BSL_CONTAINER_OF(rawListNode, BSL_HASH_Node, node);
294         }
295     }
296 
297     return BSL_HASH_IterEndGet(hash);
298 }
299 
BSL_HASH_NodeFree(BSL_HASH_Hash * hash,BSL_HASH_Node * node)300 static void BSL_HASH_NodeFree(BSL_HASH_Hash *hash, BSL_HASH_Node *node)
301 {
302     ListFreeFunc keyFreeFunc = hash->keyFunc.freeFunc;
303     ListFreeFunc valueFreeFunc = hash->valueFunc.freeFunc;
304 
305     if (keyFreeFunc != NULL) {
306         keyFreeFunc((void *)node->key);
307     }
308 
309     if (valueFreeFunc != NULL) {
310         valueFreeFunc((void *)node->value);
311     }
312 
313     BSL_SAL_FREE(node);
314 }
315 
BSL_HASH_CodeCalcInt(uintptr_t key,uint32_t bktSize)316 uint32_t BSL_HASH_CodeCalcInt(uintptr_t key, uint32_t bktSize)
317 {
318     uint32_t hashCode = BSL_HASH_CodeCalc(&key, sizeof(key));
319 
320     return hashCode % bktSize;
321 }
322 
BSL_HASH_MatchInt(uintptr_t key1,uintptr_t key2)323 bool BSL_HASH_MatchInt(uintptr_t key1, uintptr_t key2)
324 {
325     return key1 == key2;
326 }
327 
BSL_HASH_CodeCalcStr(uintptr_t key,uint32_t bktSize)328 uint32_t BSL_HASH_CodeCalcStr(uintptr_t key, uint32_t bktSize)
329 {
330     char *tmpKey = (char *)key;
331     uint32_t hashCode = BSL_HASH_CodeCalc(tmpKey, (uint32_t)strlen(tmpKey));
332 
333     return hashCode % bktSize;
334 }
335 
BSL_HASH_MatchStr(uintptr_t key1,uintptr_t key2)336 bool BSL_HASH_MatchStr(uintptr_t key1, uintptr_t key2)
337 {
338     char *tkey1 = (char *)key1;
339     char *tkey2 = (char *)key2;
340 
341     if (strcmp(tkey1, tkey2) == 0) {
342         return true;
343     }
344 
345     return false;
346 }
347 
BSL_HASH_Create(uint32_t bktSize,BSL_HASH_CodeCalcFunc hashFunc,BSL_HASH_MatchFunc matchFunc,ListDupFreeFuncPair * keyFunc,ListDupFreeFuncPair * valueFunc)348 BSL_HASH_Hash *BSL_HASH_Create(uint32_t bktSize, BSL_HASH_CodeCalcFunc hashFunc, BSL_HASH_MatchFunc matchFunc,
349     ListDupFreeFuncPair *keyFunc, ListDupFreeFuncPair *valueFunc)
350 {
351     uint32_t i;
352     uint32_t size;
353     BSL_HASH_Hash *hash = NULL;
354     RawList *listAddr = NULL;
355     if (bktSize == 0U) {
356         return NULL;
357     }
358 
359     size = (bktSize + 1) * sizeof(RawList);
360     if (IsMultiOverflow((bktSize + 1), sizeof(RawList)) || IsAddOverflow(size, sizeof(BSL_HASH_Hash))) {
361         return NULL;
362     }
363 
364     size += sizeof(BSL_HASH_Hash);
365     hash = (BSL_HASH_Hash *)BSL_SAL_Malloc(size);
366     if (hash == NULL) {
367         return NULL;
368     }
369 
370     (void)memset_s(hash, size, 0, size);
371     hash->bucketSize = bktSize;
372     BSL_HASH_HookRegister(hash, hashFunc, matchFunc, keyFunc, valueFunc);
373 
374     listAddr = hash->listArray;
375     for (i = 0; i <= bktSize; ++i) {
376         ListRawInit(listAddr + i, NULL);
377     }
378 
379     return hash;
380 }
381 
BSL_HASH_InsertNode(BSL_HASH_Hash * hash,RawList * rawList,const BSL_CstlUserData * inputKey,const BSL_CstlUserData * inputValue)382 static int32_t BSL_HASH_InsertNode(
383     BSL_HASH_Hash *hash, RawList *rawList, const BSL_CstlUserData *inputKey, const BSL_CstlUserData *inputValue)
384 {
385     BSL_HASH_Node *hashNode = BSL_HASH_NodeCreate(
386         hash, inputKey->inputData, inputKey->dataSize, inputValue->inputData, inputValue->dataSize);
387     if (hashNode == NULL) {
388         BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
389         return BSL_INTERNAL_EXCEPTION;
390     }
391 
392     ListRawPushBack(rawList, &hashNode->node);
393     hash->hashCount++;
394 
395     return BSL_SUCCESS;
396 }
397 
BSL_HASH_UpdateNode(const BSL_HASH_Hash * hash,BSL_HASH_Node * node,uintptr_t value,uint32_t valueSize)398 static int32_t BSL_HASH_UpdateNode(const BSL_HASH_Hash *hash, BSL_HASH_Node *node, uintptr_t value, uint32_t valueSize)
399 {
400     uintptr_t tmpValue;
401     void *tmpPtr = NULL;
402 
403     if (hash->valueFunc.dupFunc != NULL) {
404         tmpPtr = hash->valueFunc.dupFunc((void *)value, valueSize);
405         tmpValue = (uintptr_t)tmpPtr;
406         if (tmpValue == (uintptr_t)NULL) {
407             BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
408             return BSL_INTERNAL_EXCEPTION;
409         }
410 
411         if (hash->valueFunc.freeFunc != NULL) {
412             hash->valueFunc.freeFunc((void *)node->value);
413         }
414     } else {
415         tmpValue = value;
416     }
417 
418     node->value = tmpValue;
419 
420     return BSL_SUCCESS;
421 }
422 
BSL_HASH_CodeCheck(const BSL_HASH_Hash * hash,uintptr_t key,uint32_t * hashCode)423 static inline int32_t BSL_HASH_CodeCheck(const BSL_HASH_Hash *hash, uintptr_t key, uint32_t *hashCode)
424 {
425     if (hash == NULL) {
426         BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
427         return BSL_INTERNAL_EXCEPTION;
428     }
429 
430     *hashCode = hash->hashFunc(key, hash->bucketSize);
431     if (*hashCode >= hash->bucketSize) {
432         BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
433         return BSL_INTERNAL_EXCEPTION;
434     }
435 
436     return BSL_SUCCESS;
437 }
438 
BSL_HASH_Insert(BSL_HASH_Hash * hash,uintptr_t key,uint32_t keySize,uintptr_t value,uint32_t valueSize)439 int32_t BSL_HASH_Insert(BSL_HASH_Hash *hash, uintptr_t key, uint32_t keySize, uintptr_t value, uint32_t valueSize)
440 {
441     int32_t ret;
442     uint32_t hashCode;
443     BSL_HASH_Node *hashNode = NULL;
444     RawList *rawList = NULL;
445     BSL_CstlUserData inputKey;
446     BSL_CstlUserData inputValue;
447 
448     ret = BSL_HASH_CodeCheck(hash, key, &hashCode);
449     if (ret != BSL_SUCCESS) {
450         BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
451         return BSL_INTERNAL_EXCEPTION;
452     }
453 
454     rawList = &hash->listArray[hashCode];
455     hashNode = BSL_HASH_FindNode(rawList, key, hash->matchFunc);
456     if (hashNode != NULL) {
457         BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
458         return BSL_INTERNAL_EXCEPTION;
459     }
460 
461     inputKey.inputData = key;
462     inputKey.dataSize = keySize;
463     inputValue.inputData = value;
464     inputValue.dataSize = valueSize;
465 
466     return BSL_HASH_InsertNode(hash, rawList, &inputKey, &inputValue);
467 }
468 
BSL_HASH_Put(BSL_HASH_Hash * hash,uintptr_t key,uint32_t keySize,uintptr_t value,uint32_t valueSize,BSL_HASH_UpdateNodeFunc updateNodeFunc)469 int32_t BSL_HASH_Put(BSL_HASH_Hash *hash, uintptr_t key, uint32_t keySize, uintptr_t value, uint32_t valueSize,
470     BSL_HASH_UpdateNodeFunc updateNodeFunc)
471 {
472     int32_t ret;
473     uint32_t hashCode;
474     RawList *rawList = NULL;
475     BSL_HASH_Node *hashNode = NULL;
476     BSL_CstlUserData inputValue;
477     BSL_CstlUserData inputKey;
478 
479     ret = BSL_HASH_CodeCheck(hash, key, &hashCode);
480     if (ret != BSL_SUCCESS) {
481         BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
482         return BSL_INTERNAL_EXCEPTION;
483     }
484 
485     rawList = &hash->listArray[hashCode];
486     hashNode = BSL_HASH_FindNode(rawList, key, hash->matchFunc);
487     if (hashNode != NULL) {
488         if (updateNodeFunc != NULL) {
489             return updateNodeFunc(hash, hashNode, value, valueSize);
490         } else {
491             return BSL_HASH_UpdateNode(hash, hashNode, value, valueSize);
492         }
493     }
494 
495     inputKey.inputData = key;
496     inputKey.dataSize = keySize;
497     inputValue.inputData = value;
498     inputValue.dataSize = valueSize;
499 
500     return BSL_HASH_InsertNode(hash, rawList, &inputKey, &inputValue);
501 }
502 
BSL_HASH_At(const BSL_HASH_Hash * hash,uintptr_t key,uintptr_t * value)503 int32_t BSL_HASH_At(const BSL_HASH_Hash *hash, uintptr_t key, uintptr_t *value)
504 {
505     BSL_HASH_Node *hashNode = BSL_HASH_Find(hash, key);
506 
507     if (hashNode == BSL_HASH_IterEndGet(hash)) {
508         BSL_ERR_PUSH_ERROR(BSL_INTERNAL_EXCEPTION);
509         return BSL_INTERNAL_EXCEPTION;
510     }
511 
512     *value = hashNode->value;
513 
514     return BSL_SUCCESS;
515 }
516 
BSL_HASH_Find(const BSL_HASH_Hash * hash,uintptr_t key)517 BSL_HASH_Iterator BSL_HASH_Find(const BSL_HASH_Hash *hash, uintptr_t key)
518 {
519     int32_t ret;
520     uint32_t hashCode;
521     BSL_HASH_Node *hashNode = NULL;
522 
523     ret = BSL_HASH_CodeCheck(hash, key, &hashCode);
524     if (ret != BSL_SUCCESS) {
525         return hash == NULL ? NULL : BSL_HASH_IterEndGet(hash);
526     }
527 
528     hashNode = BSL_HASH_FindNode(&hash->listArray[hashCode], key, hash->matchFunc);
529     if (hashNode == NULL) {
530         return BSL_HASH_IterEndGet(hash);
531     }
532 
533     return hashNode;
534 }
535 
BSL_HASH_Empty(const BSL_HASH_Hash * hash)536 bool BSL_HASH_Empty(const BSL_HASH_Hash *hash)
537 {
538     if ((hash == NULL) || (hash->hashCount == 0U)) {
539         return true;
540     }
541 
542     return false;
543 }
544 
BSL_HASH_Size(const BSL_HASH_Hash * hash)545 uint32_t BSL_HASH_Size(const BSL_HASH_Hash *hash)
546 {
547     if (hash == NULL) {
548         return 0;
549     }
550 
551     return hash->hashCount;
552 }
553 
BSL_HASH_Erase(BSL_HASH_Hash * hash,uintptr_t key)554 BSL_HASH_Iterator BSL_HASH_Erase(BSL_HASH_Hash *hash, uintptr_t key)
555 {
556     uint32_t hashCode;
557     BSL_HASH_Node *hashNode = NULL;
558     BSL_HASH_Node *nextHashNode = NULL;
559     BSL_HASH_MatchFunc matchFunc = NULL;
560     BSL_HASH_CodeCalcFunc hashFunc = NULL;
561 
562     if (hash == NULL) {
563         return NULL;
564     }
565 
566     hashFunc = hash->hashFunc;
567     hashCode = hashFunc(key, hash->bucketSize);
568     if (hashCode >= hash->bucketSize) {
569         return BSL_HASH_IterEndGet(hash);
570     }
571 
572     matchFunc = hash->matchFunc;
573     hashNode = BSL_HASH_FindNode(&hash->listArray[hashCode], key, matchFunc);
574     if (hashNode == NULL) {
575         return BSL_HASH_IterEndGet(hash);
576     }
577 
578     nextHashNode = BSL_HASH_Next(hash, hashNode);
579     ListRawRemove(&hash->listArray[hashCode], &hashNode->node);
580     BSL_HASH_NodeFree(hash, hashNode);
581     --hash->hashCount;
582 
583     return nextHashNode;
584 }
585 
BSL_HASH_Clear(BSL_HASH_Hash * hash)586 void BSL_HASH_Clear(BSL_HASH_Hash *hash)
587 {
588     uint32_t i;
589     RawList *list = NULL;
590     BSL_HASH_Node *hashNode = NULL;
591     ListRawNode *rawListNode = NULL;
592 
593     if (hash == NULL) {
594         return;
595     }
596 
597     for (i = 0; i < hash->bucketSize; ++i) {
598         list = &hash->listArray[i];
599         while (!ListRawEmpty(list)) {
600             rawListNode = ListRawFront(list);
601             hashNode = BSL_CONTAINER_OF(rawListNode, BSL_HASH_Node, node);
602             ListRawRemove(list, rawListNode);
603             BSL_HASH_NodeFree(hash, hashNode);
604         }
605     }
606 
607     hash->hashCount = 0;
608 }
609 
BSL_HASH_Destory(BSL_HASH_Hash * hash)610 void BSL_HASH_Destory(BSL_HASH_Hash *hash)
611 {
612     if (hash == NULL) {
613         return;
614     }
615 
616     BSL_HASH_Clear(hash);
617     BSL_SAL_FREE(hash);
618 }
619 
BSL_HASH_IterBegin(const BSL_HASH_Hash * hash)620 BSL_HASH_Iterator BSL_HASH_IterBegin(const BSL_HASH_Hash *hash)
621 {
622     if (hash == NULL) {
623         return NULL;
624     }
625 
626     return BSL_HASH_Front(hash);
627 }
628 
BSL_HASH_IterEnd(const BSL_HASH_Hash * hash)629 BSL_HASH_Iterator BSL_HASH_IterEnd(const BSL_HASH_Hash *hash)
630 {
631     if (hash == NULL) {
632         return NULL;
633     }
634 
635     return BSL_HASH_IterEndGet(hash);
636 }
637 
BSL_HASH_IterNext(const BSL_HASH_Hash * hash,BSL_HASH_Iterator it)638 BSL_HASH_Iterator BSL_HASH_IterNext(const BSL_HASH_Hash *hash, BSL_HASH_Iterator it)
639 {
640     if ((hash == NULL) || (it == BSL_HASH_IterEnd(hash))) {
641         return BSL_HASH_IterEnd(hash);
642     }
643 
644     return BSL_HASH_Next(hash, it);
645 }
646 
BSL_HASH_HashIterKey(const BSL_HASH_Hash * hash,BSL_HASH_Iterator it)647 uintptr_t BSL_HASH_HashIterKey(const BSL_HASH_Hash *hash, BSL_HASH_Iterator it)
648 {
649     if (it == NULL || it == BSL_HASH_IterEnd(hash)) {
650         return 0;
651     }
652 
653     return it->key;
654 }
655 
BSL_HASH_IterValue(const BSL_HASH_Hash * hash,BSL_HASH_Iterator it)656 uintptr_t BSL_HASH_IterValue(const BSL_HASH_Hash *hash, BSL_HASH_Iterator it)
657 {
658     if (it == NULL || it == BSL_HASH_IterEnd(hash)) {
659         return 0;
660     }
661 
662     return it->value;
663 }
664 
665 #ifdef __cplusplus
666 }
667 #endif /* __cplusplus */
668 
669 #endif /* HITLS_BSL_HASH */
670