11/*
2- Copyright (c) 2003-2018 , Troy D. Hanson http ://troydhanson.github.com /uthash/
2+ Copyright (c) 2003-2025 , Troy D. Hanson https ://troydhanson.github.io /uthash/
33All rights reserved.
44
55Redistribution and use in source and binary forms, with or without
@@ -24,12 +24,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2424#ifndef UTHASH_H
2525#define UTHASH_H
2626
27- #define UTHASH_VERSION 2.1 .0
27+ #define UTHASH_VERSION 2.3 .0
2828
2929#include <string.h> /* memcmp, memset, strlen */
3030#include <stddef.h> /* ptrdiff_t */
3131#include <stdlib.h> /* exit */
3232
33+ #if defined(HASH_NO_STDINT ) && HASH_NO_STDINT
34+ /* The user doesn't have <stdint.h>, and must figure out their own way
35+ to provide definitions for uint8_t and uint32_t. */
36+ #else
37+ #include <stdint.h> /* uint8_t, uint32_t */
38+ #endif
39+
3340/* These macros use decltype or the earlier __typeof GNU extension.
3441 As decltype is only available in newer compilers (VS2010 or gcc 4.3+
3542 when compiling c++ source) this code uses whatever method is needed
@@ -41,6 +48,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4148#else /* VS2008 or older (or VS2010 in C mode) */
4249#define NO_DECLTYPE
4350#endif
51+ #elif defined(__MCST__ ) /* Elbrus C Compiler */
52+ #define DECLTYPE (x ) (__typeof(x))
4453#elif defined(__BORLANDC__ ) || defined(__ICCARM__ ) || defined(__LCC__ ) || defined(__WATCOMC__ )
4554#define NO_DECLTYPE
4655#else /* GNU, Sun and other compilers */
6271} while (0)
6372#endif
6473
65- /* a number of the hash function use uint32_t which isn't defined on Pre VS2010 */
66- #if defined(_WIN32 )
67- #if defined(_MSC_VER ) && _MSC_VER >= 1600
68- #include <stdint.h>
69- #elif defined(__WATCOMC__ ) || defined(__MINGW32__ ) || defined(__CYGWIN__ )
70- #include <stdint.h>
71- #else
72- typedef unsigned int uint32_t ;
73- typedef unsigned char uint8_t ;
74- #endif
75- #elif defined(__GNUC__ ) && !defined(__VXWORKS__ )
76- #include <stdint.h>
77- #else
78- typedef unsigned int uint32_t ;
79- typedef unsigned char uint8_t ;
80- #endif
81-
8274#ifndef uthash_malloc
8375#define uthash_malloc (sz ) malloc(sz) /* malloc fcn */
8476#endif
@@ -92,15 +84,12 @@ typedef unsigned char uint8_t;
9284#define uthash_strlen (s ) strlen(s)
9385#endif
9486
95- #ifdef uthash_memcmp
96- /* This warning will not catch programs that define uthash_memcmp AFTER including uthash.h. */
97- #warning "uthash_memcmp is deprecated; please use HASH_KEYCMP instead"
98- #else
99- #define uthash_memcmp (a ,b ,n ) memcmp(a,b,n)
87+ #ifndef HASH_FUNCTION
88+ #define HASH_FUNCTION (keyptr ,keylen ,hashv ) HASH_JEN(keyptr, keylen, hashv)
10089#endif
10190
10291#ifndef HASH_KEYCMP
103- #define HASH_KEYCMP (a ,b ,n ) uthash_memcmp (a,b,n)
92+ #define HASH_KEYCMP (a ,b ,n ) memcmp (a,b,n)
10493#endif
10594
10695#ifndef uthash_noexpand_fyi
@@ -144,7 +133,7 @@ typedef unsigned char uint8_t;
144133/* calculate the element whose hash handle address is hhp */
145134#define ELMT_FROM_HH (tbl ,hhp ) ((void*)(((char*)(hhp)) - ((tbl)->hho)))
146135/* calculate the hash handle from element address elp */
147- #define HH_FROM_ELMT (tbl ,elp ) ((UT_hash_handle *)(void *)(((char*)(elp)) + ((tbl)->hho)))
136+ #define HH_FROM_ELMT (tbl ,elp ) ((UT_hash_handle*)(void*)(((char*)(elp)) + ((tbl)->hho)))
148137
149138#define HASH_ROLLBACK_BKT (hh , head , itemptrhh ) \
150139do { \
158147
159148#define HASH_VALUE (keyptr ,keylen ,hashv ) \
160149do { \
161- HASH_FCN (keyptr, keylen, hashv); \
150+ HASH_FUNCTION (keyptr, keylen, hashv); \
162151} while (0)
163152
164153#define HASH_FIND_BYHASHVALUE (hh ,head ,keyptr ,keylen ,hashval ,out ) \
@@ -167,17 +156,20 @@ do {
167156 if (head) { \
168157 unsigned _hf_bkt; \
169158 HASH_TO_BKT(hashval, (head)->hh.tbl->num_buckets, _hf_bkt); \
170- if (HASH_BLOOM_TEST((head)->hh.tbl, hashval) != 0 ) { \
159+ if (HASH_BLOOM_TEST((head)->hh.tbl, hashval)) { \
171160 HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], keyptr, keylen, hashval, out); \
172161 } \
173162 } \
174163} while (0)
175164
176165#define HASH_FIND (hh ,head ,keyptr ,keylen ,out ) \
177166do { \
178- unsigned _hf_hashv; \
179- HASH_VALUE(keyptr, keylen, _hf_hashv); \
180- HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out); \
167+ (out) = NULL; \
168+ if (head) { \
169+ unsigned _hf_hashv; \
170+ HASH_VALUE(keyptr, keylen, _hf_hashv); \
171+ HASH_FIND_BYHASHVALUE(hh, head, keyptr, keylen, _hf_hashv, out); \
172+ } \
181173} while (0)
182174
183175#ifdef HASH_BLOOM
201193} while (0)
202194
203195#define HASH_BLOOM_BITSET (bv ,idx ) (bv[(idx)/8U] |= (1U << ((idx)%8U)))
204- #define HASH_BLOOM_BITTEST (bv ,idx ) (bv[(idx)/8U] & (1U << ((idx)%8U)))
196+ #define HASH_BLOOM_BITTEST (bv ,idx ) (( bv[(idx)/8U] & (1U << ((idx)%8U))) != 0 )
205197
206198#define HASH_BLOOM_ADD (tbl ,hashv ) \
207199 HASH_BLOOM_BITSET((tbl)->bloom_bv, ((hashv) & (uint32_t)((1UL << (tbl)->bloom_nbits) - 1U)))
213205#define HASH_BLOOM_MAKE (tbl ,oomed )
214206#define HASH_BLOOM_FREE (tbl )
215207#define HASH_BLOOM_ADD (tbl ,hashv )
216- #define HASH_BLOOM_TEST (tbl ,hashv ) (1)
208+ #define HASH_BLOOM_TEST (tbl ,hashv ) 1
217209#define HASH_BLOOM_BYTELEN 0U
218210#endif
219211
405397do { \
406398 IF_HASH_NONFATAL_OOM( int _ha_oomed = 0; ) \
407399 (add)->hh.hashv = (hashval); \
408- (add)->hh.key = (char *) (keyptr); \
400+ (add)->hh.key = (const void *) (keyptr); \
409401 (add)->hh.keylen = (unsigned) (keylen_in); \
410402 if (!(head)) { \
411403 (add)->hh.next = NULL; \
457449
458450#define HASH_DELETE_HH (hh ,head ,delptrhh ) \
459451do { \
460- struct UT_hash_handle *_hd_hh_del = (delptrhh); \
452+ const struct UT_hash_handle *_hd_hh_del = (delptrhh); \
461453 if ((_hd_hh_del->prev == NULL) && (_hd_hh_del->next == NULL)) { \
462454 HASH_BLOOM_FREE((head)->hh.tbl); \
463455 uthash_free((head)->hh.tbl->buckets, \
519511 * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined.
520512 */
521513#ifdef HASH_DEBUG
522- #define HASH_OOPS (...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0)
514+ #include <stdio.h> /* fprintf, stderr */
515+ #define HASH_OOPS (...) do { fprintf(stderr, __VA_ARGS__); exit(-1); } while (0)
523516#define HASH_FSCK (hh ,head ,where ) \
524517do { \
525518 struct UT_hash_handle *_thh; \
@@ -586,13 +579,6 @@ do {
586579#define HASH_EMIT_KEY (hh ,head ,keyptr ,fieldlen )
587580#endif
588581
589- /* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */
590- #ifdef HASH_FUNCTION
591- #define HASH_FCN HASH_FUNCTION
592- #else
593- #define HASH_FCN HASH_JEN
594- #endif
595-
596582/* The Bernstein hash function, used in Perl prior to v5.6. Note (x<<5+x)=x*33. */
597583#define HASH_BER (key ,keylen ,hashv ) \
598584do { \
606592
607593
608594/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at
609- * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */
595+ * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx
596+ * (archive link: https://archive.is/Ivcan )
597+ */
610598#define HASH_SAX (key ,keylen ,hashv ) \
611599do { \
612600 unsigned _sx_i; \
691679 case 4 : _hj_i += ( (unsigned )_hj_key [3 ] << 24 ); /* FALLTHROUGH */ \
692680 case 3 : _hj_i += ( (unsigned )_hj_key [2 ] << 16 ); /* FALLTHROUGH */ \
693681 case 2 : _hj_i += ( (unsigned )_hj_key [1 ] << 8 ); /* FALLTHROUGH */ \
694- case 1 : _hj_i += _hj_key [0 ]; \
682+ case 1 : _hj_i += _hj_key [0 ]; /* FALLTHROUGH */ \
683+ default : ; \
695684 } \
696685 HASH_JEN_MIX (_hj_i , _hj_j , hashv ); \
697686} while (0 )
739728 case 1 : hashv += * _sfh_key ; \
740729 hashv ^= hashv << 10 ; \
741730 hashv += hashv >> 1 ; \
731+ break ; \
732+ default : ; \
742733 } \
743734 \
744735 /* Force "avalanching" of final 127 bits */ \
@@ -750,87 +741,6 @@ do {
750741 hashv += hashv >> 6 ; \
751742} while (0 )
752743
753- #ifdef HASH_USING_NO_STRICT_ALIASING
754- /* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads.
755- * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error.
756- * MurmurHash uses the faster approach only on CPU's where we know it's safe.
757- *
758- * Note the preprocessor built-in defines can be emitted using:
759- *
760- * gcc -m64 -dM -E - < /dev/null (on gcc)
761- * cc -## a.c (where a.c is a simple test file) (Sun Studio)
762- */
763- #if (defined(__i386__ ) || defined(__x86_64__ ) || defined(_M_IX86 ))
764- #define MUR_GETBLOCK (p ,i ) p[i]
765- #else /* non intel */
766- #define MUR_PLUS0_ALIGNED (p ) (((unsigned long)p & 3UL) == 0UL)
767- #define MUR_PLUS1_ALIGNED (p ) (((unsigned long)p & 3UL) == 1UL)
768- #define MUR_PLUS2_ALIGNED (p ) (((unsigned long)p & 3UL) == 2UL)
769- #define MUR_PLUS3_ALIGNED (p ) (((unsigned long)p & 3UL) == 3UL)
770- #define WP (p ) ((uint32_t*)((unsigned long)(p) & ~3UL))
771- #if (defined(__BIG_ENDIAN__ ) || defined(SPARC ) || defined(__ppc__ ) || defined(__ppc64__ ))
772- #define MUR_THREE_ONE (p ) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24))
773- #define MUR_TWO_TWO (p ) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16))
774- #define MUR_ONE_THREE (p ) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8))
775- #else /* assume little endian non-intel */
776- #define MUR_THREE_ONE (p ) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24))
777- #define MUR_TWO_TWO (p ) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16))
778- #define MUR_ONE_THREE (p ) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8))
779- #endif
780- #define MUR_GETBLOCK (p ,i ) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \
781- (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \
782- (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \
783- MUR_ONE_THREE(p))))
784- #endif
785- #define MUR_ROTL32 (x ,r ) (((x) << (r)) | ((x) >> (32 - (r))))
786- #define MUR_FMIX (_h ) \
787- do { \
788- _h ^= _h >> 16; \
789- _h *= 0x85ebca6bu; \
790- _h ^= _h >> 13; \
791- _h *= 0xc2b2ae35u; \
792- _h ^= _h >> 16; \
793- } while (0)
794-
795- #define HASH_MUR (key ,keylen ,hashv ) \
796- do { \
797- const uint8_t *_mur_data = (const uint8_t*)(key); \
798- const int _mur_nblocks = (int)(keylen) / 4; \
799- uint32_t _mur_h1 = 0xf88D5353u; \
800- uint32_t _mur_c1 = 0xcc9e2d51u; \
801- uint32_t _mur_c2 = 0x1b873593u; \
802- uint32_t _mur_k1 = 0; \
803- const uint8_t *_mur_tail; \
804- const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+(_mur_nblocks*4)); \
805- int _mur_i; \
806- for (_mur_i = -_mur_nblocks; _mur_i != 0; _mur_i++) { \
807- _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \
808- _mur_k1 *= _mur_c1; \
809- _mur_k1 = MUR_ROTL32(_mur_k1,15); \
810- _mur_k1 *= _mur_c2; \
811- \
812- _mur_h1 ^= _mur_k1; \
813- _mur_h1 = MUR_ROTL32(_mur_h1,13); \
814- _mur_h1 = (_mur_h1*5U) + 0xe6546b64u; \
815- } \
816- _mur_tail = (const uint8_t*)(_mur_data + (_mur_nblocks*4)); \
817- _mur_k1=0; \
818- switch ((keylen) & 3U) { \
819- case 0: break; \
820- case 3: _mur_k1 ^= (uint32_t)_mur_tail[2] << 16; /* FALLTHROUGH */ \
821- case 2 : _mur_k1 ^= (uint32_t )_mur_tail [1 ] << 8 ; /* FALLTHROUGH */ \
822- case 1 : _mur_k1 ^= (uint32_t )_mur_tail [0 ]; \
823- _mur_k1 *= _mur_c1 ; \
824- _mur_k1 = MUR_ROTL32 (_mur_k1 ,15 ); \
825- _mur_k1 *= _mur_c2 ; \
826- _mur_h1 ^= _mur_k1 ; \
827- } \
828- _mur_h1 ^= (uint32_t )(keylen ); \
829- MUR_FMIX (_mur_h1 ); \
830- hashv = _mur_h1 ; \
831- } while (0 )
832- #endif /* HASH_USING_NO_STRICT_ALIASING */
833-
834744/* iterate over items in a known bucket to find desired item */
835745#define HASH_FIND_IN_BKT (tbl ,hh ,head ,keyptr ,keylen_in ,hashval ,out ) \
836746do { \
841751 } \
842752 while ((out) != NULL) { \
843753 if ((out)->hh.hashv == (hashval) && (out)->hh.keylen == (keylen_in)) { \
844- if (HASH_KEYCMP((out)->hh.key, keyptr, keylen_in) == 0) { \
754+ if (HASH_KEYCMP((out)->hh.key, keyptr, keylen_in) == 0) { \
845755 break; \
846756 } \
847757 } \
@@ -927,12 +837,12 @@ do {
927837 struct UT_hash_handle *_he_thh, *_he_hh_nxt; \
928838 UT_hash_bucket *_he_new_buckets, *_he_newbkt; \
929839 _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \
930- 2UL * (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \
840+ sizeof(struct UT_hash_bucket) * (tbl)->num_buckets * 2U); \
931841 if (!_he_new_buckets) { \
932842 HASH_RECORD_OOM(oomed); \
933843 } else { \
934844 uthash_bzero(_he_new_buckets, \
935- 2UL * (tbl)->num_buckets * sizeof(struct UT_hash_bucket)); \
845+ sizeof(struct UT_hash_bucket) * (tbl)->num_buckets * 2U); \
936846 (tbl)->ideal_chain_maxlen = \
937847 ((tbl)->num_items >> ((tbl)->log2_num_buckets+1U)) + \
938848 ((((tbl)->num_items & (((tbl)->num_buckets*2U)-1U)) != 0U) ? 1U : 0U); \
@@ -1080,7 +990,7 @@ do {
1080990 _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \
1081991 if (cond(_elt)) { \
1082992 IF_HASH_NONFATAL_OOM( int _hs_oomed = 0; ) \
1083- _dst_hh = (UT_hash_handle*)((( char*)_elt) + _dst_hho); \
993+ _dst_hh = (UT_hash_handle*)(void*)((( char*)_elt) + _dst_hho); \
1084994 _dst_hh->key = _src_hh->key; \
1085995 _dst_hh->keylen = _src_hh->keylen; \
1086996 _dst_hh->hashv = _src_hh->hashv; \
@@ -1219,7 +1129,7 @@ typedef struct UT_hash_handle {
12191129 void * next ; /* next element in app order */
12201130 struct UT_hash_handle * hh_prev ; /* previous hh in bucket order */
12211131 struct UT_hash_handle * hh_next ; /* next hh in bucket order */
1222- void * key ; /* ptr to enclosing struct's key */
1132+ const void * key ; /* ptr to enclosing struct's key */
12231133 unsigned keylen ; /* enclosing struct's key len */
12241134 unsigned hashv ; /* result of hash-fcn(key) */
12251135} UT_hash_handle ;
0 commit comments