diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | hash.c | 11 |
2 files changed, 19 insertions, 0 deletions
@@ -1,5 +1,13 @@ 2014-02-12 Kaz Kylheku <kaz@kylheku.com> + * hash.c (struct hash): New member, equal_fun. + (hash_equal_op): Short circuited logic: whenever we pull + identical cells from either hash, we don't have to go + through the pending lookaside list. + (make_hash, make_similar_hash): Initialize new structure member. + +2014-02-12 Kaz Kylheku <kaz@kylheku.com> + * hash.c (hash_equal_op, hash_hash_op): New static functions. (hash_ops): New functions registered in table of operations. @@ -55,6 +55,7 @@ struct hash { cnum count; val userdata; cnum (*hash_fun)(val); + val (*equal_fun)(val, val); val (*assoc_fun)(val key, val list); val *(*acons_new_l_fun)(val key, val *new_p, val *list); }; @@ -248,6 +249,14 @@ static val hash_equal_op(val left, val right) val found; /* + * Short circuit the logic if we have two identical cells; + * no need to go through the pending list. + */ + + if (l->equal_fun(car(lcell), car(rcell)) && equal(cdr(lcell), cdr(rcell))) + continue; + + /* * Try to find a cell matching the left cell on the pending list by key. * If it is found, and the associated datum is equal, then remove it from * the list. If it is found and the data is not equal, then we have found @@ -460,6 +469,7 @@ val make_hash(val weak_keys, val weak_vals, val equal_based) h->userdata = nil; h->hash_fun = equal_based ? equal_hash : eql_hash; + h->equal_fun = equal_based ? equal : eql; h->assoc_fun = equal_based ? assoc : assql; h->acons_new_l_fun = equal_based ? acons_new_l : aconsql_new_l; @@ -482,6 +492,7 @@ val make_similar_hash(val existing) h->flags = ex->flags; h->hash_fun = ex->hash_fun; + h->equal_fun = ex->equal_fun; h->assoc_fun = ex->assoc_fun; h->acons_new_l_fun = ex->acons_new_l_fun; |