summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-02-12 03:01:15 -0800
committerKaz Kylheku <kaz@kylheku.com>2014-02-12 03:01:15 -0800
commite18525f5d6de86773df9d72dd5d5f9e2c6dca581 (patch)
tree960e8219a553b073acdc718481af740087cf464c
parent3fb9836753f7685a5ce31bb67212cbb5b5c7dcad (diff)
downloadtxr-e18525f5d6de86773df9d72dd5d5f9e2c6dca581.tar.gz
txr-e18525f5d6de86773df9d72dd5d5f9e2c6dca581.tar.bz2
txr-e18525f5d6de86773df9d72dd5d5f9e2c6dca581.zip
* 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.
-rw-r--r--ChangeLog8
-rw-r--r--hash.c11
2 files changed, 19 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index b04577bc..9e418e8c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/hash.c b/hash.c
index cd91ad5e..c74a6294 100644
--- a/hash.c
+++ b/hash.c
@@ -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;