60
60
((_Py_hashtable_entry_t *)_Py_SLIST_ITEM_NEXT(ENTRY))
61
61
62
62
/* Forward declaration */
63
- static void hashtable_rehash (_Py_hashtable_t * ht );
63
+ static int hashtable_rehash (_Py_hashtable_t * ht );
64
64
65
65
static void
66
66
_Py_slist_init (_Py_slist_t * list )
@@ -198,6 +198,7 @@ _Py_hashtable_steal(_Py_hashtable_t *ht, const void *key)
198
198
ht -> alloc .free (entry );
199
199
200
200
if ((float )ht -> nentries / (float )ht -> nbuckets < HASHTABLE_LOW ) {
201
+ // Ignore failure: error cannot be reported to the caller
201
202
hashtable_rehash (ht );
202
203
}
203
204
return value ;
@@ -228,13 +229,17 @@ _Py_hashtable_set(_Py_hashtable_t *ht, const void *key, void *value)
228
229
entry -> key = (void * )key ;
229
230
entry -> value = value ;
230
231
231
- size_t index = entry -> key_hash & (ht -> nbuckets - 1 );
232
- _Py_slist_prepend (& ht -> buckets [index ], (_Py_slist_item_t * )entry );
233
232
ht -> nentries ++ ;
234
-
235
233
if ((float )ht -> nentries / (float )ht -> nbuckets > HASHTABLE_HIGH ) {
236
- hashtable_rehash (ht );
234
+ if (hashtable_rehash (ht ) < 0 ) {
235
+ ht -> nentries -- ;
236
+ ht -> alloc .free (entry );
237
+ return -1 ;
238
+ }
237
239
}
240
+
241
+ size_t index = entry -> key_hash & (ht -> nbuckets - 1 );
242
+ _Py_slist_prepend (& ht -> buckets [index ], (_Py_slist_item_t * )entry );
238
243
return 0 ;
239
244
}
240
245
@@ -271,19 +276,19 @@ _Py_hashtable_foreach(_Py_hashtable_t *ht,
271
276
}
272
277
273
278
274
- static void
279
+ static int
275
280
hashtable_rehash (_Py_hashtable_t * ht )
276
281
{
277
282
size_t new_size = round_size ((size_t )(ht -> nentries * HASHTABLE_REHASH_FACTOR ));
278
283
if (new_size == ht -> nbuckets ) {
279
- return ;
284
+ return 0 ;
280
285
}
281
286
282
287
size_t buckets_size = new_size * sizeof (ht -> buckets [0 ]);
283
288
_Py_slist_t * new_buckets = ht -> alloc .malloc (buckets_size );
284
289
if (new_buckets == NULL ) {
285
290
/* memory allocation failed */
286
- return ;
291
+ return -1 ;
287
292
}
288
293
memset (new_buckets , 0 , buckets_size );
289
294
@@ -303,6 +308,7 @@ hashtable_rehash(_Py_hashtable_t *ht)
303
308
ht -> alloc .free (ht -> buckets );
304
309
ht -> nbuckets = new_size ;
305
310
ht -> buckets = new_buckets ;
311
+ return 0 ;
306
312
}
307
313
308
314
@@ -388,7 +394,9 @@ _Py_hashtable_clear(_Py_hashtable_t *ht)
388
394
_Py_slist_init (& ht -> buckets [i ]);
389
395
}
390
396
ht -> nentries = 0 ;
391
- hashtable_rehash (ht );
397
+ // Ignore failure: clear function is not expected to fail
398
+ // because of a memory allocation failure.
399
+ (void )hashtable_rehash (ht );
392
400
}
393
401
394
402
0 commit comments