mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-04-25 07:40:40 -07:00
Alternative implementation for weak hash tables
It can be enabled with -DUSE_EPHEMERON_POOL. This variant uses the ephemeron pool and hence sovles the key-in-value problem. This version stores key/values pairs a vector-of-pairs instead of a pair-of-vectors. The same vector-of-pairs type is used for weak and non-weak. This avoids the code duplication used by the pair-of-vector version; though it adds a bit of overhead to the non-weak code path. * src/lisp.h: (struct vector_pair [!USE_EPHEMERON_POOL]): New type. (struct pair_vector [USE_EPHEMERON_POOL]):New type. (hash_table_kv): New typedef used to both version. (hash_table_kv_create, hash_table_kv_free, hash_table_kv_key) (hash_table_kv_value, hash_table_kv_set_key, hash_table_kv_set_value) (hash_table_kv_null): New helpers (struct Lisp_Hash_Table): Use a single field kv of type hash_table_kv instead of two fields. (HASH_KEY, HASH_VALUE, WEAK_HASH_KEY, WEAK_HASH_VALUE, DOHASH) (DOHASH_WEAK, set_hash_key_slot, set_hash_value_slot) (set_weak_hash_key_slot, set_weak_hash_value_slot): Adapt to hash_table_kv. (DOHASH [USE_EPHEMERON_POOL]): New version. * src/igc.h (enum igc_obj_type): Add IGC_OBJ_PAIR_VECTOR, IGC_OBJ_WEAK_KEY_PAIR_VECTOR, IGC_OBJ_WEAK_VALUE_PAIR_VECTOR, IGC_OBJ_WEAK_OR_PAIR_VECTOR. (igc_alloc_pair_vector): New prototype. * src/igc.c (obj_type_names, set_header, dflt_scan_obj, thread_ap): Handle new tpes. (struct igc_thread, create_ephemeron_ap, create_thread_aps) (igc_thread_remove): Add allocation point for ephemeron pool. (struct igc, make_pool_aeph, make_igc): Add ephemeron pool. (as_igc_header, fix_pair_vector, decode_ptr, encode_ptr) (increment_ndeleted, splat_pair, fix_weak_key_pair, fix_weak_value_pair) (fix_weak_or_pair, fix_weak_and_pair, scan_pair_vector) (fix_weak_key_pair_vector, fix_weak_value_pair_vector) (fix_weak_or_pair_vector, fix_weak_and_pair_vector): New helpers. (fix_hash_table, fix_weak_hash_table_strong_part) (fix_weak_hash_table_weak_part): Adapt to hash_table_kv. (igc_alloc_pair_vector): New function. * src/fns.c (maybe_resize_hash_table): Call maybe_resize_hash_table. (Fgethash): Add assertion for HASH_UNUSED_ENTRY_KEY. (Fhash_table_count): Take deleted entries into account. (hash_table_kv_init, hash_table_kv_create) (hash_table_kv_resize, hash_table_kv_free): New helpers. (hash_table_kv_ndeleted, hash_table_ndeleted) (hash_table_count, reclaim_deleted_entries) (maybe_reclaim_deleted_entries): New helpers. (make_hash_table, copy_hash_table, hash_table_thaw, hash_table_rehash) (allocate_weak_hash_table_parts, make_weak_hash_table) (maybe_resize_weak_hash_table): Adapt to hash_table_kv. * src/alloc.c (cleanup_vector): Adapt to hash_table_kv. * src/pdumper.c (hash_table_contents, hash_table_freeze) (dump_hash_table): Adapt to hash_table_kv. (dump_hash_table_kv_slot, dump_hash_table_kv, dump_hash_table_kv_part): New helpers. * src/print.c (print_object): Use Fhash_table_count instead of the h->count field. * test/src/fns-tests.el (ft--check-entries): Check hash-table-count. (ft-weak-fixnums2, ft--test-weak-fixnums2): New test. (ft--test-ephemeron-table): Better check for hash-table-count.
This commit is contained in:
parent
c067ff171e
commit
b3ee5b351e
10 changed files with 992 additions and 164 deletions
|
|
@ -1307,7 +1307,8 @@
|
|||
(cl-loop for (k1 . v1) in expected
|
||||
for (k2 . v2) in actual
|
||||
do (ft--check-entry w k1 v1 k2 v2))
|
||||
(should (= (length expected) (length actual)))))
|
||||
(should (= (length expected) (length actual)))
|
||||
(should (= (hash-table-count table) (length expected)))))
|
||||
|
||||
(defun ft--gc (weakness)
|
||||
(cond ((fboundp 'igc--collect)
|
||||
|
|
@ -1388,6 +1389,23 @@
|
|||
(dolist (test '(eq eql equal))
|
||||
(ft--test-weak-fixnums w test))))
|
||||
|
||||
(defun ft--test-weak-fixnums2 (weakness test)
|
||||
(let ((h (make-hash-table :weakness weakness :test test)))
|
||||
(dotimes (i 3)
|
||||
(cl-ecase i
|
||||
(#b00 (dotimes (i 10)
|
||||
(puthash i (lognot i) h)))
|
||||
(#b01 (dotimes (i 10)
|
||||
(puthash i (cons nil nil) h)))
|
||||
(#b10 (dotimes (i 10)
|
||||
(puthash (cons nil nil) i h)))))
|
||||
(ft--gc weakness)))
|
||||
|
||||
(ert-deftest ft-weak-fixnums2 ()
|
||||
(dolist (w '(key value key-and-value key-or-value))
|
||||
(dolist (test '(eq eql equal))
|
||||
(ft--test-weak-fixnums2 w test))))
|
||||
|
||||
(defun ft--test-ephemeron-table (weakness)
|
||||
(let* ((h (make-hash-table :weakness weakness :test 'eq))
|
||||
(n 1000))
|
||||
|
|
@ -1395,6 +1413,7 @@
|
|||
(let* ((obj (cons 'a i)))
|
||||
(puthash obj obj h)))
|
||||
(ft--gc weakness)
|
||||
(should (< (length (ft--hash-table-entries h)) n))
|
||||
(should (< (hash-table-count h) n))))
|
||||
|
||||
(ert-deftest ft-ephemeron-table ()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue