@@ -69,9 +69,9 @@ dn_simdhash_ght_replaced (dn_simdhash_ght_data data, void * old_key, void * new_
6969static  unsigned int  
7070dn_simdhash_ght_default_hash  (const  void  *  key )
7171{
72-      // You might think we should avalanche the key bits but in my testing, it doesn't help. 
73-      // Right now the default hash function is rarely used anyway 
74-      return  (unsigned int  )(size_t )key ;
72+ 	 // You might think we should avalanche the key bits but in my testing, it doesn't help. 
73+ 	 // Right now the default hash function is rarely used anyway 
74+ 	 return  (unsigned int  )(size_t )key ;
7575}
7676
7777static  int32_t 
@@ -87,6 +87,8 @@ dn_simdhash_ght_new (
8787)
8888{
8989	dn_simdhash_ght_t  * hash  =  dn_simdhash_new_internal (& DN_SIMDHASH_T_META , DN_SIMDHASH_T_VTABLE , capacity , allocator );
90+ 	if  (!hash )
91+ 		return  NULL ;
9092	// Most users of dn_simdhash_ght are passing a custom comparer, and always doing an indirect call ends up being faster 
9193	//  than conditionally doing a fast inline check when there's no comparer set. Somewhat counter-intuitive, but true 
9294	//  on both x64 and arm64. Probably due to the smaller code size and reduced branch predictor pressure. 
@@ -107,6 +109,8 @@ dn_simdhash_ght_new_full (
107109)
108110{
109111	dn_simdhash_ght_t  * hash  =  dn_simdhash_new_internal (& DN_SIMDHASH_T_META , DN_SIMDHASH_T_VTABLE , capacity , allocator );
112+ 	if  (!hash )
113+ 		return  NULL ;
110114	if  (!hash_func )
111115		hash_func  =  dn_simdhash_ght_default_hash ;
112116	if  (!key_equal_func )
@@ -133,7 +137,14 @@ dn_simdhash_ght_insert_replace (
133137
134138	dn_simdhash_insert_result  ok  =  DN_SIMDHASH_TRY_INSERT_INTERNAL (hash , key , key_hash , value , imode );
135139	if  (ok  ==  DN_SIMDHASH_INSERT_NEED_TO_GROW ) {
136- 		dn_simdhash_buffers_t  old_buffers  =  dn_simdhash_ensure_capacity_internal (hash , dn_simdhash_capacity (hash ) +  1 );
140+ 		uint8_t  grow_ok ;
141+ 		dn_simdhash_buffers_t  old_buffers  =  dn_simdhash_ensure_capacity_internal (hash , dn_simdhash_capacity (hash ) +  1 , & grow_ok );
142+ 		// The ghashtable API doesn't have a way to signal failure, so just assert that we didn't fail to grow 
143+ 		dn_simdhash_assert (grow_ok );
144+ 		// Don't attempt to insert after a failed grow (it's possible to get here because dn_simdhash_assert is configurable) 
145+ 		if  (!grow_ok )
146+ 			return ;
147+ 
137148		if  (old_buffers .buckets ) {
138149			DN_SIMDHASH_REHASH_INTERNAL (hash , old_buffers );
139150			dn_simdhash_free_buffers (old_buffers );
@@ -151,11 +162,51 @@ dn_simdhash_ght_insert_replace (
151162		case  DN_SIMDHASH_INSERT_KEY_ALREADY_PRESENT :
152163		case  DN_SIMDHASH_INSERT_NEED_TO_GROW :
153164		default :
154- 			assert ( 0 );
165+ 			dn_simdhash_assert (! "Internal error in dn_simdhash_ght_insert_replace" );
155166			return ;
156167	}
157168}
158169
170+ dn_simdhash_add_result 
171+ dn_simdhash_ght_try_insert  (
172+ 	dn_simdhash_ght_t  * hash ,
173+ 	void  * key , void  * value ,
174+ 	dn_simdhash_insert_mode  mode 
175+ )
176+ {
177+ 	check_self (hash );
178+ 	uint32_t  key_hash  =  DN_SIMDHASH_KEY_HASHER (DN_SIMDHASH_GET_DATA (hash ), key );
179+ 
180+ 	dn_simdhash_insert_result  ok  =  DN_SIMDHASH_TRY_INSERT_INTERNAL (hash , key , key_hash , value , mode );
181+ 	if  (ok  ==  DN_SIMDHASH_INSERT_NEED_TO_GROW ) {
182+ 		uint8_t  grow_ok ;
183+ 		dn_simdhash_buffers_t  old_buffers  =  dn_simdhash_ensure_capacity_internal (hash , dn_simdhash_capacity (hash ) +  1 , & grow_ok );
184+ 		if  (!grow_ok )
185+ 			return  DN_SIMDHASH_OUT_OF_MEMORY ;
186+ 
187+ 		if  (old_buffers .buckets ) {
188+ 			DN_SIMDHASH_REHASH_INTERNAL (hash , old_buffers );
189+ 			dn_simdhash_free_buffers (old_buffers );
190+ 		}
191+ 		ok  =  DN_SIMDHASH_TRY_INSERT_INTERNAL (hash , key , key_hash , value , mode );
192+ 	}
193+ 
194+ 	switch  (ok ) {
195+ 		case  DN_SIMDHASH_INSERT_OK_ADDED_NEW :
196+ 			hash -> count ++ ;
197+ 			return  DN_SIMDHASH_ADD_INSERTED ;
198+ 		case  DN_SIMDHASH_INSERT_OK_OVERWROTE_EXISTING :
199+ 			return  DN_SIMDHASH_ADD_OVERWROTE ;
200+ 		case  DN_SIMDHASH_INSERT_KEY_ALREADY_PRESENT :
201+ 			return  DN_SIMDHASH_ADD_FAILED ;
202+ 
203+ 		case  DN_SIMDHASH_INSERT_NEED_TO_GROW :
204+ 		default :
205+ 			dn_simdhash_assert (!"Internal error in dn_simdhash_ght_insert_replace" );
206+ 			return  DN_SIMDHASH_INTERNAL_ERROR ;
207+ 	}
208+ }
209+ 
159210void  * 
160211dn_simdhash_ght_get_value_or_default  (
161212	dn_simdhash_ght_t  * hash , void  *  key 
0 commit comments