diff options
author | Marius Vollmer <mvo@zagadka.de> | 2005-04-04 14:53:27 +0000 |
---|---|---|
committer | Marius Vollmer <mvo@zagadka.de> | 2005-04-04 14:53:27 +0000 |
commit | d3a80924bc68db8ad41dad014edac5d61f520537 (patch) | |
tree | 1081b1bf2c31ede8e228500e8505c0e48847fed5 /libguile/hashtab.c | |
parent | 9aa0c3dd94f26417ef138c9b6f3133134a3dc6d2 (diff) | |
download | guile-d3a80924bc68db8ad41dad014edac5d61f520537.tar.gz |
(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.
Diffstat (limited to 'libguile/hashtab.c')
-rw-r--r-- | libguile/hashtab.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/libguile/hashtab.c b/libguile/hashtab.c index 1df1dea1f..488054969 100644 --- a/libguile/hashtab.c +++ b/libguile/hashtab.c @@ -102,6 +102,7 @@ make_hash_table (int flags, unsigned long k, const char *func_name) t->lower = 0; t->upper = 9 * n / 10; t->flags = flags; + t->hash_fn = NULL; if (flags) { 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; } - void scm_i_rehash (SCM table, unsigned long (*hash_fn)(), @@ -139,9 +139,13 @@ scm_i_rehash (SCM table, if (i >= HASHTABLE_SIZE_N) /* don't rehash */ return; - /* store for use in rehash_after_gc */ - SCM_HASHTABLE (table)->hash_fn = hash_fn; - SCM_HASHTABLE (table)->closure = closure; + + /* Remember HASH_FN for rehash_after_gc, but only when 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; @@ -298,11 +302,11 @@ rehash_after_gc (void *dummy1 SCM_UNUSED, h = first; do { - scm_i_rehash (h, - /* use same hash_fn and closure as last time */ - SCM_HASHTABLE (h)->hash_fn, - SCM_HASHTABLE (h)->closure, - "rehash_after_gc"); + /* Rehash only when we have a hash_fn. + */ + if (SCM_HASHTABLE (h)->hash_fn) + scm_i_rehash (h, SCM_HASHTABLE (h)->hash_fn, NULL, + "rehash_after_gc"); last = h; h = SCM_HASHTABLE_NEXT (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); 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); - 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); } return SCM_CAR (new_bucket); |