mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 03:30:27 +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:
parent
9aa0c3dd94
commit
d3a80924bc
2 changed files with 21 additions and 12 deletions
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue