From 50879fd5d924864100b63b4f05af3fc585e81366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Kochma=C5=84ski?= Date: Thu, 31 Oct 2024 09:49:01 +0100 Subject: [PATCH] hash: factor out _ecl_store_key and _ecl_store_val for weak htables This makes the function _ecl_remash_weak and ecl_sethash_weak closer to the "default" macros HASH_TABLE_REMOVE and HASH_TABLE_SET. --- src/c/hash.d | 108 +++++++++++++++++++++++++-------------------------- 1 file changed, 53 insertions(+), 55 deletions(-) diff --git a/src/c/hash.d b/src/c/hash.d index 4f51758f1..08b2a3654 100644 --- a/src/c/hash.d +++ b/src/c/hash.d @@ -286,22 +286,22 @@ static cl_hashkey _hash_generic(cl_object ht, cl_object key) { } \ } -#define HASH_TABLE_SET(h,loop,compute_key,store_key) { \ - cl_hashkey h = compute_key; \ - struct ecl_hashtable_entry *e; \ - AGAIN: \ - e = loop(h, key, hashtable); \ - if (e->key == OBJNULL) { \ - cl_index i = hashtable->hash.entries + 1; \ - if (i >= hashtable->hash.limit) { \ - hashtable = ecl_extend_hashtable(hashtable); \ - goto AGAIN; \ - } \ - hashtable->hash.entries = i; \ - e->key = store_key; \ - } \ - e->value = value; \ - return hashtable; \ +#define HASH_TABLE_SET(h,loop,compute_key,store_key,store_val) { \ + cl_hashkey h = compute_key; \ + struct ecl_hashtable_entry *e; \ + AGAIN: \ + e = loop(h, key, hashtable); \ + if (e->key == OBJNULL) { \ + cl_index i = hashtable->hash.entries + 1; \ + if (i >= hashtable->hash.limit) { \ + hashtable = ecl_extend_hashtable(hashtable); \ + goto AGAIN; \ + } \ + hashtable->hash.entries = i; \ + e->key = store_key; \ + } \ + e->value = store_val; \ + return hashtable; \ } /* HASH_TABLE_REMOVE tries to fills up holes generated by deleting @@ -372,7 +372,7 @@ _ecl_gethash_eq(cl_object key, cl_object hashtable, cl_object def) static cl_object _ecl_sethash_eq(cl_object key, cl_object hashtable, cl_object value) { - HASH_TABLE_SET(h, _ecl_hash_loop_eq, _hash_eq(key), key); + HASH_TABLE_SET(h, _ecl_hash_loop_eq, _hash_eq(key), key, value); } static bool @@ -402,7 +402,7 @@ _ecl_gethash_eql(cl_object key, cl_object hashtable, cl_object def) static cl_object _ecl_sethash_eql(cl_object key, cl_object hashtable, cl_object value) { - HASH_TABLE_SET(h, _ecl_hash_loop_eql, _hash_eql(0, key), key); + HASH_TABLE_SET(h, _ecl_hash_loop_eql, _hash_eql(0, key), key, value); } static bool @@ -433,7 +433,7 @@ _ecl_gethash_equal(cl_object key, cl_object hashtable, cl_object def) static cl_object _ecl_sethash_equal(cl_object key, cl_object hashtable, cl_object value) { - HASH_TABLE_SET(h, _ecl_hash_loop_equal, _hash_equal(3, 0, key), key); + HASH_TABLE_SET(h, _ecl_hash_loop_equal, _hash_equal(3, 0, key), key, value); } static bool @@ -464,7 +464,7 @@ _ecl_gethash_equalp(cl_object key, cl_object hashtable, cl_object def) static cl_object _ecl_sethash_equalp(cl_object key, cl_object hashtable, cl_object value) { - HASH_TABLE_SET(h, _ecl_hash_loop_equalp, _hash_equalp(3, 0, key), key); + HASH_TABLE_SET(h, _ecl_hash_loop_equalp, _hash_equalp(3, 0, key),key, value); } static bool @@ -498,7 +498,7 @@ static cl_object _ecl_sethash_pack(cl_object key, cl_object hashtable, cl_object value) { HASH_TABLE_SET(h, _ecl_hash_loop_pack, _hash_equal(3, 0, key), - ecl_make_fixnum(h & 0xFFFFFFF)); + ecl_make_fixnum(h & 0xFFFFFFF), value); } static bool @@ -538,7 +538,8 @@ _ecl_gethash_generic(cl_object key, cl_object hashtable, cl_object def) static cl_object _ecl_sethash_generic(cl_object key, cl_object hashtable, cl_object value) { - HASH_TABLE_SET(h, _ecl_hash_loop_generic, _hash_generic(hashtable, key), key); + HASH_TABLE_SET(h, _ecl_hash_loop_generic, _hash_generic(hashtable, key), + key, value); } static bool @@ -614,6 +615,31 @@ normalize_weak_key_or_value_entry(struct ecl_hashtable_entry *e) { return 0; } +static cl_object +_ecl_store_key (cl_object hashtable, cl_object key) { + switch (hashtable->hash.weak) { + case ecl_htt_weak_key: + case ecl_htt_weak_key_and_value: + case ecl_htt_weak_key_or_value: + return si_make_weak_pointer(key); + default: + return key; + } +} + + +static cl_object +_ecl_store_val (cl_object hashtable, cl_object val) { + switch (hashtable->hash.weak) { + case ecl_htt_weak_value: + case ecl_htt_weak_key_and_value: + case ecl_htt_weak_key_or_value: + return si_make_weak_pointer(val); + default: + return val; + } +} + /* This function normalizes entries. That means that si_weak_pointer_value shouldn't be called on resulting entry key and value. -- jd 2019-05-28 */ static struct ecl_hashtable_entry @@ -701,21 +727,9 @@ _ecl_sethash_weak(cl_object key, cl_object hashtable, cl_object value) goto AGAIN; } hashtable->hash.entries = i; - switch (hashtable->hash.weak) { - case ecl_htt_weak_key: - case ecl_htt_weak_key_and_value: - case ecl_htt_weak_key_or_value: - key = si_make_weak_pointer(key); - } - e->key = key; + e->key = _ecl_store_key(hashtable, key); } - switch (hashtable->hash.weak) { - case ecl_htt_weak_value: - case ecl_htt_weak_key_and_value: - case ecl_htt_weak_key_or_value: - value = si_make_weak_pointer(value); - } - e->value = value; + e->value = _ecl_store_val(hashtable, value); return hashtable; } @@ -728,9 +742,7 @@ _ecl_remhash_weak(cl_object key, cl_object hashtable) for (i = h % hsize; ; i = (i + 1) % hsize) { struct ecl_hashtable_entry *p = hashtable->hash.data + i; struct ecl_hashtable_entry e = copy_entry(p, hashtable); - if (e.key == OBJNULL) { - return 0; - } + if (e.key == OBJNULL) return 0; if (_ecl_hash_test(hashtable, key, e.key)) { cl_index j = (i+1) % hsize, k; for (k = 1; k <= hsize; j = (j+1) % hsize, k++) { @@ -743,22 +755,8 @@ _ecl_remhash_weak(cl_object key, cl_object hashtable) cl_index m = hf % hsize; cl_index d = (j >= m) ? (j - m) : (j + hsize - m); if (k <= d) { - switch (hashtable->hash.weak) { - case ecl_htt_weak_key: - case ecl_htt_weak_key_and_value: - case ecl_htt_weak_key_or_value: - p->key = si_make_weak_pointer(f.key); - default: - p->key = f.key; - } - switch (hashtable->hash.weak) { - case ecl_htt_weak_value: - case ecl_htt_weak_key_and_value: - case ecl_htt_weak_key_or_value: - p->value = si_make_weak_pointer(f.value); - default: - p->value = f.value; - } + p->key = _ecl_store_key(hashtable, f.key); + p->value = _ecl_store_val(hashtable, f.value); p = q; i = j; k = 0;