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