7474#define SH_DESTROY SH_MAKE_NAME(destroy)
7575#define SH_RESET SH_MAKE_NAME(reset)
7676#define SH_INSERT SH_MAKE_NAME(insert)
77+ #define SH_INSERT_HASH SH_MAKE_NAME(insert_hash)
7778#define SH_DELETE SH_MAKE_NAME(delete)
7879#define SH_LOOKUP SH_MAKE_NAME(lookup)
80+ #define SH_LOOKUP_HASH SH_MAKE_NAME(lookup_hash)
7981#define SH_GROW SH_MAKE_NAME(grow)
8082#define SH_START_ITERATE SH_MAKE_NAME(start_iterate)
8183#define SH_START_ITERATE_AT SH_MAKE_NAME(start_iterate_at)
9193#define SH_DISTANCE_FROM_OPTIMAL SH_MAKE_NAME(distance)
9294#define SH_INITIAL_BUCKET SH_MAKE_NAME(initial_bucket)
9395#define SH_ENTRY_HASH SH_MAKE_NAME(entry_hash)
96+ #define SH_INSERT_HASH_INTERNAL SH_MAKE_NAME(insert_hash_internal)
97+ #define SH_LOOKUP_HASH_INTERNAL SH_MAKE_NAME(lookup_hash_internal)
9498
9599/* generate forward declarations necessary to use the hash table */
96100#ifdef SH_DECLARE
@@ -144,7 +148,11 @@ SH_SCOPE void SH_DESTROY(SH_TYPE * tb);
144148SH_SCOPE void SH_RESET (SH_TYPE * tb );
145149SH_SCOPE void SH_GROW (SH_TYPE * tb , uint32 newsize );
146150SH_SCOPE SH_ELEMENT_TYPE * SH_INSERT (SH_TYPE * tb , SH_KEY_TYPE key , bool * found );
151+ SH_SCOPE SH_ELEMENT_TYPE * SH_INSERT_HASH (SH_TYPE * tb , SH_KEY_TYPE key ,
152+ uint32 hash , bool * found );
147153SH_SCOPE SH_ELEMENT_TYPE * SH_LOOKUP (SH_TYPE * tb , SH_KEY_TYPE key );
154+ SH_SCOPE SH_ELEMENT_TYPE * SH_LOOKUP_HASH (SH_TYPE * tb , SH_KEY_TYPE key ,
155+ uint32 hash );
148156SH_SCOPE bool SH_DELETE (SH_TYPE * tb , SH_KEY_TYPE key );
149157SH_SCOPE void SH_START_ITERATE (SH_TYPE * tb , SH_ITERATOR * iter );
150158SH_SCOPE void SH_START_ITERATE_AT (SH_TYPE * tb , SH_ITERATOR * iter , uint32 at );
@@ -492,14 +500,12 @@ SH_GROW(SH_TYPE * tb, uint32 newsize)
492500}
493501
494502/*
495- * Insert the key key into the hash-table, set *found to true if the key
496- * already exists, false otherwise. Returns the hash-table entry in either
497- * case.
503+ * This is a separate static inline function, so it can be reliably be inlined
504+ * into its wrapper functions even if SH_SCOPE is extern.
498505 */
499- SH_SCOPE SH_ELEMENT_TYPE *
500- SH_INSERT (SH_TYPE * tb , SH_KEY_TYPE key , bool * found )
506+ static inline SH_ELEMENT_TYPE *
507+ SH_INSERT_HASH_INTERNAL (SH_TYPE * tb , SH_KEY_TYPE key , uint32 hash , bool * found )
501508{
502- uint32 hash = SH_HASH_KEY (tb , key );
503509 uint32 startelem ;
504510 uint32 curelem ;
505511 SH_ELEMENT_TYPE * data ;
@@ -664,12 +670,36 @@ SH_INSERT(SH_TYPE * tb, SH_KEY_TYPE key, bool *found)
664670}
665671
666672/*
667- * Lookup up entry in hash table. Returns NULL if key not present.
673+ * Insert the key key into the hash-table, set *found to true if the key
674+ * already exists, false otherwise. Returns the hash-table entry in either
675+ * case.
668676 */
669677SH_SCOPE SH_ELEMENT_TYPE *
670- SH_LOOKUP (SH_TYPE * tb , SH_KEY_TYPE key )
678+ SH_INSERT (SH_TYPE * tb , SH_KEY_TYPE key , bool * found )
679+ {
680+ uint32 hash = SH_HASH_KEY (tb , key );
681+
682+ return SH_INSERT_HASH_INTERNAL (tb , key , hash , found );
683+ }
684+
685+ /*
686+ * Insert the key key into the hash-table using an already-calculated
687+ * hash. Set *found to true if the key already exists, false
688+ * otherwise. Returns the hash-table entry in either case.
689+ */
690+ SH_SCOPE SH_ELEMENT_TYPE *
691+ SH_INSERT_HASH (SH_TYPE * tb , SH_KEY_TYPE key , uint32 hash , bool * found )
692+ {
693+ return SH_INSERT_HASH_INTERNAL (tb , key , hash , found );
694+ }
695+
696+ /*
697+ * This is a separate static inline function, so it can be reliably be inlined
698+ * into its wrapper functions even if SH_SCOPE is extern.
699+ */
700+ static inline SH_ELEMENT_TYPE *
701+ SH_LOOKUP_HASH_INTERNAL (SH_TYPE * tb , SH_KEY_TYPE key , uint32 hash )
671702{
672- uint32 hash = SH_HASH_KEY (tb , key );
673703 const uint32 startelem = SH_INITIAL_BUCKET (tb , hash );
674704 uint32 curelem = startelem ;
675705
@@ -698,6 +728,28 @@ SH_LOOKUP(SH_TYPE * tb, SH_KEY_TYPE key)
698728 }
699729}
700730
731+ /*
732+ * Lookup up entry in hash table. Returns NULL if key not present.
733+ */
734+ SH_SCOPE SH_ELEMENT_TYPE *
735+ SH_LOOKUP (SH_TYPE * tb , SH_KEY_TYPE key )
736+ {
737+ uint32 hash = SH_HASH_KEY (tb , key );
738+
739+ return SH_LOOKUP_HASH_INTERNAL (tb , key , hash );
740+ }
741+
742+ /*
743+ * Lookup up entry in hash table using an already-calculated hash.
744+ *
745+ * Returns NULL if key not present.
746+ */
747+ SH_SCOPE SH_ELEMENT_TYPE *
748+ SH_LOOKUP_HASH (SH_TYPE * tb , SH_KEY_TYPE key , uint32 hash )
749+ {
750+ return SH_LOOKUP_HASH_INTERNAL (tb , key , hash );
751+ }
752+
701753/*
702754 * Delete entry from hash table. Returns whether to-be-deleted key was
703755 * present.
@@ -971,8 +1023,10 @@ SH_STAT(SH_TYPE * tb)
9711023#undef SH_DESTROY
9721024#undef SH_RESET
9731025#undef SH_INSERT
1026+ #undef SH_INSERT_HASH
9741027#undef SH_DELETE
9751028#undef SH_LOOKUP
1029+ #undef SH_LOOKUP_HASH
9761030#undef SH_GROW
9771031#undef SH_START_ITERATE
9781032#undef SH_START_ITERATE_AT
@@ -989,3 +1043,5 @@ SH_STAT(SH_TYPE * tb)
9891043#undef SH_PREV
9901044#undef SH_DISTANCE_FROM_OPTIMAL
9911045#undef SH_ENTRY_HASH
1046+ #undef SH_INSERT_HASH_INTERNAL
1047+ #undef SH_LOOKUP_HASH_INTERNAL
0 commit comments