{"thread":{"id":"27762","subject":"[PATCH v2 0/4] prepare for histogram diff","startedAt":"2011-07-06T16:38:53Z","lastAt":"2011-07-07T04:23:58Z","messageCount":16,"participants":["Tay Ray Chuan","Junio C Hamano","Phil Hord"],"isPatch":true,"patchVersion":2,"patchTotal":4},"messages":[{"id":"170926","messageId":"1309970337-6016-1-git-send-email-rctay89@gmail.com","threadId":"27762","inReplyTo":null,"subject":"[PATCH v2 0/4] prepare for histogram diff","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2011-07-06T16:38:53Z","receivedAt":"2011-07-06T16:38:53Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Tay Ray Chuan (4):\n  xdiff/xprepare: use memset()\n  xdiff/xprepare: refactor abort cleanups\n  xdiff/xpatience: factor out fall-back-diff function\n  t4033-diff-patience: factor out tests\n\n t/lib-diff-patience.sh   |  163 ++++++++++++++++++++++++++++++++++++++++++++++\n t/t4033-diff-patience.sh |  162 +--------------------------------------------\n xdiff/xpatience.c        |   27 +-------\n xdiff/xprepare.c         |  104 +++++++++++-------------------\n xdiff/xutils.c           |   31 +++++++++\n xdiff/xutils.h           |    2 +\n 6 files changed, 238 insertions(+), 251 deletions(-)\n create mode 100644 t/lib-diff-patience.sh\n\n-- \n1.7.3.4.721.g4666.dirty\n"},{"id":"170927","messageId":"1309970337-6016-2-git-send-email-rctay89@gmail.com","threadId":"27762","inReplyTo":"1309970337-6016-1-git-send-email-rctay89@gmail.com","subject":"[PATCH v2 1/4] xdiff/xprepare: use memset()","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2011-07-06T16:38:54Z","receivedAt":"2011-07-06T16:38:54Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Use memset() instead of a for loop to initialize. This could give a\nperformance advantage.\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n---\n xdiff/xprepare.c |   10 +++-------\n 1 files changed, 3 insertions(+), 7 deletions(-)\n\ndiff --git a/xdiff/xprepare.c b/xdiff/xprepare.c\nindex 1689085..783631a 100644\n--- a/xdiff/xprepare.c\n+++ b/xdiff/xprepare.c\n@@ -64,8 +64,6 @@ static int xdl_optimize_ctxs(xdfile_t *xdf1, xdfile_t *xdf2);\n \n \n static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags) {\n-\tlong i;\n-\n \tcf->flags = flags;\n \n \tcf->hbits = xdl_hashbits((unsigned int) size);\n@@ -80,8 +78,7 @@ static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags) {\n \t\txdl_cha_free(&cf->ncha);\n \t\treturn -1;\n \t}\n-\tfor (i = 0; i < cf->hsize; i++)\n-\t\tcf->rchash[i] = NULL;\n+\tmemset(cf->rchash, 0, cf->hsize * sizeof(xdlclass_t *));\n \n \tcf->count = 0;\n \n@@ -136,7 +133,7 @@ static int xdl_classify_record(xdlclassifier_t *cf, xrecord_t **rhash, unsigned\n static int xdl_prepare_ctx(mmfile_t *mf, long narec, xpparam_t const *xpp,\n \t\t\t   xdlclassifier_t *cf, xdfile_t *xdf) {\n \tunsigned int hbits;\n-\tlong i, nrec, hsize, bsize;\n+\tlong nrec, hsize, bsize;\n \tunsigned long hav;\n \tchar const *blk, *cur, *top, *prev;\n \txrecord_t *crec;\n@@ -164,8 +161,7 @@ static int xdl_prepare_ctx(mmfile_t *mf, long narec, xpparam_t const *xpp,\n \t\txdl_cha_free(&xdf->rcha);\n \t\treturn -1;\n \t}\n-\tfor (i = 0; i < hsize; i++)\n-\t\trhash[i] = NULL;\n+\tmemset(rhash, 0, hsize * sizeof(xrecord_t *));\n \n \tnrec = 0;\n \tif ((cur = blk = xdl_mmfile_first(mf, &bsize)) != NULL) {\n-- \n1.7.3.4.721.g4666.dirty\n"},{"id":"170928","messageId":"1309970337-6016-3-git-send-email-rctay89@gmail.com","threadId":"27762","inReplyTo":"1309970337-6016-2-git-send-email-rctay89@gmail.com","subject":"[PATCH v2 2/4] xdiff/xprepare: refactor abort cleanups","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2011-07-06T16:38:55Z","receivedAt":"2011-07-06T16:38:55Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Group free()'s that are called when a malloc() fails in\nxdl_prepare_ctx(), making for more readable code.\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n---\n xdiff/xprepare.c |   94 +++++++++++++++++++----------------------------------\n 1 files changed, 34 insertions(+), 60 deletions(-)\n\ndiff --git a/xdiff/xprepare.c b/xdiff/xprepare.c\nindex 783631a..6168327 100644\n--- a/xdiff/xprepare.c\n+++ b/xdiff/xprepare.c\n@@ -143,24 +143,15 @@ static int xdl_prepare_ctx(mmfile_t *mf, long narec, xpparam_t const *xpp,\n \tchar *rchg;\n \tlong *rindex;\n \n-\tif (xdl_cha_init(&xdf->rcha, sizeof(xrecord_t), narec / 4 + 1) < 0) {\n-\n-\t\treturn -1;\n-\t}\n-\tif (!(recs = (xrecord_t **) xdl_malloc(narec * sizeof(xrecord_t *)))) {\n-\n-\t\txdl_cha_free(&xdf->rcha);\n-\t\treturn -1;\n-\t}\n+\tif (xdl_cha_init(&xdf->rcha, sizeof(xrecord_t), narec / 4 + 1) < 0)\n+\t\tgoto abort_rcha;\n+\tif (!(recs = (xrecord_t **) xdl_malloc(narec * sizeof(xrecord_t *))))\n+\t\tgoto abort_recs;\n \n \thbits = xdl_hashbits((unsigned int) narec);\n \thsize = 1 << hbits;\n-\tif (!(rhash = (xrecord_t **) xdl_malloc(hsize * sizeof(xrecord_t *)))) {\n-\n-\t\txdl_free(recs);\n-\t\txdl_cha_free(&xdf->rcha);\n-\t\treturn -1;\n-\t}\n+\tif (!(rhash = (xrecord_t **) xdl_malloc(hsize * sizeof(xrecord_t *))))\n+\t\tgoto abort_rhash;\n \tmemset(rhash, 0, hsize * sizeof(xrecord_t *));\n \n \tnrec = 0;\n@@ -175,63 +166,30 @@ static int xdl_prepare_ctx(mmfile_t *mf, long narec, xpparam_t const *xpp,\n \t\t\thav = xdl_hash_record(&cur, top, xpp->flags);\n \t\t\tif (nrec >= narec) {\n \t\t\t\tnarec *= 2;\n-\t\t\t\tif (!(rrecs = (xrecord_t **) xdl_realloc(recs, narec * sizeof(xrecord_t *)))) {\n-\n-\t\t\t\t\txdl_free(rhash);\n-\t\t\t\t\txdl_free(recs);\n-\t\t\t\t\txdl_cha_free(&xdf->rcha);\n-\t\t\t\t\treturn -1;\n-\t\t\t\t}\n+\t\t\t\tif (!(rrecs = (xrecord_t **) xdl_realloc(recs, narec * sizeof(xrecord_t *))))\n+\t\t\t\t\tgoto abort_rrecs;\n \t\t\t\trecs = rrecs;\n \t\t\t}\n-\t\t\tif (!(crec = xdl_cha_alloc(&xdf->rcha))) {\n-\n-\t\t\t\txdl_free(rhash);\n-\t\t\t\txdl_free(recs);\n-\t\t\t\txdl_cha_free(&xdf->rcha);\n-\t\t\t\treturn -1;\n-\t\t\t}\n+\t\t\tif (!(crec = xdl_cha_alloc(&xdf->rcha)))\n+\t\t\t\tgoto abort_crec;\n \t\t\tcrec->ptr = prev;\n \t\t\tcrec->size = (long) (cur - prev);\n \t\t\tcrec->ha = hav;\n \t\t\trecs[nrec++] = crec;\n \n-\t\t\tif (xdl_classify_record(cf, rhash, hbits, crec) < 0) {\n-\n-\t\t\t\txdl_free(rhash);\n-\t\t\t\txdl_free(recs);\n-\t\t\t\txdl_cha_free(&xdf->rcha);\n-\t\t\t\treturn -1;\n-\t\t\t}\n+\t\t\tif (xdl_classify_record(cf, rhash, hbits, crec) < 0)\n+\t\t\t\tgoto abort_classify;\n \t\t}\n \t}\n \n-\tif (!(rchg = (char *) xdl_malloc((nrec + 2) * sizeof(char)))) {\n-\n-\t\txdl_free(rhash);\n-\t\txdl_free(recs);\n-\t\txdl_cha_free(&xdf->rcha);\n-\t\treturn -1;\n-\t}\n+\tif (!(rchg = (char *) xdl_malloc((nrec + 2) * sizeof(char))))\n+\t\tgoto abort_rchg;\n \tmemset(rchg, 0, (nrec + 2) * sizeof(char));\n \n-\tif (!(rindex = (long *) xdl_malloc((nrec + 1) * sizeof(long)))) {\n-\n-\t\txdl_free(rchg);\n-\t\txdl_free(rhash);\n-\t\txdl_free(recs);\n-\t\txdl_cha_free(&xdf->rcha);\n-\t\treturn -1;\n-\t}\n-\tif (!(ha = (unsigned long *) xdl_malloc((nrec + 1) * sizeof(unsigned long)))) {\n-\n-\t\txdl_free(rindex);\n-\t\txdl_free(rchg);\n-\t\txdl_free(rhash);\n-\t\txdl_free(recs);\n-\t\txdl_cha_free(&xdf->rcha);\n-\t\treturn -1;\n-\t}\n+\tif (!(rindex = (long *) xdl_malloc((nrec + 1) * sizeof(long))))\n+\t\tgoto abort_rindex;\n+\tif (!(ha = (unsigned long *) xdl_malloc((nrec + 1) * sizeof(unsigned long))))\n+\t\tgoto abort_ha;\n \n \txdf->nrec = nrec;\n \txdf->recs = recs;\n@@ -245,6 +203,22 @@ static int xdl_prepare_ctx(mmfile_t *mf, long narec, xpparam_t const *xpp,\n \txdf->dend = nrec - 1;\n \n \treturn 0;\n+\n+abort_ha:\n+\txdl_free(rindex);\n+abort_rindex:\n+\txdl_free(rchg);\n+abort_rchg:\n+abort_classify:\n+abort_crec:\n+abort_rrecs:\n+\txdl_free(rhash);\n+abort_rhash:\n+\txdl_free(recs);\n+abort_recs:\n+\txdl_cha_free(&xdf->rcha);\n+abort_rcha:\n+\treturn -1;\n }\n \n \n-- \n1.7.3.4.721.g4666.dirty\n"},{"id":"170929","messageId":"1309970337-6016-4-git-send-email-rctay89@gmail.com","threadId":"27762","inReplyTo":"1309970337-6016-3-git-send-email-rctay89@gmail.com","subject":"[PATCH v2 3/4] xdiff/xpatience: factor out fall-back-diff function","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2011-07-06T16:38:56Z","receivedAt":"2011-07-06T16:38:56Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"This is in preparation for the histogram diff algorithm, which will also\nre-use much of the code to call the default Meyers diff algorithm.\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n---\n xdiff/xpatience.c |   27 ++-------------------------\n xdiff/xutils.c    |   31 +++++++++++++++++++++++++++++++\n xdiff/xutils.h    |    2 ++\n 3 files changed, 35 insertions(+), 25 deletions(-)\n\ndiff --git a/xdiff/xpatience.c b/xdiff/xpatience.c\nindex e42c16a..fdd7d02 100644\n--- a/xdiff/xpatience.c\n+++ b/xdiff/xpatience.c\n@@ -287,34 +287,11 @@ static int walk_common_sequence(struct hashmap *map, struct entry *first,\n static int fall_back_to_classic_diff(struct hashmap *map,\n \t\tint line1, int count1, int line2, int count2)\n {\n-\t/*\n-\t * This probably does not work outside Git, since\n-\t * we have a very simple mmfile structure.\n-\t *\n-\t * Note: ideally, we would reuse the prepared environment, but\n-\t * the libxdiff interface does not (yet) allow for diffing only\n-\t * ranges of lines instead of the whole files.\n-\t */\n-\tmmfile_t subfile1, subfile2;\n \txpparam_t xpp;\n-\txdfenv_t env;\n-\n-\tsubfile1.ptr = (char *)map->env->xdf1.recs[line1 - 1]->ptr;\n-\tsubfile1.size = map->env->xdf1.recs[line1 + count1 - 2]->ptr +\n-\t\tmap->env->xdf1.recs[line1 + count1 - 2]->size - subfile1.ptr;\n-\tsubfile2.ptr = (char *)map->env->xdf2.recs[line2 - 1]->ptr;\n-\tsubfile2.size = map->env->xdf2.recs[line2 + count2 - 2]->ptr +\n-\t\tmap->env->xdf2.recs[line2 + count2 - 2]->size - subfile2.ptr;\n \txpp.flags = map->xpp->flags & ~XDF_PATIENCE_DIFF;\n-\tif (xdl_do_diff(&subfile1, &subfile2, &xpp, &env) < 0)\n-\t\treturn -1;\n \n-\tmemcpy(map->env->xdf1.rchg + line1 - 1, env.xdf1.rchg, count1);\n-\tmemcpy(map->env->xdf2.rchg + line2 - 1, env.xdf2.rchg, count2);\n-\n-\txdl_free_env(&env);\n-\n-\treturn 0;\n+\treturn xdl_fall_back_diff(map->env, &xpp,\n+\t\t\t\t  line1, count1, line2, count2);\n }\n \n /*\ndiff --git a/xdiff/xutils.c b/xdiff/xutils.c\nindex ab65034..ded7c32 100644\n--- a/xdiff/xutils.c\n+++ b/xdiff/xutils.c\n@@ -402,3 +402,34 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,\n \n \treturn 0;\n }\n+\n+int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,\n+\t\tint line1, int count1, int line2, int count2)\n+{\n+\t/*\n+\t * This probably does not work outside Git, since\n+\t * we have a very simple mmfile structure.\n+\t *\n+\t * Note: ideally, we would reuse the prepared environment, but\n+\t * the libxdiff interface does not (yet) allow for diffing only\n+\t * ranges of lines instead of the whole files.\n+\t */\n+\tmmfile_t subfile1, subfile2;\n+\txdfenv_t env;\n+\n+\tsubfile1.ptr = (char *)diff_env->xdf1.recs[line1 - 1]->ptr;\n+\tsubfile1.size = diff_env->xdf1.recs[line1 + count1 - 2]->ptr +\n+\t\tdiff_env->xdf1.recs[line1 + count1 - 2]->size - subfile1.ptr;\n+\tsubfile2.ptr = (char *)diff_env->xdf2.recs[line2 - 1]->ptr;\n+\tsubfile2.size = diff_env->xdf2.recs[line2 + count2 - 2]->ptr +\n+\t\tdiff_env->xdf2.recs[line2 + count2 - 2]->size - subfile2.ptr;\n+\tif (xdl_do_diff(&subfile1, &subfile2, xpp, &env) < 0)\n+\t\treturn -1;\n+\n+\tmemcpy(diff_env->xdf1.rchg + line1 - 1, env.xdf1.rchg, count1);\n+\tmemcpy(diff_env->xdf2.rchg + line2 - 1, env.xdf2.rchg, count2);\n+\n+\txdl_free_env(&env);\n+\n+\treturn 0;\n+}\ndiff --git a/xdiff/xutils.h b/xdiff/xutils.h\nindex d5de829..674a657 100644\n--- a/xdiff/xutils.h\n+++ b/xdiff/xutils.h\n@@ -41,6 +41,8 @@ int xdl_num_out(char *out, long val);\n long xdl_atol(char const *str, char const **next);\n int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,\n \t\t      const char *func, long funclen, xdemitcb_t *ecb);\n+int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,\n+\t\t       int line1, int count1, int line2, int count2);\n \n \n \n-- \n1.7.3.4.721.g4666.dirty\n"},{"id":"170930","messageId":"1309970337-6016-5-git-send-email-rctay89@gmail.com","threadId":"27762","inReplyTo":"1309970337-6016-4-git-send-email-rctay89@gmail.com","subject":"[PATCH v2 4/4] t4033-diff-patience: factor out tests","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2011-07-06T16:38:57Z","receivedAt":"2011-07-06T16:38:57Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Group the test cases into two functions, test_diff_(frobnitz|unique).\nThis in preparation for the histogram diff algorithm, which would also\nre-use these test cases.\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n---\n\nRam: the rename is detected in git-log, but not in the diffstat. The\nexpected and actual content, which makes up the bulk of content, is\nunchanged, but the 'surrounding' changes should be pretty easy to spot.\n\n t/lib-diff-patience.sh   |  163 ++++++++++++++++++++++++++++++++++++++++++++++\n t/t4033-diff-patience.sh |  162 +--------------------------------------------\n 2 files changed, 166 insertions(+), 159 deletions(-)\n create mode 100644 t/lib-diff-patience.sh\n\ndiff --git a/t/lib-diff-patience.sh b/t/lib-diff-patience.sh\nnew file mode 100644\nindex 0000000..761bb09\n--- /dev/null\n+++ b/t/lib-diff-patience.sh\n@@ -0,0 +1,163 @@\n+test_diff_frobnitz() {\n+\tcat >file1 <<\\EOF\n+#include <stdio.h>\n+\n+// Frobs foo heartily\n+int frobnitz(int foo)\n+{\n+    int i;\n+    for(i = 0; i < 10; i++)\n+    {\n+        printf(\"Your answer is: \");\n+        printf(\"%d\\n\", foo);\n+    }\n+}\n+\n+int fact(int n)\n+{\n+    if(n > 1)\n+    {\n+        return fact(n-1) * n;\n+    }\n+    return 1;\n+}\n+\n+int main(int argc, char **argv)\n+{\n+    frobnitz(fact(10));\n+}\n+EOF\n+\n+\tcat >file2 <<\\EOF\n+#include <stdio.h>\n+\n+int fib(int n)\n+{\n+    if(n > 2)\n+    {\n+        return fib(n-1) + fib(n-2);\n+    }\n+    return 1;\n+}\n+\n+// Frobs foo heartily\n+int frobnitz(int foo)\n+{\n+    int i;\n+    for(i = 0; i < 10; i++)\n+    {\n+        printf(\"%d\\n\", foo);\n+    }\n+}\n+\n+int main(int argc, char **argv)\n+{\n+    frobnitz(fib(10));\n+}\n+EOF\n+\n+\tcat >expect <<\\EOF\n+diff --git a/file1 b/file2\n+index 6faa5a3..e3af329 100644\n+--- a/file1\n++++ b/file2\n+@@ -1,26 +1,25 @@\n+ #include <stdio.h>\n+ \n++int fib(int n)\n++{\n++    if(n > 2)\n++    {\n++        return fib(n-1) + fib(n-2);\n++    }\n++    return 1;\n++}\n++\n+ // Frobs foo heartily\n+ int frobnitz(int foo)\n+ {\n+     int i;\n+     for(i = 0; i < 10; i++)\n+     {\n+-        printf(\"Your answer is: \");\n+         printf(\"%d\\n\", foo);\n+     }\n+ }\n+ \n+-int fact(int n)\n+-{\n+-    if(n > 1)\n+-    {\n+-        return fact(n-1) * n;\n+-    }\n+-    return 1;\n+-}\n+-\n+ int main(int argc, char **argv)\n+ {\n+-    frobnitz(fact(10));\n++    frobnitz(fib(10));\n+ }\n+EOF\n+\n+\tSTRATEGY=$1\n+\n+\ttest_expect_success \"$STRATEGY diff\" '\n+\t\ttest_must_fail git diff --no-index \"--$STRATEGY\" file1 file2 > output &&\n+\t\ttest_cmp expect output\n+\t'\n+\n+\ttest_expect_success \"$STRATEGY diff output is valid\" '\n+\t\tmv file2 expect &&\n+\t\tgit apply < output &&\n+\t\ttest_cmp expect file2\n+\t'\n+}\n+\n+test_diff_unique() {\n+\tcat >uniq1 <<\\EOF\n+1\n+2\n+3\n+4\n+5\n+6\n+EOF\n+\n+\tcat >uniq2 <<\\EOF\n+a\n+b\n+c\n+d\n+e\n+f\n+EOF\n+\n+\tcat >expect <<\\EOF\n+diff --git a/uniq1 b/uniq2\n+index b414108..0fdf397 100644\n+--- a/uniq1\n++++ b/uniq2\n+@@ -1,6 +1,6 @@\n+-1\n+-2\n+-3\n+-4\n+-5\n+-6\n++a\n++b\n++c\n++d\n++e\n++f\n+EOF\n+\n+\tSTRATEGY=$1\n+\n+\ttest_expect_success 'completely different files' '\n+\t\ttest_must_fail git diff --no-index \"--$STRATEGY\" uniq1 uniq2 > output &&\n+\t\ttest_cmp expect output\n+\t'\n+}\n+\ndiff --git a/t/t4033-diff-patience.sh b/t/t4033-diff-patience.sh\nindex 1eb1498..9fe9921 100755\n--- a/t/t4033-diff-patience.sh\n+++ b/t/t4033-diff-patience.sh\n@@ -3,166 +3,10 @@\n test_description='patience diff algorithm'\n \n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-diff-patience.sh\n \n-cat >file1 <<\\EOF\n-#include <stdio.h>\n+test_diff_frobnitz \"patience\"\n \n-// Frobs foo heartily\n-int frobnitz(int foo)\n-{\n-    int i;\n-    for(i = 0; i < 10; i++)\n-    {\n-        printf(\"Your answer is: \");\n-        printf(\"%d\\n\", foo);\n-    }\n-}\n-\n-int fact(int n)\n-{\n-    if(n > 1)\n-    {\n-        return fact(n-1) * n;\n-    }\n-    return 1;\n-}\n-\n-int main(int argc, char **argv)\n-{\n-    frobnitz(fact(10));\n-}\n-EOF\n-\n-cat >file2 <<\\EOF\n-#include <stdio.h>\n-\n-int fib(int n)\n-{\n-    if(n > 2)\n-    {\n-        return fib(n-1) + fib(n-2);\n-    }\n-    return 1;\n-}\n-\n-// Frobs foo heartily\n-int frobnitz(int foo)\n-{\n-    int i;\n-    for(i = 0; i < 10; i++)\n-    {\n-        printf(\"%d\\n\", foo);\n-    }\n-}\n-\n-int main(int argc, char **argv)\n-{\n-    frobnitz(fib(10));\n-}\n-EOF\n-\n-cat >expect <<\\EOF\n-diff --git a/file1 b/file2\n-index 6faa5a3..e3af329 100644\n---- a/file1\n-+++ b/file2\n-@@ -1,26 +1,25 @@\n- #include <stdio.h>\n- \n-+int fib(int n)\n-+{\n-+    if(n > 2)\n-+    {\n-+        return fib(n-1) + fib(n-2);\n-+    }\n-+    return 1;\n-+}\n-+\n- // Frobs foo heartily\n- int frobnitz(int foo)\n- {\n-     int i;\n-     for(i = 0; i < 10; i++)\n-     {\n--        printf(\"Your answer is: \");\n-         printf(\"%d\\n\", foo);\n-     }\n- }\n- \n--int fact(int n)\n--{\n--    if(n > 1)\n--    {\n--        return fact(n-1) * n;\n--    }\n--    return 1;\n--}\n--\n- int main(int argc, char **argv)\n- {\n--    frobnitz(fact(10));\n-+    frobnitz(fib(10));\n- }\n-EOF\n-\n-test_expect_success 'patience diff' '\n-\n-\ttest_must_fail git diff --no-index --patience file1 file2 > output &&\n-\ttest_cmp expect output\n-\n-'\n-\n-test_expect_success 'patience diff output is valid' '\n-\n-\tmv file2 expect &&\n-\tgit apply < output &&\n-\ttest_cmp expect file2\n-\n-'\n-\n-cat >uniq1 <<\\EOF\n-1\n-2\n-3\n-4\n-5\n-6\n-EOF\n-\n-cat >uniq2 <<\\EOF\n-a\n-b\n-c\n-d\n-e\n-f\n-EOF\n-\n-cat >expect <<\\EOF\n-diff --git a/uniq1 b/uniq2\n-index b414108..0fdf397 100644\n---- a/uniq1\n-+++ b/uniq2\n-@@ -1,6 +1,6 @@\n--1\n--2\n--3\n--4\n--5\n--6\n-+a\n-+b\n-+c\n-+d\n-+e\n-+f\n-EOF\n-\n-test_expect_success 'completely different files' '\n-\n-\ttest_must_fail git diff --no-index --patience uniq1 uniq2 > output &&\n-\ttest_cmp expect output\n-\n-'\n+test_diff_unique \"patience\"\n \n test_done\n-- \n1.7.3.4.721.g4666.dirty\n"},{"id":"170933","messageId":"7vliwbmgv0.fsf@alter.siamese.dyndns.org","threadId":"27762","inReplyTo":"1309970337-6016-3-git-send-email-rctay89@gmail.com","subject":"Re: [PATCH v2 2/4] xdiff/xprepare: refactor abort cleanups","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-07-06T17:57:55Z","receivedAt":"2011-07-06T17:57:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Tay Ray Chuan <rctay89@gmail.com> writes:\n\n> Group free()'s that are called when a malloc() fails in\n> xdl_prepare_ctx(), making for more readable code.\n\nNicer, but I wonder if we can get away with a single label that lets us\nabort with freeing whatever we have allocated by making sure that the\nvarious pointer fields and variables are initialized to NULL, which may\nlead to even more readable code.\n"},{"id":"170936","messageId":"7vhb6zmgkg.fsf@alter.siamese.dyndns.org","threadId":"27762","inReplyTo":"1309970337-6016-5-git-send-email-rctay89@gmail.com","subject":"Re: [PATCH v2 4/4] t4033-diff-patience: factor out tests","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-07-06T18:04:15Z","receivedAt":"2011-07-06T18:04:15Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Tay Ray Chuan <rctay89@gmail.com> writes:\n\n> Group the test cases into two functions, test_diff_(frobnitz|unique).\n> This in preparation for the histogram diff algorithm, which would also\n> re-use these test cases.\n>\n> Signed-off-by: Tay Ray Chuan <rctay89@gmail.com>\n> ---\n>\n> Ram: the rename is detected in git-log, but not in the diffstat. The\n> expected and actual content, which makes up the bulk of content, is\n> unchanged, but the 'surrounding' changes should be pretty easy to spot.\n>\n>  t/lib-diff-patience.sh   |  163 ++++++++++++++++++++++++++++++++++++++++++++++\n\nPerhaps name this \"t/lib-diff-alternative.sh\" (or \"strategy\"), as this\nwill soon be for testing non-default diff backend algorithms, not just\npatience diff?\n\n>  t/t4033-diff-patience.sh |  162 +--------------------------------------------\n>  2 files changed, 166 insertions(+), 159 deletions(-)\n>  create mode 100644 t/lib-diff-patience.sh\n>\n> diff --git a/t/lib-diff-patience.sh b/t/lib-diff-patience.sh\n> new file mode 100644\n> index 0000000..761bb09\n> --- /dev/null\n> +++ b/t/lib-diff-patience.sh\n> @@ -0,0 +1,163 @@\n> ...\n> +\tSTRATEGY=$1\n> +\n> +\ttest_expect_success \"$STRATEGY diff\" '\n> +\t\ttest_must_fail git diff --no-index \"--$STRATEGY\" file1 file2 > output &&\n> +\t\ttest_cmp expect output\n> +\t'\n> +\n> +\ttest_expect_success \"$STRATEGY diff output is valid\" '\n> +\t\tmv file2 expect &&\n> +\t\tgit apply < output &&\n> +\t\ttest_cmp expect file2\n> +\t'\n> +}\n"},{"id":"170937","messageId":"CALUzUxqPf0nReHHhQ3zJoVbPAN7GNuzWeunWoxbzLuoYtuEbUw@mail.gmail.com","threadId":"27762","inReplyTo":"7vliwbmgv0.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v2 2/4] xdiff/xprepare: refactor abort cleanups","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2011-07-06T18:10:21Z","receivedAt":"2011-07-06T18:10:21Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"On Thu, Jul 7, 2011 at 1:57 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Tay Ray Chuan <rctay89@gmail.com> writes:\n>\n>> Group free()'s that are called when a malloc() fails in\n>> xdl_prepare_ctx(), making for more readable code.\n>\n> Nicer, but I wonder if we can get away with a single label that lets us\n> abort with freeing whatever we have allocated by making sure that the\n> various pointer fields and variables are initialized to NULL, which may\n> lead to even more readable code.\n\nPardon my dullness. Do you mean to check if the various fields are set\nto NULL upon allocation, and free()'ing them if so?\n\n-- \nCheers,\nRay Chuan\n"},{"id":"170953","messageId":"7vaacrhtp3.fsf@alter.siamese.dyndns.org","threadId":"27762","inReplyTo":"CALUzUxqPf0nReHHhQ3zJoVbPAN7GNuzWeunWoxbzLuoYtuEbUw@mail.gmail.com","subject":"Re: [PATCH v2 2/4] xdiff/xprepare: refactor abort cleanups","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-07-06T23:31:52Z","receivedAt":"2011-07-06T23:31:52Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Tay Ray Chuan <rctay89@gmail.com> writes:\n\n> On Thu, Jul 7, 2011 at 1:57 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Tay Ray Chuan <rctay89@gmail.com> writes:\n>>\n>>> Group free()'s that are called when a malloc() fails in\n>>> xdl_prepare_ctx(), making for more readable code.\n>>\n>> Nicer, but I wonder if we can get away with a single label that lets us\n>> abort with freeing whatever we have allocated by making sure that the\n>> various pointer fields and variables are initialized to NULL, which may\n>> lead to even more readable code.\n>\n> Pardon my dullness. Do you mean to check if the various fields are set\n> to NULL upon allocation, and free()'ing them if so?\n\nWhat I meant was that, instead of doing this:\n\n    func() {\n\tif (somefunc(&A, ...) < 0)\n\t\tgoto failA;\n        ... do something ...\n\tB = someotheralloc();\n        if (!B)\n        \tgoto failB;\n        ... do something ...\n\tC = yetanotheralloc();\n        if (!C)\n        \tgoto failC;\n\t... do things using A, B, C ...\n\n\treturn 0;\n    failC:\n    \tfree(B);\n    failB:\n\tfree(A);\n    failA:\n        return -1;\n    }\n\nit would be easier to follow if you did:\n\n    func() {\n\tA = B = C = NULL;\n\tif (somefunc(&A, ...) < 0)\n\t\tgoto fail;\n        ... do something ...\n\tB = someotheralloc();\n        if (!B)\n        \tgoto fail;\n        ... do something ...\n\tC = yetanotheralloc();\n        if (!C)\n        \tgoto fail;\n\t... do things using A, B, C ...\n\n    fail:\n        free(B);\n    \tfree(A);\n        return -1;\n    }\n\nEspecially when you have more than 2 such fail labels.\n"},{"id":"170956","messageId":"4E152E31.4020105@cisco.com","threadId":"27762","inReplyTo":"7vaacrhtp3.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v2 2/4] xdiff/xprepare: refactor abort cleanups","fromName":"Phil Hord","fromEmail":"hordp@cisco.com","sentAt":"2011-07-07T03:55:29Z","receivedAt":"2011-07-07T03:55:29Z","isPatch":true,"sender":{"key":"phil.hord@gmail.com","avatar":"https://avatars.githubusercontent.com/u/123908?v=4"},"body":"\n\nOn 07/06/2011 07:31 PM, Junio C Hamano wrote:\n> Tay Ray Chuan <rctay89@gmail.com> writes:\n>\n>> On Thu, Jul 7, 2011 at 1:57 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>>> Tay Ray Chuan <rctay89@gmail.com> writes:\n>>>\n>>>> Group free()'s that are called when a malloc() fails in\n>>>> xdl_prepare_ctx(), making for more readable code.\n>>> Nicer, but I wonder if we can get away with a single label that lets us\n>>> abort with freeing whatever we have allocated by making sure that the\n>>> various pointer fields and variables are initialized to NULL, which may\n>>> lead to even more readable code.\n>> Pardon my dullness. Do you mean to check if the various fields are set\n>> to NULL upon allocation, and free()'ing them if so?\n> What I meant was that, instead of doing this:\n>\n>     func() {\n> \tif (somefunc(&A, ...) < 0)\n> \t\tgoto failA;\n>         ... do something ...\n> \tB = someotheralloc();\n>         if (!B)\n>         \tgoto failB;\n>         ... do something ...\n> \tC = yetanotheralloc();\n>         if (!C)\n>         \tgoto failC;\n> \t... do things using A, B, C ...\n>\n> \treturn 0;\n>     failC:\n>     \tfree(B);\n>     failB:\n> \tfree(A);\n>     failA:\n>         return -1;\n>     }\n>\n> it would be easier to follow if you did:\n>\n>     func() {\n> \tA = B = C = NULL;\n> \tif (somefunc(&A, ...) < 0)\n> \t\tgoto fail;\n>         ... do something ...\n> \tB = someotheralloc();\n>         if (!B)\n>         \tgoto fail;\n>         ... do something ...\n> \tC = yetanotheralloc();\n>         if (!C)\n>         \tgoto fail;\n> \t... do things using A, B, C ...\n>\n>     fail:\n>         free(B);\n>     \tfree(A);\n>         return -1;\n>     }\n>\n> Especially when you have more than 2 such fail labels.\n\n\nBecause 'free(NULL)' is handled sanely (as a no-op).\nhttp://pubs.opengroup.org/onlinepubs/009695399/functions/free.html\n\nI haven't looked, but I assume xdl_cha_free does the same thing.  I only\nassume this because Junio seems to imply it, though.\n\nPhil\n"},{"id":"170957","messageId":"CALUzUxoSBVfzEhvKQahhRXCDsFs5nQvfHeohHUJMeJ7QYMv3wA@mail.gmail.com","threadId":"27762","inReplyTo":"4E152E31.4020105@cisco.com","subject":"Re: [PATCH v2 2/4] xdiff/xprepare: refactor abort cleanups","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2011-07-07T04:05:26Z","receivedAt":"2011-07-07T04:05:26Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"On Thu, Jul 7, 2011 at 11:55 AM, Phil Hord <hordp@cisco.com> wrote:\n> Because 'free(NULL)' is handled sanely (as a no-op).\n> http://pubs.opengroup.org/onlinepubs/009695399/functions/free.html\n\nYup, I got what Junio meant after he posted an example. (Thanks Junio.)\n\n> I haven't looked, but I assume xdl_cha_free does the same thing.  I only\n> assume this because Junio seems to imply it, though.\n\nxdl_cha_(init|free)() do something more complicated, so we don't have\nto set xdf->cha to NULL, unlike the others.\n\n-- \nCheers,\nRay Chuan\n"},{"id":"170959","messageId":"1310012638-3668-1-git-send-email-rctay89@gmail.com","threadId":"27762","inReplyTo":"1309970337-6016-1-git-send-email-rctay89@gmail.com","subject":"[PATCH v3 0/4] prepare for histogram diff","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2011-07-07T04:23:54Z","receivedAt":"2011-07-07T04:23:54Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Tay Ray Chuan (4):\n  xdiff/xprepare: use memset()\n  xdiff/xprepare: refactor abort cleanups\n  xdiff/xpatience: factor out fall-back-diff function\n  t4033-diff-patience: factor out tests\n\n t/lib-diff-alternative.sh |  165 +++++++++++++++++++++++++++++++++++++++++++++\n t/t4033-diff-patience.sh  |  162 +-------------------------------------------\n xdiff/xpatience.c         |   27 +-------\n xdiff/xprepare.c          |  101 ++++++++++------------------\n xdiff/xutils.c            |   31 +++++++++\n xdiff/xutils.h            |    2 +\n 6 files changed, 238 insertions(+), 250 deletions(-)\n create mode 100644 t/lib-diff-alternative.sh\n\n-- \n1.7.3.4.676.gf08cd.dirty\n"},{"id":"170958","messageId":"1310012638-3668-2-git-send-email-rctay89@gmail.com","threadId":"27762","inReplyTo":"1310012638-3668-1-git-send-email-rctay89@gmail.com","subject":"[PATCH v3 1/4] xdiff/xprepare: use memset()","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2011-07-07T04:23:55Z","receivedAt":"2011-07-07T04:23:55Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Use memset() instead of a for loop to initialize. This could give a\nperformance advantage.\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n---\n xdiff/xprepare.c |   10 +++-------\n 1 files changed, 3 insertions(+), 7 deletions(-)\n\ndiff --git a/xdiff/xprepare.c b/xdiff/xprepare.c\nindex 1689085..783631a 100644\n--- a/xdiff/xprepare.c\n+++ b/xdiff/xprepare.c\n@@ -64,8 +64,6 @@ static int xdl_optimize_ctxs(xdfile_t *xdf1, xdfile_t *xdf2);\n \n \n static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags) {\n-\tlong i;\n-\n \tcf->flags = flags;\n \n \tcf->hbits = xdl_hashbits((unsigned int) size);\n@@ -80,8 +78,7 @@ static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags) {\n \t\txdl_cha_free(&cf->ncha);\n \t\treturn -1;\n \t}\n-\tfor (i = 0; i < cf->hsize; i++)\n-\t\tcf->rchash[i] = NULL;\n+\tmemset(cf->rchash, 0, cf->hsize * sizeof(xdlclass_t *));\n \n \tcf->count = 0;\n \n@@ -136,7 +133,7 @@ static int xdl_classify_record(xdlclassifier_t *cf, xrecord_t **rhash, unsigned\n static int xdl_prepare_ctx(mmfile_t *mf, long narec, xpparam_t const *xpp,\n \t\t\t   xdlclassifier_t *cf, xdfile_t *xdf) {\n \tunsigned int hbits;\n-\tlong i, nrec, hsize, bsize;\n+\tlong nrec, hsize, bsize;\n \tunsigned long hav;\n \tchar const *blk, *cur, *top, *prev;\n \txrecord_t *crec;\n@@ -164,8 +161,7 @@ static int xdl_prepare_ctx(mmfile_t *mf, long narec, xpparam_t const *xpp,\n \t\txdl_cha_free(&xdf->rcha);\n \t\treturn -1;\n \t}\n-\tfor (i = 0; i < hsize; i++)\n-\t\trhash[i] = NULL;\n+\tmemset(rhash, 0, hsize * sizeof(xrecord_t *));\n \n \tnrec = 0;\n \tif ((cur = blk = xdl_mmfile_first(mf, &bsize)) != NULL) {\n-- \n1.7.3.4.676.gf08cd.dirty\n"},{"id":"170961","messageId":"1310012638-3668-3-git-send-email-rctay89@gmail.com","threadId":"27762","inReplyTo":"1310012638-3668-2-git-send-email-rctay89@gmail.com","subject":"[PATCH v3 2/4] xdiff/xprepare: refactor abort cleanups","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2011-07-07T04:23:56Z","receivedAt":"2011-07-07T04:23:56Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Group free()'s that are called when a malloc() fails in\nxdl_prepare_ctx(), making for more readable code.\n\nAlso add a free() on ha, in case future git hackers add allocs after the\nha malloc.\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n---\n\nChanged from v2: took up Junio's suggestion and used one cleanup label\nonly.\n\n xdiff/xprepare.c |   91 +++++++++++++++++++-----------------------------------\n 1 files changed, 32 insertions(+), 59 deletions(-)\n\ndiff --git a/xdiff/xprepare.c b/xdiff/xprepare.c\nindex 783631a..0f571db 100644\n--- a/xdiff/xprepare.c\n+++ b/xdiff/xprepare.c\n@@ -143,24 +143,21 @@ static int xdl_prepare_ctx(mmfile_t *mf, long narec, xpparam_t const *xpp,\n \tchar *rchg;\n \tlong *rindex;\n \n-\tif (xdl_cha_init(&xdf->rcha, sizeof(xrecord_t), narec / 4 + 1) < 0) {\n+\tha = NULL;\n+\trindex = NULL;\n+\trchg = NULL;\n+\trhash = NULL;\n+\trecs = NULL;\n \n-\t\treturn -1;\n-\t}\n-\tif (!(recs = (xrecord_t **) xdl_malloc(narec * sizeof(xrecord_t *)))) {\n-\n-\t\txdl_cha_free(&xdf->rcha);\n-\t\treturn -1;\n-\t}\n+\tif (xdl_cha_init(&xdf->rcha, sizeof(xrecord_t), narec / 4 + 1) < 0)\n+\t\tgoto abort;\n+\tif (!(recs = (xrecord_t **) xdl_malloc(narec * sizeof(xrecord_t *))))\n+\t\tgoto abort;\n \n \thbits = xdl_hashbits((unsigned int) narec);\n \thsize = 1 << hbits;\n-\tif (!(rhash = (xrecord_t **) xdl_malloc(hsize * sizeof(xrecord_t *)))) {\n-\n-\t\txdl_free(recs);\n-\t\txdl_cha_free(&xdf->rcha);\n-\t\treturn -1;\n-\t}\n+\tif (!(rhash = (xrecord_t **) xdl_malloc(hsize * sizeof(xrecord_t *))))\n+\t\tgoto abort;\n \tmemset(rhash, 0, hsize * sizeof(xrecord_t *));\n \n \tnrec = 0;\n@@ -175,63 +172,30 @@ static int xdl_prepare_ctx(mmfile_t *mf, long narec, xpparam_t const *xpp,\n \t\t\thav = xdl_hash_record(&cur, top, xpp->flags);\n \t\t\tif (nrec >= narec) {\n \t\t\t\tnarec *= 2;\n-\t\t\t\tif (!(rrecs = (xrecord_t **) xdl_realloc(recs, narec * sizeof(xrecord_t *)))) {\n-\n-\t\t\t\t\txdl_free(rhash);\n-\t\t\t\t\txdl_free(recs);\n-\t\t\t\t\txdl_cha_free(&xdf->rcha);\n-\t\t\t\t\treturn -1;\n-\t\t\t\t}\n+\t\t\t\tif (!(rrecs = (xrecord_t **) xdl_realloc(recs, narec * sizeof(xrecord_t *))))\n+\t\t\t\t\tgoto abort;\n \t\t\t\trecs = rrecs;\n \t\t\t}\n-\t\t\tif (!(crec = xdl_cha_alloc(&xdf->rcha))) {\n-\n-\t\t\t\txdl_free(rhash);\n-\t\t\t\txdl_free(recs);\n-\t\t\t\txdl_cha_free(&xdf->rcha);\n-\t\t\t\treturn -1;\n-\t\t\t}\n+\t\t\tif (!(crec = xdl_cha_alloc(&xdf->rcha)))\n+\t\t\t\tgoto abort;\n \t\t\tcrec->ptr = prev;\n \t\t\tcrec->size = (long) (cur - prev);\n \t\t\tcrec->ha = hav;\n \t\t\trecs[nrec++] = crec;\n \n-\t\t\tif (xdl_classify_record(cf, rhash, hbits, crec) < 0) {\n-\n-\t\t\t\txdl_free(rhash);\n-\t\t\t\txdl_free(recs);\n-\t\t\t\txdl_cha_free(&xdf->rcha);\n-\t\t\t\treturn -1;\n-\t\t\t}\n+\t\t\tif (xdl_classify_record(cf, rhash, hbits, crec) < 0)\n+\t\t\t\tgoto abort;\n \t\t}\n \t}\n \n-\tif (!(rchg = (char *) xdl_malloc((nrec + 2) * sizeof(char)))) {\n-\n-\t\txdl_free(rhash);\n-\t\txdl_free(recs);\n-\t\txdl_cha_free(&xdf->rcha);\n-\t\treturn -1;\n-\t}\n+\tif (!(rchg = (char *) xdl_malloc((nrec + 2) * sizeof(char))))\n+\t\tgoto abort;\n \tmemset(rchg, 0, (nrec + 2) * sizeof(char));\n \n-\tif (!(rindex = (long *) xdl_malloc((nrec + 1) * sizeof(long)))) {\n-\n-\t\txdl_free(rchg);\n-\t\txdl_free(rhash);\n-\t\txdl_free(recs);\n-\t\txdl_cha_free(&xdf->rcha);\n-\t\treturn -1;\n-\t}\n-\tif (!(ha = (unsigned long *) xdl_malloc((nrec + 1) * sizeof(unsigned long)))) {\n-\n-\t\txdl_free(rindex);\n-\t\txdl_free(rchg);\n-\t\txdl_free(rhash);\n-\t\txdl_free(recs);\n-\t\txdl_cha_free(&xdf->rcha);\n-\t\treturn -1;\n-\t}\n+\tif (!(rindex = (long *) xdl_malloc((nrec + 1) * sizeof(long))))\n+\t\tgoto abort;\n+\tif (!(ha = (unsigned long *) xdl_malloc((nrec + 1) * sizeof(unsigned long))))\n+\t\tgoto abort;\n \n \txdf->nrec = nrec;\n \txdf->recs = recs;\n@@ -245,6 +209,15 @@ static int xdl_prepare_ctx(mmfile_t *mf, long narec, xpparam_t const *xpp,\n \txdf->dend = nrec - 1;\n \n \treturn 0;\n+\n+abort:\n+\txdl_free(ha);\n+\txdl_free(rindex);\n+\txdl_free(rchg);\n+\txdl_free(rhash);\n+\txdl_free(recs);\n+\txdl_cha_free(&xdf->rcha);\n+\treturn -1;\n }\n \n \n-- \n1.7.3.4.676.gf08cd.dirty\n"},{"id":"170960","messageId":"1310012638-3668-4-git-send-email-rctay89@gmail.com","threadId":"27762","inReplyTo":"1310012638-3668-3-git-send-email-rctay89@gmail.com","subject":"[PATCH v3 3/4] xdiff/xpatience: factor out fall-back-diff function","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2011-07-07T04:23:57Z","receivedAt":"2011-07-07T04:23:57Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"This is in preparation for the histogram diff algorithm, which will also\nre-use much of the code to call the default Meyers diff algorithm.\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n---\n xdiff/xpatience.c |   27 ++-------------------------\n xdiff/xutils.c    |   31 +++++++++++++++++++++++++++++++\n xdiff/xutils.h    |    2 ++\n 3 files changed, 35 insertions(+), 25 deletions(-)\n\ndiff --git a/xdiff/xpatience.c b/xdiff/xpatience.c\nindex e42c16a..fdd7d02 100644\n--- a/xdiff/xpatience.c\n+++ b/xdiff/xpatience.c\n@@ -287,34 +287,11 @@ static int walk_common_sequence(struct hashmap *map, struct entry *first,\n static int fall_back_to_classic_diff(struct hashmap *map,\n \t\tint line1, int count1, int line2, int count2)\n {\n-\t/*\n-\t * This probably does not work outside Git, since\n-\t * we have a very simple mmfile structure.\n-\t *\n-\t * Note: ideally, we would reuse the prepared environment, but\n-\t * the libxdiff interface does not (yet) allow for diffing only\n-\t * ranges of lines instead of the whole files.\n-\t */\n-\tmmfile_t subfile1, subfile2;\n \txpparam_t xpp;\n-\txdfenv_t env;\n-\n-\tsubfile1.ptr = (char *)map->env->xdf1.recs[line1 - 1]->ptr;\n-\tsubfile1.size = map->env->xdf1.recs[line1 + count1 - 2]->ptr +\n-\t\tmap->env->xdf1.recs[line1 + count1 - 2]->size - subfile1.ptr;\n-\tsubfile2.ptr = (char *)map->env->xdf2.recs[line2 - 1]->ptr;\n-\tsubfile2.size = map->env->xdf2.recs[line2 + count2 - 2]->ptr +\n-\t\tmap->env->xdf2.recs[line2 + count2 - 2]->size - subfile2.ptr;\n \txpp.flags = map->xpp->flags & ~XDF_PATIENCE_DIFF;\n-\tif (xdl_do_diff(&subfile1, &subfile2, &xpp, &env) < 0)\n-\t\treturn -1;\n \n-\tmemcpy(map->env->xdf1.rchg + line1 - 1, env.xdf1.rchg, count1);\n-\tmemcpy(map->env->xdf2.rchg + line2 - 1, env.xdf2.rchg, count2);\n-\n-\txdl_free_env(&env);\n-\n-\treturn 0;\n+\treturn xdl_fall_back_diff(map->env, &xpp,\n+\t\t\t\t  line1, count1, line2, count2);\n }\n \n /*\ndiff --git a/xdiff/xutils.c b/xdiff/xutils.c\nindex ab65034..ded7c32 100644\n--- a/xdiff/xutils.c\n+++ b/xdiff/xutils.c\n@@ -402,3 +402,34 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,\n \n \treturn 0;\n }\n+\n+int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,\n+\t\tint line1, int count1, int line2, int count2)\n+{\n+\t/*\n+\t * This probably does not work outside Git, since\n+\t * we have a very simple mmfile structure.\n+\t *\n+\t * Note: ideally, we would reuse the prepared environment, but\n+\t * the libxdiff interface does not (yet) allow for diffing only\n+\t * ranges of lines instead of the whole files.\n+\t */\n+\tmmfile_t subfile1, subfile2;\n+\txdfenv_t env;\n+\n+\tsubfile1.ptr = (char *)diff_env->xdf1.recs[line1 - 1]->ptr;\n+\tsubfile1.size = diff_env->xdf1.recs[line1 + count1 - 2]->ptr +\n+\t\tdiff_env->xdf1.recs[line1 + count1 - 2]->size - subfile1.ptr;\n+\tsubfile2.ptr = (char *)diff_env->xdf2.recs[line2 - 1]->ptr;\n+\tsubfile2.size = diff_env->xdf2.recs[line2 + count2 - 2]->ptr +\n+\t\tdiff_env->xdf2.recs[line2 + count2 - 2]->size - subfile2.ptr;\n+\tif (xdl_do_diff(&subfile1, &subfile2, xpp, &env) < 0)\n+\t\treturn -1;\n+\n+\tmemcpy(diff_env->xdf1.rchg + line1 - 1, env.xdf1.rchg, count1);\n+\tmemcpy(diff_env->xdf2.rchg + line2 - 1, env.xdf2.rchg, count2);\n+\n+\txdl_free_env(&env);\n+\n+\treturn 0;\n+}\ndiff --git a/xdiff/xutils.h b/xdiff/xutils.h\nindex d5de829..674a657 100644\n--- a/xdiff/xutils.h\n+++ b/xdiff/xutils.h\n@@ -41,6 +41,8 @@ int xdl_num_out(char *out, long val);\n long xdl_atol(char const *str, char const **next);\n int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,\n \t\t      const char *func, long funclen, xdemitcb_t *ecb);\n+int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,\n+\t\t       int line1, int count1, int line2, int count2);\n \n \n \n-- \n1.7.3.4.676.gf08cd.dirty\n"},{"id":"170962","messageId":"1310012638-3668-5-git-send-email-rctay89@gmail.com","threadId":"27762","inReplyTo":"1310012638-3668-4-git-send-email-rctay89@gmail.com","subject":"[PATCH v3 4/4] t4033-diff-patience: factor out tests","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2011-07-07T04:23:58Z","receivedAt":"2011-07-07T04:23:58Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"Group the test cases into two functions, test_diff_(frobnitz|unique).\nThis in preparation for the histogram diff algorithm, which would also\nre-use these test cases.\n\nSigned-off-by: Tay Ray Chuan <rctay89@gmail.com>\n---\n\nChanged from v2: refactored tests live in lib-diff-alternative.sh\ninstead of lib-diff-patience.sh.\n\n t/lib-diff-alternative.sh |  165 +++++++++++++++++++++++++++++++++++++++++++++\n t/t4033-diff-patience.sh  |  162 +-------------------------------------------\n 2 files changed, 168 insertions(+), 159 deletions(-)\n create mode 100644 t/lib-diff-alternative.sh\n\ndiff --git a/t/lib-diff-alternative.sh b/t/lib-diff-alternative.sh\nnew file mode 100644\nindex 0000000..75ffd91\n--- /dev/null\n+++ b/t/lib-diff-alternative.sh\n@@ -0,0 +1,165 @@\n+#!/bin/sh\n+\n+test_diff_frobnitz() {\n+\tcat >file1 <<\\EOF\n+#include <stdio.h>\n+\n+// Frobs foo heartily\n+int frobnitz(int foo)\n+{\n+    int i;\n+    for(i = 0; i < 10; i++)\n+    {\n+        printf(\"Your answer is: \");\n+        printf(\"%d\\n\", foo);\n+    }\n+}\n+\n+int fact(int n)\n+{\n+    if(n > 1)\n+    {\n+        return fact(n-1) * n;\n+    }\n+    return 1;\n+}\n+\n+int main(int argc, char **argv)\n+{\n+    frobnitz(fact(10));\n+}\n+EOF\n+\n+\tcat >file2 <<\\EOF\n+#include <stdio.h>\n+\n+int fib(int n)\n+{\n+    if(n > 2)\n+    {\n+        return fib(n-1) + fib(n-2);\n+    }\n+    return 1;\n+}\n+\n+// Frobs foo heartily\n+int frobnitz(int foo)\n+{\n+    int i;\n+    for(i = 0; i < 10; i++)\n+    {\n+        printf(\"%d\\n\", foo);\n+    }\n+}\n+\n+int main(int argc, char **argv)\n+{\n+    frobnitz(fib(10));\n+}\n+EOF\n+\n+\tcat >expect <<\\EOF\n+diff --git a/file1 b/file2\n+index 6faa5a3..e3af329 100644\n+--- a/file1\n++++ b/file2\n+@@ -1,26 +1,25 @@\n+ #include <stdio.h>\n+ \n++int fib(int n)\n++{\n++    if(n > 2)\n++    {\n++        return fib(n-1) + fib(n-2);\n++    }\n++    return 1;\n++}\n++\n+ // Frobs foo heartily\n+ int frobnitz(int foo)\n+ {\n+     int i;\n+     for(i = 0; i < 10; i++)\n+     {\n+-        printf(\"Your answer is: \");\n+         printf(\"%d\\n\", foo);\n+     }\n+ }\n+ \n+-int fact(int n)\n+-{\n+-    if(n > 1)\n+-    {\n+-        return fact(n-1) * n;\n+-    }\n+-    return 1;\n+-}\n+-\n+ int main(int argc, char **argv)\n+ {\n+-    frobnitz(fact(10));\n++    frobnitz(fib(10));\n+ }\n+EOF\n+\n+\tSTRATEGY=$1\n+\n+\ttest_expect_success \"$STRATEGY diff\" '\n+\t\ttest_must_fail git diff --no-index \"--$STRATEGY\" file1 file2 > output &&\n+\t\ttest_cmp expect output\n+\t'\n+\n+\ttest_expect_success \"$STRATEGY diff output is valid\" '\n+\t\tmv file2 expect &&\n+\t\tgit apply < output &&\n+\t\ttest_cmp expect file2\n+\t'\n+}\n+\n+test_diff_unique() {\n+\tcat >uniq1 <<\\EOF\n+1\n+2\n+3\n+4\n+5\n+6\n+EOF\n+\n+\tcat >uniq2 <<\\EOF\n+a\n+b\n+c\n+d\n+e\n+f\n+EOF\n+\n+\tcat >expect <<\\EOF\n+diff --git a/uniq1 b/uniq2\n+index b414108..0fdf397 100644\n+--- a/uniq1\n++++ b/uniq2\n+@@ -1,6 +1,6 @@\n+-1\n+-2\n+-3\n+-4\n+-5\n+-6\n++a\n++b\n++c\n++d\n++e\n++f\n+EOF\n+\n+\tSTRATEGY=$1\n+\n+\ttest_expect_success 'completely different files' '\n+\t\ttest_must_fail git diff --no-index \"--$STRATEGY\" uniq1 uniq2 > output &&\n+\t\ttest_cmp expect output\n+\t'\n+}\n+\ndiff --git a/t/t4033-diff-patience.sh b/t/t4033-diff-patience.sh\nindex 1eb1498..3c9932e 100755\n--- a/t/t4033-diff-patience.sh\n+++ b/t/t4033-diff-patience.sh\n@@ -3,166 +3,10 @@\n test_description='patience diff algorithm'\n \n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-diff-alternative.sh\n \n-cat >file1 <<\\EOF\n-#include <stdio.h>\n+test_diff_frobnitz \"patience\"\n \n-// Frobs foo heartily\n-int frobnitz(int foo)\n-{\n-    int i;\n-    for(i = 0; i < 10; i++)\n-    {\n-        printf(\"Your answer is: \");\n-        printf(\"%d\\n\", foo);\n-    }\n-}\n-\n-int fact(int n)\n-{\n-    if(n > 1)\n-    {\n-        return fact(n-1) * n;\n-    }\n-    return 1;\n-}\n-\n-int main(int argc, char **argv)\n-{\n-    frobnitz(fact(10));\n-}\n-EOF\n-\n-cat >file2 <<\\EOF\n-#include <stdio.h>\n-\n-int fib(int n)\n-{\n-    if(n > 2)\n-    {\n-        return fib(n-1) + fib(n-2);\n-    }\n-    return 1;\n-}\n-\n-// Frobs foo heartily\n-int frobnitz(int foo)\n-{\n-    int i;\n-    for(i = 0; i < 10; i++)\n-    {\n-        printf(\"%d\\n\", foo);\n-    }\n-}\n-\n-int main(int argc, char **argv)\n-{\n-    frobnitz(fib(10));\n-}\n-EOF\n-\n-cat >expect <<\\EOF\n-diff --git a/file1 b/file2\n-index 6faa5a3..e3af329 100644\n---- a/file1\n-+++ b/file2\n-@@ -1,26 +1,25 @@\n- #include <stdio.h>\n- \n-+int fib(int n)\n-+{\n-+    if(n > 2)\n-+    {\n-+        return fib(n-1) + fib(n-2);\n-+    }\n-+    return 1;\n-+}\n-+\n- // Frobs foo heartily\n- int frobnitz(int foo)\n- {\n-     int i;\n-     for(i = 0; i < 10; i++)\n-     {\n--        printf(\"Your answer is: \");\n-         printf(\"%d\\n\", foo);\n-     }\n- }\n- \n--int fact(int n)\n--{\n--    if(n > 1)\n--    {\n--        return fact(n-1) * n;\n--    }\n--    return 1;\n--}\n--\n- int main(int argc, char **argv)\n- {\n--    frobnitz(fact(10));\n-+    frobnitz(fib(10));\n- }\n-EOF\n-\n-test_expect_success 'patience diff' '\n-\n-\ttest_must_fail git diff --no-index --patience file1 file2 > output &&\n-\ttest_cmp expect output\n-\n-'\n-\n-test_expect_success 'patience diff output is valid' '\n-\n-\tmv file2 expect &&\n-\tgit apply < output &&\n-\ttest_cmp expect file2\n-\n-'\n-\n-cat >uniq1 <<\\EOF\n-1\n-2\n-3\n-4\n-5\n-6\n-EOF\n-\n-cat >uniq2 <<\\EOF\n-a\n-b\n-c\n-d\n-e\n-f\n-EOF\n-\n-cat >expect <<\\EOF\n-diff --git a/uniq1 b/uniq2\n-index b414108..0fdf397 100644\n---- a/uniq1\n-+++ b/uniq2\n-@@ -1,6 +1,6 @@\n--1\n--2\n--3\n--4\n--5\n--6\n-+a\n-+b\n-+c\n-+d\n-+e\n-+f\n-EOF\n-\n-test_expect_success 'completely different files' '\n-\n-\ttest_must_fail git diff --no-index --patience uniq1 uniq2 > output &&\n-\ttest_cmp expect output\n-\n-'\n+test_diff_unique \"patience\"\n \n test_done\n-- \n1.7.3.4.676.gf08cd.dirty\n"}]}