74
74
#define SH_DESTROY SH_MAKE_NAME(destroy)
75
75
#define SH_RESET SH_MAKE_NAME(reset)
76
76
#define SH_INSERT SH_MAKE_NAME(insert)
77
+ #define SH_INSERT_HASH SH_MAKE_NAME(insert_hash)
77
78
#define SH_DELETE SH_MAKE_NAME(delete)
78
79
#define SH_LOOKUP SH_MAKE_NAME(lookup)
80
+ #define SH_LOOKUP_HASH SH_MAKE_NAME(lookup_hash)
79
81
#define SH_GROW SH_MAKE_NAME(grow)
80
82
#define SH_START_ITERATE SH_MAKE_NAME(start_iterate)
81
83
#define SH_START_ITERATE_AT SH_MAKE_NAME(start_iterate_at)
91
93
#define SH_DISTANCE_FROM_OPTIMAL SH_MAKE_NAME(distance)
92
94
#define SH_INITIAL_BUCKET SH_MAKE_NAME(initial_bucket)
93
95
#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)
94
98
95
99
/* generate forward declarations necessary to use the hash table */
96
100
#ifdef SH_DECLARE
@@ -144,7 +148,11 @@ SH_SCOPE void SH_DESTROY(SH_TYPE * tb);
144
148
SH_SCOPE void SH_RESET (SH_TYPE * tb );
145
149
SH_SCOPE void SH_GROW (SH_TYPE * tb , uint32 newsize );
146
150
SH_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 );
147
153
SH_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 );
148
156
SH_SCOPE bool SH_DELETE (SH_TYPE * tb , SH_KEY_TYPE key );
149
157
SH_SCOPE void SH_START_ITERATE (SH_TYPE * tb , SH_ITERATOR * iter );
150
158
SH_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)
492
500
}
493
501
494
502
/*
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.
498
505
*/
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 )
501
508
{
502
- uint32 hash = SH_HASH_KEY (tb , key );
503
509
uint32 startelem ;
504
510
uint32 curelem ;
505
511
SH_ELEMENT_TYPE * data ;
@@ -664,12 +670,36 @@ SH_INSERT(SH_TYPE * tb, SH_KEY_TYPE key, bool *found)
664
670
}
665
671
666
672
/*
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.
668
676
*/
669
677
SH_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 )
671
702
{
672
- uint32 hash = SH_HASH_KEY (tb , key );
673
703
const uint32 startelem = SH_INITIAL_BUCKET (tb , hash );
674
704
uint32 curelem = startelem ;
675
705
@@ -698,6 +728,28 @@ SH_LOOKUP(SH_TYPE * tb, SH_KEY_TYPE key)
698
728
}
699
729
}
700
730
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
+
701
753
/*
702
754
* Delete entry from hash table. Returns whether to-be-deleted key was
703
755
* present.
@@ -971,8 +1023,10 @@ SH_STAT(SH_TYPE * tb)
971
1023
#undef SH_DESTROY
972
1024
#undef SH_RESET
973
1025
#undef SH_INSERT
1026
+ #undef SH_INSERT_HASH
974
1027
#undef SH_DELETE
975
1028
#undef SH_LOOKUP
1029
+ #undef SH_LOOKUP_HASH
976
1030
#undef SH_GROW
977
1031
#undef SH_START_ITERATE
978
1032
#undef SH_START_ITERATE_AT
@@ -989,3 +1043,5 @@ SH_STAT(SH_TYPE * tb)
989
1043
#undef SH_PREV
990
1044
#undef SH_DISTANCE_FROM_OPTIMAL
991
1045
#undef SH_ENTRY_HASH
1046
+ #undef SH_INSERT_HASH_INTERNAL
1047
+ #undef SH_LOOKUP_HASH_INTERNAL
0 commit comments