diff --git a/src/CHANGELOG b/src/CHANGELOG index 02a47ca42..a8e29d59c 100755 --- a/src/CHANGELOG +++ b/src/CHANGELOG @@ -53,6 +53,11 @@ ECL 13.4.1 - New functions RATIOP, {SINGLE,SHORT,DOUBLE,LONG}-FLOAT-P help avoid consing in TYPEP +- HASH-TABLE-COUNT did not work with weak hashes: it did not update the count + of live cells (Note, however, that this function is by definition not + reliable, just a hint, since a garbage collection may happen while the count + is being computed) + * CLOS: - Added built in classes FIXNUM and BIGNUM. diff --git a/src/c/hash.d b/src/c/hash.d index 51e133643..bb68640a6 100644 --- a/src/c/hash.d +++ b/src/c/hash.d @@ -970,11 +970,33 @@ cl_hash_table_size(cl_object ht) @(return ecl_make_fixnum(ht->hash.size)) } +cl_index +ecl_hash_table_count(cl_object ht) +{ + if (ht->hash.weak == ecl_htt_not_weak) { + return ht->hash.entries; + } else if (ht->hash.size) { + cl_index i, j; + for (i = j = 0; i < ht->hash.size; i++) { + struct ecl_hashtable_entry output = + copy_entry(ht->hash.data + i, ht); + if (output.key != OBJNULL) { + if (++j == ht->hash.size) + break; + } + } + return ht->hash.entries = j; + } else { + return 0; + } +} + + cl_object cl_hash_table_count(cl_object ht) { assert_type_hash_table(@[hash-table-count], 1, ht); - @(return (ecl_make_fixnum(ht->hash.entries))) + @(return (ecl_make_fixnum(ecl_hash_table_count(ht)))) } static cl_object diff --git a/src/cmp/sysfun.lsp b/src/cmp/sysfun.lsp index 0e486c232..481bab188 100644 --- a/src/cmp/sysfun.lsp +++ b/src/cmp/sysfun.lsp @@ -284,6 +284,7 @@ (def-inline gethash :always (t t t) t "ecl_gethash_safe(#0,#1,#2)" :multiple-values nil) (def-inline gethash :always (t t) t "ecl_gethash_safe(#0,#1,ECL_NIL)" :multiple-values nil) +(def-inline hash-table-count :unsafe (hash-table) ext:array-index "ecl_hash_table_count(#0)") ;; file list.d diff --git a/src/h/external.h b/src/h/external.h index 4670e10a1..e3dee7768 100755 --- a/src/h/external.h +++ b/src/h/external.h @@ -817,6 +817,7 @@ extern ECL_API cl_object ecl_gethash(cl_object key, cl_object hash); extern ECL_API cl_object ecl_gethash_safe(cl_object key, cl_object hash, cl_object def); extern ECL_API bool ecl_remhash(cl_object key, cl_object hash); extern ECL_API cl_object _ecl_sethash(cl_object key, cl_object hashtable, cl_object value); +extern ECL_API cl_index ecl_hash_table_count(cl_object hash); /* instance.c */