@@ -64,20 +64,33 @@ static void rehash(st_table *);
6464#ifdef RUBY
6565#define malloc xmalloc
6666#define calloc xcalloc
67+ #define realloc xrealloc
6768#define free (x ) xfree(x)
6869#endif
6970
7071#define numberof (array ) (int)(sizeof(array) / sizeof((array)[0]))
7172
72- #define alloc (type ) (type*)malloc((size_t)sizeof(type))
73- #define Calloc (n ,s ) (char*)calloc((n),(s))
74-
7573#define EQUAL (table ,x ,y ) ((x)==(y) || (*(table)->type->compare)((x),(y)) == 0)
7674
7775/* remove cast to unsigned int in the future */
7876#define do_hash (key ,table ) (unsigned int)(st_index_t)(*(table)->type->hash)((key))
7977#define do_hash_bin (key ,table ) (do_hash((key), (table))%(table)->num_bins)
8078
79+ /* preparation for possible allocation improvements */
80+ #define st_alloc_entry () (st_table_entry *)malloc(sizeof(st_table_entry))
81+ #define st_free_entry (entry ) free(entry)
82+ #define st_alloc_table () (st_table *)malloc(sizeof(st_table))
83+ #define st_dealloc_table (table ) free(table)
84+ #define st_alloc_bins (size ) (st_table_entry **)calloc(size, sizeof(st_table_entry *))
85+ #define st_free_bins (bins , size ) free(bins)
86+ static inline st_table_entry * *
87+ st_realloc_bins (st_table_entry * * bins , st_index_t newsize , st_index_t oldsize )
88+ {
89+ bins = (st_table_entry * * ) realloc (bins , newsize * sizeof (st_table_entry * ));
90+ memset (bins , 0 , newsize * sizeof (st_table_entry * ));
91+ return bins ;
92+ }
93+
8194/* preparation for possible packing improvements */
8295#define PKEY_POS (i , num_bins ) ((i)*2)
8396#define PVAL_POS (i , num_bins ) ((i)*2+1)
@@ -202,12 +215,12 @@ st_init_table_with_size(const struct st_hash_type *type, st_index_t size)
202215
203216 size = new_size (size ); /* round up to prime number */
204217
205- tbl = alloc ( st_table );
218+ tbl = st_alloc_table ( );
206219 tbl -> type = type ;
207220 tbl -> num_entries = 0 ;
208221 tbl -> entries_packed = type == & type_numhash && size /2 <= MAX_PACKED_NUMHASH ;
209222 tbl -> num_bins = size ;
210- tbl -> bins = ( st_table_entry * * ) Calloc ( size , sizeof ( st_table_entry * ) );
223+ tbl -> bins = st_alloc_bins ( size );
211224 tbl -> head = 0 ;
212225 tbl -> tail = 0 ;
213226
@@ -272,7 +285,7 @@ st_clear(st_table *table)
272285 table -> bins [i ] = 0 ;
273286 while (ptr != 0 ) {
274287 next = ptr -> next ;
275- free (ptr );
288+ st_free_entry (ptr );
276289 ptr = next ;
277290 }
278291 }
285298st_free_table (st_table * table )
286299{
287300 st_clear (table );
288- free (table -> bins );
289- free (table );
301+ st_free_bins (table -> bins , table -> num_bins );
302+ st_dealloc_table (table );
290303}
291304
292305size_t
@@ -417,7 +430,7 @@ add_direct(st_table * table, st_data_t key, st_data_t value,
417430 bin_pos = hash_val % table -> num_bins ;
418431 }
419432
420- entry = alloc ( st_table_entry );
433+ entry = st_alloc_entry ( );
421434
422435 entry -> hash = hash_val ;
423436 entry -> key = key ;
@@ -557,12 +570,10 @@ static void
557570rehash (register st_table * table )
558571{
559572 register st_table_entry * ptr , * * new_bins ;
560- st_index_t i , new_num_bins , hash_val ;
573+ st_index_t new_num_bins , hash_val ;
561574
562575 new_num_bins = new_size (table -> num_bins + 1 );
563- new_bins = (st_table_entry * * )
564- xrealloc (table -> bins , new_num_bins * sizeof (st_table_entry * ));
565- for (i = 0 ; i < new_num_bins ; ++ i ) new_bins [i ] = 0 ;
576+ new_bins = st_realloc_bins (table -> bins , new_num_bins , table -> num_bins );
566577 table -> num_bins = new_num_bins ;
567578 table -> bins = new_bins ;
568579
@@ -583,17 +594,16 @@ st_copy(st_table *old_table)
583594 st_index_t num_bins = old_table -> num_bins ;
584595 st_index_t hash_val ;
585596
586- new_table = alloc ( st_table );
597+ new_table = st_alloc_table ( );
587598 if (new_table == 0 ) {
588599 return 0 ;
589600 }
590601
591602 * new_table = * old_table ;
592- new_table -> bins = (st_table_entry * * )
593- Calloc ((unsigned )num_bins , sizeof (st_table_entry * ));
603+ new_table -> bins = st_alloc_bins (num_bins );
594604
595605 if (new_table -> bins == 0 ) {
596- free (new_table );
606+ st_dealloc_table (new_table );
597607 return 0 ;
598608 }
599609
@@ -606,7 +616,7 @@ st_copy(st_table *old_table)
606616 prev = 0 ;
607617 tail = & new_table -> head ;
608618 do {
609- entry = alloc ( st_table_entry );
619+ entry = st_alloc_entry ( );
610620 if (entry == 0 ) {
611621 st_free_table (new_table );
612622 return 0 ;
@@ -668,7 +678,7 @@ st_delete(register st_table *table, register st_data_t *key, st_data_t *value)
668678 remove_entry (table , ptr );
669679 if (value != 0 ) * value = ptr -> record ;
670680 * key = ptr -> key ;
671- free (ptr );
681+ st_free_entry (ptr );
672682 return 1 ;
673683 }
674684 }
@@ -738,7 +748,7 @@ st_cleanup_safe(st_table *table, st_data_t never)
738748 if (ptr -> key == never ) {
739749 tmp = ptr ;
740750 * last = ptr = ptr -> next ;
741- free (tmp );
751+ st_free_entry (tmp );
742752 }
743753 else {
744754 ptr = * (last = & ptr -> next );
@@ -790,7 +800,7 @@ st_update(st_table *table, st_data_t key, int (*func)(st_data_t key, st_data_t *
790800 tmp = ptr -> fore ;
791801 * last = ptr -> next ;
792802 remove_entry (table , ptr );
793- free (ptr );
803+ st_free_entry (ptr );
794804 break ;
795805 }
796806 }
@@ -874,7 +884,7 @@ st_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg)
874884 tmp = ptr -> fore ;
875885 * last = ptr -> next ;
876886 remove_entry (table , ptr );
877- free (ptr );
887+ st_free_entry (ptr );
878888 if (ptr == tmp ) return 0 ;
879889 ptr = tmp ;
880890 break ;
@@ -952,7 +962,7 @@ st_reverse_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg)
952962 tmp = ptr -> back ;
953963 * last = ptr -> next ;
954964 remove_entry (table , ptr );
955- free (ptr );
965+ st_free_entry (ptr );
956966 ptr = tmp ;
957967 break ;
958968 }
0 commit comments