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.
This commit is contained in:
Daniel Kochmański 2024-10-31 09:49:01 +01:00
parent 1ddbb00b53
commit 50879fd5d9

View file

@ -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;