diff options
-rw-r--r-- | lib.c | 65 | ||||
-rw-r--r-- | txr.1 | 12 |
2 files changed, 67 insertions, 10 deletions
@@ -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); } @@ -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 , |