1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 11:40:18 +02:00

(scm_t_hashtable): Removed 'closure' field. The

closure can not be stored since it is no longer valid at GC time.
(make_hash_table): Initialize 'hash_fn' field.
(scm_i_rehash): Only store hash_fn in hash table when closre is
NULL.
(rehash_after_gc): Only call scm_i_rehash when 'hash_fn' is
non-NULL.  Always use a NULL closure.
(scm_hash_fn_create_handle_x): Also rehash when table contains too
few entries.
This commit is contained in:
Marius Vollmer 2005-04-04 14:53:27 +00:00
parent 9aa0c3dd94
commit d3a80924bc
2 changed files with 21 additions and 12 deletions

View file

@ -102,6 +102,7 @@ make_hash_table (int flags, unsigned long k, const char *func_name)
t->lower = 0; t->lower = 0;
t->upper = 9 * n / 10; t->upper = 9 * n / 10;
t->flags = flags; t->flags = flags;
t->hash_fn = NULL;
if (flags) if (flags)
{ {
SCM_NEWSMOB3 (table, scm_tc16_hashtable, vector, t, weak_hashtables); SCM_NEWSMOB3 (table, scm_tc16_hashtable, vector, t, weak_hashtables);
@ -112,7 +113,6 @@ make_hash_table (int flags, unsigned long k, const char *func_name)
return table; return table;
} }
void void
scm_i_rehash (SCM table, scm_i_rehash (SCM table,
unsigned long (*hash_fn)(), unsigned long (*hash_fn)(),
@ -139,9 +139,13 @@ scm_i_rehash (SCM table,
if (i >= HASHTABLE_SIZE_N) if (i >= HASHTABLE_SIZE_N)
/* don't rehash */ /* don't rehash */
return; return;
/* store for use in rehash_after_gc */
SCM_HASHTABLE (table)->hash_fn = hash_fn; /* Remember HASH_FN for rehash_after_gc, but only when CLOSURE
SCM_HASHTABLE (table)->closure = closure; is not needed since CLOSURE can not be guaranteed to be valid
after this function returns.
*/
if (closure == NULL)
SCM_HASHTABLE (table)->hash_fn = hash_fn;
} }
SCM_HASHTABLE (table)->size_index = i; SCM_HASHTABLE (table)->size_index = i;
@ -298,11 +302,11 @@ rehash_after_gc (void *dummy1 SCM_UNUSED,
h = first; h = first;
do do
{ {
scm_i_rehash (h, /* Rehash only when we have a hash_fn.
/* use same hash_fn and closure as last time */ */
SCM_HASHTABLE (h)->hash_fn, if (SCM_HASHTABLE (h)->hash_fn)
SCM_HASHTABLE (h)->closure, scm_i_rehash (h, SCM_HASHTABLE (h)->hash_fn, NULL,
"rehash_after_gc"); "rehash_after_gc");
last = h; last = h;
h = SCM_HASHTABLE_NEXT (h); h = SCM_HASHTABLE_NEXT (h);
} while (!scm_is_null (h)); } while (!scm_is_null (h));
@ -507,8 +511,14 @@ scm_hash_fn_create_handle_x (SCM table, SCM obj, SCM init, unsigned long (*hash_
SCM_SIMPLE_VECTOR_SET (buckets, k, new_bucket); SCM_SIMPLE_VECTOR_SET (buckets, k, new_bucket);
if (!scm_is_eq (table, buckets)) if (!scm_is_eq (table, buckets))
{ {
/* Update element count and maybe rehash the table. The
table might have too few entries here since weak hash
tables used with the hashx_* functions can not be
rehashed after GC.
*/
SCM_HASHTABLE_INCREMENT (table); SCM_HASHTABLE_INCREMENT (table);
if (SCM_HASHTABLE_N_ITEMS (table) > SCM_HASHTABLE_UPPER (table)) if (SCM_HASHTABLE_N_ITEMS (table) < SCM_HASHTABLE_LOWER (table)
|| SCM_HASHTABLE_N_ITEMS (table) > SCM_HASHTABLE_UPPER (table))
scm_i_rehash (table, hash_fn, closure, FUNC_NAME); scm_i_rehash (table, hash_fn, closure, FUNC_NAME);
} }
return SCM_CAR (new_bucket); return SCM_CAR (new_bucket);

View file

@ -73,8 +73,7 @@ typedef struct scm_t_hashtable {
unsigned long upper; /* when to grow */ unsigned long upper; /* when to grow */
int size_index; /* index into hashtable_size */ int size_index; /* index into hashtable_size */
int min_size_index; /* minimum size_index */ int min_size_index; /* minimum size_index */
unsigned long (*hash_fn) (); unsigned long (*hash_fn) (); /* for rehashing after a GC. */
void *closure;
} scm_t_hashtable; } scm_t_hashtable;