mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-02-08 00:20:41 -08:00
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:
parent
1ddbb00b53
commit
50879fd5d9
1 changed files with 53 additions and 55 deletions
108
src/c/hash.d
108
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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue