1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
19 /********************************************************************20**
21 Name: common hash functions
25 Desc: Hashing functions used by various layers.
26 (Newer version of functions in cm_bdy1)
28 Using hash lists in a product:
29 ------------------------------
31 Wherever a hash list is needed, a corresponding hash list
32 control point (CmHashListCp) should be declared. The structure
33 definition of the entries that belong to the hash list must
34 include a declaration of the hash list entry header
35 (CmHashListEnt) along with the key for the hash list (this
36 may be any scalar or structure type subfield of the entry).
37 For example, we need a hash list in a SAP to maintain a table
40 typedef struct xySAPCb (SAP control block)
43 CmHashListCp addrHlCp; (hash list for addresses)
47 typedef struct xyAddrEnt (hash list entry for an address)
50 CmHashListEnt hl; (hash list entry header)
52 XyAddr addr; (hash list key)
59 The functions available for using hash lists are defined
60 below. The accompanying comments explain the usage in detail.
62 Implementation details:
63 -----------------------
65 A hash list is identified by its control point
66 (CmHashListCp). This control point stores the characteristics
67 of the hash list as well as a pointer to the hash list bins.
68 The storage for the bins is allocated when the hash list is
69 initialized. Each bin is organized as a doubly linked list of
70 entries whose key maps to this bin. The hash function used to
71 map keys to a bin simply adds up all the octets of the key
72 and then divides the sum by the number of bins. Variable size
73 keys are allowed. Duplicate keys may be present if explicitly
74 allowed; if so, they can be retrieved by supplying a sequence
75 number in the find routine. A given structure may be attached
76 to more than one hash list if it contains multiple hash list
81 *********************************************************************21*/
84 #include <common_def.h>
91 /* forward references */
92 /* cm_hash_c_001.main_22: Fixing warnings on GCC compiler */
97 static S16 cmHashFuncBCD8 ARGS((CmHashListCp *hashListCp, uint8_t *key,
98 uint16_t keyLen, uint16_t *idx));
100 static S16 cmHashFuncConId ARGS((CmHashListCp *hashListCp, uint8_t *key,
101 uint16_t keyLen, uint16_t *idx));
103 static S16 cmHashFuncU32Mod ARGS((CmHashListCp *hashListCp, uint8_t *key,
104 uint16_t keyLen, uint16_t *idx));
106 static S16 cmHashFuncString ARGS((CmHashListCp *hashListCp, uint8_t *key,
107 uint16_t keyLen, uint16_t *idx));
109 static S16 cmHashFuncDefault ARGS((CmHashListCp *hashListCp, uint8_t *key,
110 uint16_t keyLen, uint16_t *idx));
112 static S16 cmHashFuncAnyKey ARGS((CmHashListCp *hashListCp, uint8_t *key,
113 uint16_t keyLen, uint16_t *idx));
115 static S16 cmHashMatchKey ARGS((uint8_t *key1, uint16_t keyLen1, uint8_t *key2, uint16_t keyLen2));
117 static S16 cmListInsert ARGS((CmListEnt *oldEntry, CmListEnt *newEntry));
119 static S16 cmListDelete ARGS((CmListEnt *entry));
121 /* cm_hash_c_001.main_22: Fixing warnings on GCC compiler */
122 static S16 cmHashFuncMult24 ARGS((CmHashListCp *hashListCp, uint8_t *key, uint16_t keyLen, uint16_t *idx));
124 static S16 cmHashFuncDirIdx ARGS((CmHashListCp *hashListCp, uint8_t *key, uint16_t keyLen, uint16_t *idx));
130 /* functions in other modules */
132 /* public variable declarations */
134 /* private variable declarations */
138 * private support functions
143 * Fun: cmHashFuncAnyKey
145 * Desc: Computes the hash list index (bin number) for a specified
146 * key of type CM_HASH_KEYTYPE_ANY.
148 * return index to hash table
150 * Ret: ROK - successful, *idx contains computed index
158 static S16 cmHashFuncAnyKey
160 CmHashListCp *hashListCp, /* hash list control point */
161 uint8_t *key, /* key string */
162 uint16_t keyLen, /* length of key string */
163 uint16_t *idx /* idx to return */
166 uint32_t a; /* hash variables */
167 uint32_t b; /* hash variables */
168 uint32_t c; /* hash variables */
169 uint32_t len; /* length */
171 /*cm_hash_c_001.main_23 : Fix for TRACE5 feature crash due to missing TRC MACRO*/
172 /* Set up the internal state */
173 len = keyLen; /* key length */
174 a = 0x9e3779b9; /* a = b = the golden ratio; an arbitrary value */
176 c = 0x12345678; /* some value */
178 /*---------------------------------------- handle most of the key */
181 a += (key[0] +((uint32_t)key[1]<<8) +((uint32_t)key[2]<<16) +((uint32_t)key[3]<<24));
182 b += (key[4] +((uint32_t)key[5]<<8) +((uint32_t)key[6]<<16) +((uint32_t)key[7]<<24));
183 c += (key[8] +((uint32_t)key[9]<<8) +((uint32_t)key[10]<<16)+((uint32_t)key[11]<<24));
184 CM_HASH_MIX(a, b, c);
185 key += 12; len -= 12;
188 /*------------------------------------- handle the last 11 bytes */
190 switch(len) /* all the case statements fall through */
192 case 11: c+=((uint32_t)key[10]<<24);
193 case 10: c+=((uint32_t)key[9]<<16);
194 case 9 : c+=((uint32_t)key[8]<<8);
195 /* the first byte of c is reserved for the keyLen */
196 case 8 : b+=((uint32_t)key[7]<<24);
197 case 7 : b+=((uint32_t)key[6]<<16);
198 case 6 : b+=((uint32_t)key[5]<<8);
200 case 4 : a+=((uint32_t)key[3]<<24);
201 case 3 : a+=((uint32_t)key[2]<<16);
202 case 2 : a+=((uint32_t)key[1]<<8);
204 /* case 0: nothing left to add */
207 /*-------------------------------------------- report the result */
209 /* if nmbBins is a power of 2, use shift, else use division */
210 if (hashListCp->binBitMask != CM_HASH_NOBITMASK)
211 *idx = (uint16_t) (c & hashListCp->binBitMask);
213 *idx = (uint16_t) (c % hashListCp->nmbBins);
216 } /* end of cmHashFuncAnyKey */
221 * Fun: cmHashFuncU32Mod
223 * Desc: Computes the hash list index (bin number) for a specified
224 * key of type CM_HASH_KEYTYPE_MOD.
226 * return (idx % hash_table_size);
228 * Ret: ROK - successful, *idx contains computed index
236 static S16 cmHashFuncU32Mod
238 CmHashListCp *hashListCp, /* hash list control point */
239 uint8_t *key, /* key string */
240 uint16_t keyLen, /* length of key string */
241 uint16_t *idx /* idx to return */
244 uint32_t sum; /* Sum of octets for hash function */
247 /* keyLen is marked Unused to remove compilation
251 sum = *((uint32_t *)key);
253 /* if nmbBins is a power of 2, use shift, else use division */
254 if (hashListCp->binBitMask != CM_HASH_NOBITMASK)
255 *idx = (uint16_t) (sum & hashListCp->binBitMask);
257 *idx = (uint16_t) (sum % hashListCp->nmbBins);
261 } /* end of cmHashFuncU32Mod () */
265 * Fun: cmHashFuncBCD8
267 * Desc: Computes the hash list index (bin number) for a specified
268 * key of type CM_HASH_KEYTYPE_BCD8.
271 * 1. Converts the 8 BCD coded octets into 2 uint32_ts
272 * 2. Adds 2 uint32_ts to get one uint32_t.
273 * 3. Apply uint32_tMod technique to get the index
274 * 4. Return the index
277 * Here we are no bothered if the keyLen is more than 8.
278 * We are interested only in the first 8 octets.
280 * Ret: ROK - successful, *idx contains computed index
288 static S16 cmHashFuncBCD8
290 CmHashListCp *hashListCp, /* hash list control point */
291 uint8_t *key, /* key string */
292 uint16_t keyLen, /* length of key string */
293 uint16_t *idx /* idx to return */
297 uint32_t firstUInt32 = 0; /* First uint32_t prepared for lower 4 octets */
298 uint32_t secondUInt32 = 0; /* Second uint32_t prepared for higher 4 octets */
299 uint32_t sum; /* Sum of the above 2 octets to get the index */
302 /* keyLen is marked Unused to remove compilation
306 /* Compute second uint32_t */
307 tmp16 = (uint16_t) PutHiByte(tmp16, (uint8_t) key[0]);
308 tmp16 = (uint16_t) PutLoByte(tmp16, (uint8_t) key[1]);
309 secondUInt32 = (uint32_t) PutHiWord(secondUInt32, (uint16_t) tmp16);
310 tmp16 = (uint16_t) PutHiByte(tmp16, (uint8_t) key[2]);
311 tmp16 = (uint16_t) PutLoByte(tmp16, (uint8_t) key[3]);
312 secondUInt32 = (uint32_t) PutLoWord(secondUInt32, (uint16_t) tmp16);
315 /* Compute first uint32_t */
316 tmp16 = (uint16_t) PutHiByte(tmp16, (uint8_t) key[4]);
317 tmp16 = (uint16_t) PutLoByte(tmp16, (uint8_t) key[5]);
318 firstUInt32 = (uint32_t) PutHiWord(firstUInt32, (uint16_t) tmp16);
319 tmp16 = (uint16_t) PutHiByte(tmp16, (uint8_t) key[6]);
320 tmp16 = (uint16_t) PutLoByte(tmp16, (uint8_t) key[7]);
321 firstUInt32 = (uint32_t) PutLoWord(firstUInt32, (uint16_t) tmp16);
323 sum = firstUInt32 + secondUInt32;
325 /* if nmbBins is a power of 2, use shift, else use division */
326 if (hashListCp->binBitMask != CM_HASH_NOBITMASK)
327 *idx = (uint16_t) (sum & hashListCp->binBitMask);
329 *idx = (uint16_t) (sum % hashListCp->nmbBins);
332 } /* end of cmHashFuncBCD8 () */
336 * Fun: cmHashFuncString
338 * Desc: Computes the hash list index (bin number) for a specified
339 * key of type CM_HASH_KEYTYPE_STR.
341 * for (length of string)
342 * idx = (31 * idx) + *string;
344 * return (idx % hash_table_size);
346 * Ret: ROK - successful, *idx contains computed index
354 static S16 cmHashFuncString
356 CmHashListCp *hashListCp, /* hash list control point */
357 uint8_t *key, /* key string */
358 uint16_t keyLen, /* length of key string */
359 uint16_t *idx /* idx to return */
362 uint16_t cntr; /* Index */
363 uint32_t sum; /* Sum of octets for hash function */
368 for (cntr = 0; cntr < keyLen; cntr++)
370 sum = (CM_STR_HASHFUNC_CONSTANT * sum) + key[cntr];
373 /* if nmbBins is a power of 2, use shift, else use division */
374 if (hashListCp->binBitMask != CM_HASH_NOBITMASK)
375 *idx = (uint16_t) (sum & hashListCp->binBitMask);
377 *idx = (uint16_t) (sum % hashListCp->nmbBins);
381 } /* end of cmHashFuncString () */
387 * Fun: cmHashFuncDefault
389 * Desc: Computes the hash list index (bin number) for a specified
390 * key of type CM_HASH_KEYTYPE_DEF.
392 * Adds up all the octets of the key string
393 * and divides the sum by the range to get the desired index.
395 * Ret: ROK - successful, *idx contains computed index
403 static S16 cmHashFuncDefault
405 CmHashListCp *hashListCp, /* hash list control point */
406 uint8_t *key, /* key string */
407 uint16_t keyLen, /* length of key string */
408 uint16_t *idx /* index to return */
411 uint32_t sum; /* sum of key string octets */
414 /* add all bytes of the key */
417 sum += (uint32_t) (*key++);
419 /* compute index by dividing the range into the sum */
421 /* if nmbBins is a power of 2, use shift, else use division */
422 if (hashListCp->binBitMask != CM_HASH_NOBITMASK)
423 *idx = (uint16_t) (sum & hashListCp->binBitMask);
425 *idx = (uint16_t) (sum % hashListCp->nmbBins);
429 } /* end of cmHashFuncDefault */
434 * Fun: cmHashFuncMult24
436 * Desc: Computes the hash list index (bin number) for a specified
437 * key of type CM_HASH_KEYTYPE_MULT24.
439 * Multiplies the given key (max k bits) with a constant
440 * multiplier and extracts p bits of the result, from the
441 * bit position k-1 to bit position k-p, to get the hash
442 * list index. p is such that 2^p is number of bins.
444 * The constant multiplier is the floor of A * 2^k, for
447 * This function uses a pre-computed constant multiplier
448 * CM_HASH_MULTMETHOD_CNST24, which is computed for
449 * A = (sqrt(5) - 1)/2, and k = 24 bits.
451 * This hashing method is explained in section 12.3.2 of
452 * "Introduction to Algorithms" by Thomas H. Cormen et al.,
455 * Ret: ROK - successful, *idx contains computed index
463 static S16 cmHashFuncMult24
465 CmHashListCp *hashListCp, /* hash list control point */
466 uint8_t *key, /* key string */
467 uint16_t keyLen, /* length of key string */
468 uint16_t *idx /* index to return */
471 uint32_t prod; /* (constant multiplier * key) */
472 uint8_t shift; /* Bits to be shifted to get index */
477 #if (ERRCLASS & ERRCLS_DEBUG)
478 /* error check on parameters */
479 if (hashListCp->binBitMask == CM_HASH_NOBITMASK)
483 prod = CM_HASH_MULT24_CONST * *((uint32_t *)key);
485 shift = CM_HASH_MULT24_BITPOS - hashListCp->nmbBinBits;
486 *idx = ((uint16_t) (prod & (hashListCp->binBitMask << shift))) >> shift;
489 } /* end of cmHashFuncMult24 */
496 * Fun: cmHashFuncConId
498 * Desc: Computes the hash list index (bin number) for a specified
499 * key of type CM_HASH_KEYTYPE_CONID.
501 * This function can be used for keys that are an integer whose
502 * size is uint8_t, uint16_t or uint32_t. Instead of adding all octets of the key,
503 * this fn computes the "index" of the bin in which the entry
504 * needs to be inserted by taking a modulo of the integer with the
505 * total number of bins.
506 * This function is typically suitable for a sequentially increasing
507 * number like suConnId/spConnId
509 * Ret: ROK - successful, *idx contains computed index
517 static S16 cmHashFuncConId
519 CmHashListCp *hashListCp, /* hash list control point */
520 uint8_t *key, /* key string */
521 uint16_t keyLen, /* length of key string */
522 uint16_t *idx /* index to return */
527 /* switch based on the length of the key */
530 case CM_HASHKEYLEN_UINT32:
531 if (hashListCp->binBitMask != CM_HASH_NOBITMASK)
532 *idx = (uint16_t) (((uint32_t) *((uint32_t *)key)) & hashListCp->binBitMask);
534 *idx = (uint16_t) (((uint32_t) *((uint32_t *)key)) % hashListCp->nmbBins);
537 case CM_HASHKEYLEN_UINT16:
538 if (hashListCp->binBitMask != CM_HASH_NOBITMASK)
539 *idx = (uint16_t) (((uint16_t)*((uint16_t *)key)) & hashListCp->binBitMask);
541 *idx = (uint16_t) (((uint16_t)*((uint16_t *)key)) % hashListCp->nmbBins);
544 case CM_HASHKEYLEN_UINT8:
545 if (hashListCp->binBitMask != CM_HASH_NOBITMASK)
546 *idx = (uint16_t) (((uint8_t)*((uint8_t *)key)) & hashListCp->binBitMask);
548 *idx = (uint16_t) (((uint8_t)*((uint8_t *)key)) % hashListCp->nmbBins);
556 } /* end of cmHashFuncConId */
562 * Fun: cmHashFuncDirIdx
564 * Desc: Computes the hash list index (bin number) for a specified
565 * key of type CM_HASH_KEYTYPE_DIRINDEX.
567 * The key is the hash table index.
569 * Ret: ROK - successful, *idx contains computed index
577 static S16 cmHashFuncDirIdx
579 CmHashListCp *hashListCp, /* hash list control point */
580 uint8_t *key, /* key string */
581 uint16_t keyLen, /* length of key string */
582 uint16_t *idx /* index to return */
589 *idx = *((uint16_t *) key);
592 } /* end of cmHashFuncDirIdx */
597 * Fun: cmHashMatchKey
599 * Desc: Compares two keys and determines if they match.
601 * Ret: ROK - match successful
602 * RFAILED - match failed (non-matching key values)
610 static S16 cmHashMatchKey
612 uint8_t *key1, /* first key string */
613 uint16_t keyLen1, /* length of first key string */
614 uint8_t *key2, /* second key string */
615 uint16_t keyLen2 /* length of second key string */
619 /* compare key lengths */
620 if (keyLen1 != keyLen2)
623 /* compare key strings */
624 return (cmMemcmp(key1, key2, (PTR) keyLen1));
625 } /* end of cmHashMatchKey */
632 * Desc: Adds an entry into a doubly linked list
634 * Ret: ROK - insertion successful
642 static S16 cmListInsert
644 CmListEnt *oldEntry, /* add new entry after this entry */
645 CmListEnt *newEntry /* new entry to add */
649 newEntry->next = oldEntry->next;
650 newEntry->prev = oldEntry;
651 oldEntry->next = newEntry;
652 (newEntry->next)->prev = newEntry;
655 } /* end of cmListInsert */
662 * Desc: Deletes an entry from a doubly linked list
664 * Ret: ROK - deletion successful
672 static S16 cmListDelete
674 CmListEnt *entry /* entry to delete */
681 if (entry->prev != NULLP)
682 (entry->prev)->next = entry->next;
684 if (entry->next != NULLP)
685 (entry->next)->prev = entry->prev;
688 } /* end of cmListDelete */
699 * Fun: cmHashListInit
701 * Desc: Initializes a hash list. Parameters are:
703 * hashListCp control point for hash list
704 * nmbBins number of bins in the hash list. Storage will
705 * be allocated for them from the indicated memory
707 * offset if the entries in this hash list are also going
708 * to be attached to another hash list, they will
709 * contain multiple hash list entry headers. The
710 * offset indicates the offset of the entry header
711 * for this hash list in the entry structure.
712 * dupFlg whether entries with duplicate keys are allowed
713 * to be inserted in the hash list.
714 * keyType indicates type of key which can be used to select
715 * different hash functions. Ignored in this
718 * pool for allocating storage for bins.
720 * Ret: ROK - initialization successful
721 * RFAILED - initialization failed, lack of memory
730 CmHashListCp *hashListCp, /* hash list to initialize */
731 uint16_t nmbBins, /* number of hash list bins */
732 uint16_t offset, /* offset of CmHashListEnt in entries */
733 Bool dupFlg, /* allow duplicate keys */
734 uint16_t keyType, /* key type for selecting hash fn */
735 Region region, /* memory region to allocate bins */
736 Pool pool /* memory pool to allocate bins */
740 #ifndef CM_MT_HASH_BIN
747 #if (ERRCLASS & ERRCLS_DEBUG)
748 /* error check on parameters */
749 if (hashListCp == NULLP)
753 /* initialize control point fields */
754 hashListCp->hl = NULLP;
755 hashListCp->region = region;
756 hashListCp->pool = pool;
757 hashListCp->nmbBins = 0;
758 hashListCp->binBitMask = CM_HASH_NOBITMASK;
759 hashListCp->nmbBinBits = 0;
760 #ifndef CM_MT_HASH_BIN
761 hashListCp->nmbEnt = 0;
763 hashListCp->offset = offset;
764 hashListCp->dupFlg = dupFlg;
765 hashListCp->keyType = keyType;
766 hashListCp->hashFunc = NULLP;
768 /* initialize hash function for this key type */
771 case CM_HASH_KEYTYPE_MULT24:
772 /* return failure if number of bins is not a power of 2 */
773 if (((nmbBins) & (nmbBins - 1)) != 0)
776 hashListCp->hashFunc = cmHashFuncMult24;
779 case CM_HASH_KEYTYPE_DIRIDX:
780 hashListCp->hashFunc = cmHashFuncDirIdx;
783 case CM_HASH_KEYTYPE_STR:
784 hashListCp->hashFunc = cmHashFuncString;
787 case CM_HASH_KEYTYPE_UINT32_MOD:
788 hashListCp->hashFunc = cmHashFuncU32Mod;
791 case CM_HASH_KEYTYPE_BCD8:
792 hashListCp->hashFunc = cmHashFuncBCD8;
795 case CM_HASH_KEYTYPE_ANY:
796 hashListCp->hashFunc = cmHashFuncAnyKey;
799 case CM_HASH_KEYTYPE_CONID:
800 hashListCp->hashFunc = cmHashFuncConId;
803 case CM_HASH_KEYTYPE_DEF: /* default hash function */
804 default: /* illegal key type */
805 hashListCp->hashFunc = cmHashFuncDefault;
809 /* allocate memory for bins */
812 #ifndef CM_MT_HASH_BIN
813 if (SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,region, pool, (Data **) &hashListCp->hl,
814 (Size) (nmbBins * sizeof(CmListEnt))) != ROK)
817 if (SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,region, pool, (Data **) &hashListCp->hl,
818 (Size) (nmbBins * sizeof(CmListBinEnt))) != ROK)
822 /* initialize bin pointers */
824 for(i = 0; i < nmbBins; i++)
826 #ifndef CM_MT_HASH_BIN
827 hl[i].next = hl[i].prev = &hl[i];
829 /* This initialization is being done as a part of checking
830 * the presence of empty/non-empty bins.
832 hl[i].next = hl[i].prev = (CmListEnt*)&hl[i];
837 /* initialize bin size */
838 hashListCp->nmbBins = nmbBins;
840 /* initialize bin bit mask */
841 if (((nmbBins) & (nmbBins - 1)) == 0)
845 /* number of bins is a power of 2 */
846 hashListCp->binBitMask = nmbBins - 1;
848 /* compute number of bits in the bit mask */
849 for (binBitMask = hashListCp->binBitMask; binBitMask; binBitMask >>= 1)
850 hashListCp->nmbBinBits++;
856 } /* end of cmHashListInit */
861 * Fun: cmHashListDeinit
863 * Desc: Deinitializes a hash list. Deallocates memory for bins
864 * and resets header fields. Parameters are:
866 * hashListCp control point for hash list
868 * Ret: ROK - successful
877 CmHashListCp *hashListCp /* hash list to deinitialize */
881 #if (ERRCLASS & ERRCLS_DEBUG)
882 /* error check on parameters */
883 if (hashListCp == NULLP)
887 /* deallocate memory for bins */
888 if (hashListCp->nmbBins)
889 #ifndef CM_MT_HASH_BIN
890 (Void) SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,hashListCp->region, hashListCp->pool,
891 (Data *) hashListCp->hl,
892 (Size) (hashListCp->nmbBins * sizeof(CmListEnt)));
894 (Void) SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,hashListCp->region, hashListCp->pool,
895 (Data *) hashListCp->hl,
896 (Size) (hashListCp->nmbBins * sizeof(CmListBinEnt)));
899 /* deinitialize control point fields */
900 hashListCp->hl = NULLP;
901 hashListCp->region = REGIONNC;
902 hashListCp->pool = 0;
903 hashListCp->nmbBins = 0;
904 hashListCp->binBitMask = CM_HASH_NOBITMASK;
905 #ifndef CM_MT_HASH_BIN
906 hashListCp->nmbEnt = 0;
908 hashListCp->offset = 0;
909 hashListCp->dupFlg = FALSE;
910 hashListCp->keyType = CM_HASH_KEYTYPE_DEF;
911 hashListCp->hashFunc = NULLP;
914 } /* end of cmHashListDeinit */
919 * Fun: cmHashListInsert
921 * Desc: Inserts a new entry in the hash list. Parameters are:
923 * hashListCp control point for hash list
924 * entry pointer to new entry to add in the hash list
925 * key pointer to key string in the new entry
926 * keyLen length of key string
928 * Ret: ROK - insertion successful
929 * ROKDUP - insertion failed (duplicate key not allowed)
930 * RFAILED - insertion failed (incorrect parameter values)
940 CmHashListCp *hashListCp, /* hash list to add to */
941 PTR entry, /* entry to add */
942 uint8_t *key, /* pointer to key */
943 uint16_t keyLen /* length of key */
946 CmHashListEnt *hashListEnt; /* pointer to hash list entry header */
947 PTR dupEntry; /* pointer to entry with duplicate key */
948 uint16_t idx; /* index for insertion into hash list */
951 #if (ERRCLASS & ERRCLS_DEBUG)
952 /* error check on parameters */
953 if ((hashListCp == NULLP) || (entry == NULLP) ||
954 (key == NULLP) || (keyLen == 0))
958 /* check for duplicates */
959 if (hashListCp->dupFlg == FALSE)
961 /* no duplicates allowed, check if key already exists */
962 if (cmHashListFind(hashListCp, key, keyLen, 0, &dupEntry) == ROK)
966 /* get pointer to hash list entry header */
967 hashListEnt = (CmHashListEnt *) (((uint8_t *) entry) + hashListCp->offset);
969 /* initialize hash list entry header */
970 hashListEnt->list.next = NULLP;
971 hashListEnt->list.prev = NULLP;
972 hashListEnt->keyLen = keyLen;
973 hashListEnt->key = key;
975 /* compute index for insertion */
976 if ((*hashListCp->hashFunc)(hashListCp, key, keyLen, &idx) != ROK)
979 hashListEnt->hashVal = idx;
981 /* insert into list */
982 cmListInsert(hashListCp->hl[idx].prev, &hashListEnt->list);
984 /* increment count of entries in hash list */
985 #ifndef CM_MT_HASH_BIN
986 hashListCp->nmbEnt++;
988 hashListCp->hl[idx].nmbEnt++;
989 #endif /* #ifndef CM_MT_HASH_BIN */
992 } /* end of cmHashListInsert */
997 * Fun: cmHashListDelete
999 * Desc: Deletes an entry from the hash list. Parameters are:
1001 * hashListCp control point for hash list
1002 * entry pointer to entry to delete from the hash list
1004 * Ret: ROK - deletion successful
1005 * RFAILED - deletion failed (incorrect parameter values)
1013 S16 cmHashListDelete
1015 CmHashListCp *hashListCp, /* hash list to delete from */
1016 PTR entry /* entry to delete */
1019 CmHashListEnt *hashListEnt; /* pointer to hash list entry header */
1020 #ifdef CM_MT_HASH_BIN
1021 uint16_t idx; /* index for selecting the right hash list bin */
1025 #if (ERRCLASS & ERRCLS_DEBUG)
1026 /* error check on parameters */
1027 if ((hashListCp == NULLP) || (entry == NULLP))
1031 /* get pointer to hash list entry header */
1032 hashListEnt = (CmHashListEnt *) (((uint8_t *) entry) + hashListCp->offset);
1034 /* check if entry is already deleted if yes then return OK */
1035 if((hashListEnt->list.next == NULLP) ||
1036 (hashListEnt->list.prev == NULLP))
1039 #ifdef CM_MT_HASH_BIN
1040 /* compute index for insertion */
1041 if ((*hashListCp->hashFunc)(hashListCp, hashListEnt->key,
1042 hashListEnt->keyLen, &idx) != ROK)
1044 #endif /* #ifdef CM_MT_HASH_BIN */
1046 /* delete entry from list */
1047 cmListDelete(&hashListEnt->list);
1049 /* reinitialize hash list entry header */
1050 hashListEnt->list.next = NULLP;
1051 hashListEnt->list.prev = NULLP;
1052 hashListEnt->keyLen = 0;
1053 hashListEnt->key = NULLP;
1054 hashListEnt->hashVal = 0;
1056 /* decrement count of entries in hash list */
1057 #ifndef CM_MT_HASH_BIN
1058 hashListCp->nmbEnt--;
1060 /* Find the right bin index and decrement the nmbEnt counter */
1061 hashListCp->hl[idx].nmbEnt--;
1062 #endif /* #ifndef CM_MT_HASH_BIN */
1065 } /* end of cmHashListDelete */
1070 * Fun: cmHashListFind
1072 * Desc: Finds an entry in the hash list. Parameters are:
1074 * hashListCp control point for hash list
1075 * key pointer to key string for search
1076 * keyLen length of key string
1077 * seqNmb sequence number in case duplicates allowed
1078 * entry pointer to found entry
1080 * Ret: ROK - find successful, *entry points to found entry
1081 * RFAILED - find failed, *entry is unchanged
1082 * (incorrect parameter values, key not found)
1092 CmHashListCp *hashListCp, /* hash list to search */
1093 uint8_t *key, /* pointer to key */
1094 uint16_t keyLen, /* length of key */
1095 uint16_t seqNmb, /* used in case of duplicate keys */
1096 PTR *entry /* entry to be returned */
1099 CmHashListEnt *hashListEnt; /* pointer to hash list entry header */
1100 #ifndef CM_MT_HASH_BIN
1101 CmListEnt *hashListBin; /* pointer to hash list bin */
1103 CmListBinEnt *hashListBin; /* pointer to hash list bin */
1104 uint16_t entCnt=0; /* counter for number of entries */
1106 uint16_t i; /* counter for sequence number */
1107 uint16_t idx; /* index for insertion into hash list */
1110 #if (ERRCLASS & ERRCLS_DEBUG)
1111 /* error check on parameters */
1112 if ((hashListCp == NULLP) || (key == NULLP) ||
1113 (keyLen == 0) || (entry == NULLP))
1117 /* compute hash table index */
1118 if ((*hashListCp->hashFunc)(hashListCp, key, keyLen, &idx) != ROK)
1121 /* search this bin for exact key match */
1122 hashListBin = &hashListCp->hl[idx];
1123 hashListEnt = (CmHashListEnt *) hashListBin->next;
1125 /* examine each entry in bin */
1127 #ifndef CM_MT_HASH_BIN
1128 while (hashListBin != (CmListEnt *) hashListEnt)
1130 for (entCnt=0; entCnt < hashListBin->nmbEnt; entCnt++)
1133 /* check if key matches */
1134 if (cmHashMatchKey(hashListEnt->key, hashListEnt->keyLen, key, keyLen)
1138 *entry = (PTR) (((uint8_t *) hashListEnt) - hashListCp->offset);
1140 /* check for duplicates */
1141 if (!hashListCp->dupFlg)
1144 /* for duplicate key, check sequence number */
1149 /* go to next entry */
1150 hashListEnt = (CmHashListEnt *) hashListEnt->list.next;
1153 /* no matching key found */
1155 } /* end of cmHashListFind */
1160 * Fun: cmHashListGetNext
1162 * Desc: Gets next entry in hash list with respect to the specified
1163 * previous entry. If previous entry is NULLP, gets first
1164 * entry in hash list. Parameters are:
1166 * hashListCp control point for hash list
1167 * prevEnt pointer to previous entry
1168 * entry pointer to next entry to be returned
1170 * Ret: ROK - get successful, *entry points to found entry
1171 * (at beginning of list or in the list)
1172 * RFAILED - get failed, *entry is unchanged
1173 * (incorrect parameter values)
1174 * ROKDNA - get failed, *entry is unchanged.
1177 * Notes: This function has to be used cautiously while the
1178 * CM Hash Module is being compiled with CM_MT_HASH_BIN.
1179 * In such cases, this function should be used only after
1180 * ensuring that none of the other threads are operating
1181 * on the common hash list.
1186 S16 cmHashListGetNext
1188 CmHashListCp *hashListCp, /* hash list to get from */
1189 PTR prevEnt, /* previous entry */
1190 PTR *entry /* entry to be returned */
1193 #ifndef CM_MT_HASH_BIN
1194 CmListEnt *hashListBin; /* temporary hash list bin pointer */
1196 CmListBinEnt *hashListBin; /* temporary hash list bin pointer */
1198 CmHashListEnt *hashListEnt; /* temporary hash list entry pointer */
1199 CmHashListEnt *prevListEnt; /* previous hash list entry pointer */
1200 uint16_t i; /* hash list counter */
1203 #if (ERRCLASS & ERRCLS_DEBUG)
1204 /* error check on parameters */
1205 if ((hashListCp == NULLP) || (entry == NULLP))
1209 /* check if need to get first entry */
1210 if (prevEnt == NULLP)
1212 /* get first entry in hash list */
1213 for (i = 0; i < hashListCp->nmbBins; i++)
1214 /* check for non-empty bin */
1215 #ifndef CM_MT_HASH_BIN
1216 if (hashListCp->hl[i].next != &hashListCp->hl[i])
1218 if (hashListCp->hl[i].next != (CmListEnt*)&hashListCp->hl[i])
1221 /* get first entry in bin */
1222 hashListEnt = (CmHashListEnt *) hashListCp->hl[i].next;
1224 /* requested entry is in nxtEnt */
1225 *entry = (PTR) (((uint8_t *) hashListEnt) - hashListCp->offset);
1230 /* no more entries */
1234 /* use previous entry to find next entry */
1236 /* get pointer to previous hash list entry header */
1237 prevListEnt = (CmHashListEnt *) (((uint8_t *) prevEnt) + hashListCp->offset);
1239 /* get index of previous entry */
1240 i = prevListEnt->hashVal;
1242 /* set pointers to get next entry */
1243 hashListBin = &hashListCp->hl[i];
1244 prevListEnt = (CmHashListEnt *) prevListEnt->list.next;
1247 /* check if more entries in this bin */
1248 if (prevListEnt != (CmHashListEnt *) hashListBin)
1250 /* found next entry */
1251 *entry = (PTR) (((uint8_t *) prevListEnt) - hashListCp->offset);
1256 /* no more entries in this bin, go to next bin, check if more bins */
1257 if (++i >= hashListCp->nmbBins)
1258 /* no more entries */
1261 /* reset pointers for next bin */
1262 hashListBin = &hashListCp->hl[i];
1263 prevListEnt = (CmHashListEnt *) hashListBin->next;
1266 /* no more entries */
1268 } /* end of cmHashListGetNext */
1270 #ifdef CM_MT_HASH_BIN
1274 * Fun: cmHashListBinGetNextEntry
1276 * Desc: Gets next entry in a given hash bin respect to the specified
1277 * previous entry. If previous entry is NULLP, gets first
1278 * entry in hash bin. Parameters are:
1280 * hashListCp control point for hash list
1281 * binIdx Bin Index to find the entry in
1282 * prevEnt pointer to previous entry
1283 * entry pointer to next entry to be returned
1285 * Ret: ROK - get successful, *entry points to found entry
1286 * (at beginning of list or in the list)
1287 * RFAILED - get failed, *entry is unchanged
1288 * (incorrect parameter values)
1289 * ROKDNA - get failed, *entry is unchanged.
1296 S16 cmHashListBinGetNextEntry
1298 CmHashListCp *hashListCp, /* hash list to get from */
1299 uint16_t binIdx, /* Bin Index to retreive the entry */
1300 PTR prevEnt, /* previous entry */
1301 PTR *entry /* entry to be returned */
1304 CmListBinEnt *hashListBin; /* temporary hash list bin pointer */
1305 CmHashListEnt *hashListEnt; /* temporary hash list entry pointer */
1306 CmHashListEnt *prevListEnt; /* previous hash list entry pointer */
1309 #if (ERRCLASS & ERRCLS_DEBUG)
1310 /* error check on parameters */
1311 if ((hashListCp == NULLP) || (entry == NULLP))
1315 /* check if need to get first entry */
1316 if (prevEnt == NULLP)
1318 /* get first entry in hash list */
1319 /* check for non-empty bin */
1320 if (hashListCp->hl[binIdx].next != (CmListEnt*)&hashListCp->hl[binIdx])
1322 /* get first entry in bin */
1323 hashListEnt = (CmHashListEnt *) hashListCp->hl[binIdx].next;
1325 /* requested entry is in nxtEnt */
1326 *entry = (PTR) (((uint8_t *) hashListEnt) - hashListCp->offset);
1331 /* no more entries */
1335 /* use previous entry to find next entry */
1337 /* get pointer to previous hash list entry header */
1338 prevListEnt = (CmHashListEnt *) (((uint8_t *) prevEnt) + hashListCp->offset);
1340 /* set pointers to get next entry */
1341 hashListBin = &hashListCp->hl[binIdx];
1342 prevListEnt = (CmHashListEnt *) prevListEnt->list.next;
1344 /* check if more entries in this bin */
1345 if (prevListEnt != (CmHashListEnt *) hashListBin)
1347 /* found next entry */
1348 *entry = (PTR) (((uint8_t *) prevListEnt) - hashListCp->offset);
1353 /* no more entries */
1355 } /* end of cmHashListBinGetNextEntry */
1361 * Fun: cmHashListQuery
1363 * Desc: Gets hash list attributes. Parameters are:
1365 * hashListCp control point for hash list
1366 * queryType type of attribute being queried
1367 * result result of query, to be returned
1369 * Ret: ROK - successful, *result contains query result
1370 * RFAILED - failed, *result unchanged (incorrect parameter values)
1372 * Notes: This function is obsoleted!
1373 * Use macros defined in cm_hash.h instead
1380 CmHashListCp *hashListCp, /* hash list to query */
1381 uint8_t queryType, /* type of query */
1382 uint16_t *result /* result of query */
1385 #ifdef CM_MT_HASH_BIN
1390 /* deal with queries that do not need hashListCp */
1392 #if (ERRCLASS & ERRCLS_DEBUG)
1393 /* error check on parameters */
1394 if (result == NULLP)
1398 /* respond depending on query type */
1399 if (queryType == CM_HASH_QUERYTYPE_BINSIZE)
1401 /* storage for each bin */
1402 #ifndef CM_MT_HASH_BIN
1403 *result = (uint16_t) sizeof(CmListEnt);
1405 *result = (uint16_t) sizeof(CmListBinEnt);
1410 /* deal with queries that do need hashListCp */
1412 #if (ERRCLASS & ERRCLS_DEBUG)
1413 /* error check on parameters */
1414 if (hashListCp == NULLP)
1418 /* respond depending on query type */
1421 case CM_HASH_QUERYTYPE_ENTRIES: /* current number of entries */
1422 #ifndef CM_MT_HASH_BIN
1423 *result = (uint16_t) hashListCp->nmbEnt;
1426 for (i=0; i < hashListCp->nmbBins; i++)
1428 *result += hashListCp->hl[i].nmbEnt;
1433 case CM_HASH_QUERYTYPE_BINS: /* number of bins */
1434 *result = (uint16_t) hashListCp->nmbBins;
1437 case CM_HASH_QUERYTYPE_OFFSET: /* offset of CmHashListEnt in entries */
1438 *result = (uint16_t) hashListCp->offset;
1441 case CM_HASH_QUERYTYPE_DUPFLG: /* allow duplicate keys */
1442 *result = (uint16_t) hashListCp->dupFlg;
1445 case CM_HASH_QUERYTYPE_KEYTYPE: /* key type for selecting hash functions */
1446 *result = (uint16_t) hashListCp->keyType;
1449 default: /* process other query types */
1453 /* illegal query type */
1455 } /* end of cmHashListQuery */
1457 #ifdef HASH_OPEN_ADDRESSING
1461 * Fun: cmHashListOAInsert
1463 * Desc: Inserts a new entry in the hash list with open addressing.
1466 * hashListCp control point for hash list
1467 * entry pointer to new entry to add in the hash list
1468 * key pointer to key string in the new entry
1469 * keyLen length of key string
1471 * Ret: ROK - insertion successful
1472 * ROKDUP - insertion failed (duplicate key not allowed)
1473 * RFAILED - insertion failed (incorrect parameter values)
1481 S16 cmHashListOAInsert
1483 CmHashListCp *hashListCp, /* hash table to add to */
1484 PTR entry, /* entry to add */
1485 uint8_t *key, /* pointer to key */
1486 uint16_t keyLen /* length of key */
1489 /* cm_hash_c_001.main_21. Modify. Compilation Issue resolved. */
1490 #ifndef CM_MT_HASH_BIN
1491 CmListEnt *hashBin; /* temporary hash list bin pointer */
1493 CmListBinEnt *hashBin; /* temporary hash list bin pointer */
1495 CmHashListEnt *hashListEnt; /* pointer to hash list entry header */
1496 uint16_t idx; /* index for insertion into hash list */
1497 uint16_t hashSize; /* hash size */
1499 /* cm_hash_c_001.main_21. Modify. Compilation Issue resolved. */
1503 #if (ERRCLASS & ERRCLS_DEBUG)
1504 /* error check on parameters */
1505 if ((hashListCp == NULLP) || (entry == NULLP) ||
1506 (key == NULLP) || (keyLen == 0))
1510 #ifndef CM_MT_HASH_BIN
1511 nmbEnt = hashListCp->nmbEnt;
1514 for (i=0; i < hashListCp->nmbBins; i++)
1516 nmbEnt += hashListCp->hl[i].nmbEnt;
1519 /* check if table is full */
1520 if (hashListCp->nmbBins == nmbEnt)
1523 /* get pointer to hash list entry header */
1524 hashListEnt = (CmHashListEnt *) (((uint8_t *) entry) + hashListCp->offset);
1526 /* initialize hash list entry header */
1527 hashListEnt->list.next = NULLP;
1528 hashListEnt->list.prev = NULLP;
1529 hashListEnt->keyLen = keyLen;
1530 hashListEnt->key = key;
1532 /* compute index for insertion */
1533 if ((*hashListCp->hashFunc)(hashListCp, key, keyLen, &idx) != ROK)
1539 hashSize = hashListCp->nmbBins;
1540 hashBin = &hashListCp->hl[idx];
1541 for (i = hashSize; i > 0; i--)
1543 if (hashBin->next == hashBin)
1545 if (++idx >= hashSize)
1548 hashBin = &hashListCp->hl[0];
1554 /* insert into list */
1555 if (cmListInsert(hashBin->prev, &hashListEnt->list) != ROK)
1558 hashListEnt->hashVal = idx;
1560 #ifndef CM_MT_HASH_BIN
1561 /* increment count of entries in hash list */
1562 hashListCp->nmbEnt++;
1568 } /* end of cmHashListOAInsert */
1571 #endif /* HASH_OPENADDRESSING */
1573 /**********************************************************************
1575 **********************************************************************/