summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib.c65
-rw-r--r--txr.112
2 files changed, 67 insertions, 10 deletions
diff --git a/lib.c b/lib.c
index bd647111..780984c1 100644
--- a/lib.c
+++ b/lib.c
@@ -13270,6 +13270,7 @@ val diff(val seq1, val seq2, val testfun, val keyfun)
list_collect_decl (out, ptail);
seq_iter_t si1, si2;
val el1;
+ unsigned c1 = 0;
testfun = default_arg(testfun, equal_f);
keyfun = default_arg(keyfun, identity_f);
@@ -13281,12 +13282,23 @@ val diff(val seq1, val seq2, val testfun, val keyfun)
val el1_key = funcall1(keyfun, el1);
val el2;
int found = 0;
+ unsigned c2 = 0;
+
+ c1++;
seq_iter_init(self, &si2, seq2);
while (seq_get(&si2, &el2)) {
val el2_key = funcall1(keyfun, el2);
+ if (++c2 >= 50 && c1 >= 50 &&
+ testfun == equal_f && keyfun == identity_f)
+ {
+ args_decl_constsize(args, ARGS_MIN);
+ val hash = hash_diff(hash_seq(seq1, args), hash_seq(seq2, args));
+ return make_like(hash_keys(hash), seq1);
+ }
+
if (funcall2(testfun, el1_key, el2_key)) {
found = 1;
break;
@@ -13334,6 +13346,7 @@ val symdiff(val seq1, val seq2, val testfun, val keyfun)
list_collect_decl (out, ptail);
seq_iter_t si1, si2;
val el1, el2;
+ unsigned c1 = 0, c2 = 0;
testfun = default_arg(testfun, equal_f);
keyfun = default_arg(keyfun, identity_f);
@@ -13341,14 +13354,25 @@ val symdiff(val seq1, val seq2, val testfun, val keyfun)
seq_iter_init(self, &si1, seq1);
seq_iter_init(self, &si2, seq2);
- while (seq_get(&si1, &el1))
+ while (seq_get(&si1, &el1)) {
+ if (c1 != 50)
+ c1++;
ptail = list_collect(ptail, el1);
+ }
while (seq_get(&si2, &el2)) {
val el2_key = funcall1(keyfun, el2);
val *iter;
int found = 0;
+ if (++c2 == 50 && c1 == 50 &&
+ testfun == equal_f && keyfun == identity_f)
+ {
+ args_decl_constsize(args, ARGS_MIN);
+ val hash = hash_symdiff(hash_seq(seq1, args), hash_seq(seq2, args));
+ return make_like(hash_keys(hash), seq1);
+ }
+
for (iter = &out; *iter; ) {
val elo = us_car(*iter);
val elo_key = funcall1(keyfun, elo);
@@ -13377,6 +13401,7 @@ val isec(val seq1, val seq2, val testfun, val keyfun)
list_collect_decl (out, ptail);
seq_iter_t si1, si2;
val el1;
+ unsigned c1 = 0;
testfun = default_arg(testfun, equal_f);
keyfun = default_arg(keyfun, identity_f);
@@ -13387,12 +13412,24 @@ val isec(val seq1, val seq2, val testfun, val keyfun)
while (seq_get(&si1, &el1)) {
val el1_key = funcall1(keyfun, el1);
val el2;
+ unsigned c2 = 0;
+
+ c1++;
seq_iter_init(self, &si2, seq2);
while (seq_get(&si2, &el2)) {
val el2_key = funcall1(keyfun, el2);
+ if (++c2 >= 50 && c1 >= 50 &&
+ testfun == equal_f && keyfun == identity_f)
+ {
+ args_decl_constsize(args, ARGS_MIN);
+ val hash = hash_isec(hash_seq(seq1, args), hash_seq(seq2, args),
+ colon_k);
+ return make_like(hash_keys(hash), seq1);
+ }
+
if (funcall2(testfun, el1_key, el2_key)) {
ptail = list_collect(ptail, el1);
break;
@@ -13409,6 +13446,7 @@ val isecp(val seq1, val seq2, val testfun, val keyfun)
val out = nil;
seq_iter_t si1, si2;
val el1;
+ unsigned c1 = 0;
testfun = default_arg(testfun, equal_f);
keyfun = default_arg(keyfun, identity_f);
@@ -13419,12 +13457,22 @@ val isecp(val seq1, val seq2, val testfun, val keyfun)
while (seq_get(&si1, &el1)) {
val el1_key = funcall1(keyfun, el1);
val el2;
+ unsigned c2 = 0;
+
+ c1++;
seq_iter_init(self, &si2, seq2);
while (seq_get(&si2, &el2)) {
val el2_key = funcall1(keyfun, el2);
+ if (++c2 >= 50 && c1 >= 50 &&
+ testfun == equal_f && keyfun == identity_f)
+ {
+ args_decl_constsize(args, ARGS_MIN);
+ return hash_isecp(hash_seq(seq1, args), hash_seq(seq2, args));
+ }
+
if (funcall2(testfun, el1_key, el2_key)) {
out = t;
break;
@@ -13441,6 +13489,7 @@ val uni(val seq1, val seq2, val testfun, val keyfun)
list_collect_decl (out, ptail);
seq_iter_t si1, si2;
val el1, el2;
+ unsigned c1 = 0, c2 = 0;
testfun = default_arg(testfun, equal_f);
keyfun = default_arg(keyfun, identity_f);
@@ -13448,12 +13497,24 @@ val uni(val seq1, val seq2, val testfun, val keyfun)
seq_iter_init(self, &si1, seq1);
seq_iter_init(self, &si2, seq2);
- while (seq_get(&si1, &el1))
+ while (seq_get(&si1, &el1)) {
+ if (c1 != 50)
+ c1++;
ptail = list_collect(ptail, el1);
+ }
while (seq_get(&si2, &el2)) {
val el2_key = funcall1(keyfun, el2);
+ if (++c2 == 50 && c1 == 50 &&
+ testfun == equal_f && keyfun == identity_f)
+ {
+ args_decl_constsize(args, ARGS_MIN);
+ val hash = hash_uni(hash_seq(seq1, args), hash_seq(seq2, args),
+ colon_k, colon_k, colon_k);
+ return make_like(hash_keys(hash), seq1);
+ }
+
if (!member(el2_key, out, testfun, keyfun))
ptail = list_collect(ptail, el2);
}
diff --git a/txr.1 b/txr.1
index cbecdee2..b5a442e7 100644
--- a/txr.1
+++ b/txr.1
@@ -39339,19 +39339,15 @@ function, the requirement was specified to preserve the original
order of items from
.meta iter1
that survive into the output sequence.
-This requirement is not documented for the
+This requirement does not apply to the
.code diff
-function, but is de facto
-honored by the implementation for at as long as the
-.code set-diff
-synonym continues to be available.
-The
+function. The
.code set-diff
function doesn't support hash tables and is inefficient for vectors and
strings.
-Note: these functions are not efficient for the processing of hash tables,
-even when both inputs are hashes, the
+Note: these functions are not required to be efficient for the processing of
+hash tables, even when both inputs are hashes, the
.meta keyfun
argument is
.codn car ,