]> git.neil.brown.name Git - wiggle.git/commitdiff
Get merge2 to pass all the tests...
authorNeil Brown <neilb@suse.de>
Thu, 25 May 2006 10:59:57 +0000 (10:59 +0000)
committerNeil Brown <neilb@suse.de>
Thu, 25 May 2006 10:59:57 +0000 (10:59 +0000)
Some of this done by changing tests...

Signed-off-by: Neil Brown <neilb@suse.de>
12 files changed:
merge2.c
tests/linux/idmap.h/merge
tests/linux/md-resync/merge
tests/linux/md/lmerge
tests/linux/md/merge
tests/linux/md/wmerge
tests/linux/raid5build/merge
tests/linux/raid5line/lmerge
tests/linux/raid5line/merge
tests/linux/raid5line/wmerge
tests/linux/rpc_tcp_nonagle/merge
wiggle.h

index aec9ef22aceaebd820a99841657824cdc2060591..808e18e134917926429d80749602c97e8a25e48e 100644 (file)
--- a/merge2.c
+++ b/merge2.c
@@ -94,6 +94,13 @@ inline int isolate_conflicts(struct file af, struct file bf, struct file cf,
         * Also, unless 'words', we need to include any partial lines
         * in the Unchanged text that forms the border of a conflict.
         *
+        * A Changed text may also border a conflict, but it can
+        * only border one conflict (where as an Unchanged can border
+        * a preceeding and a following conflict).
+        * The 'new' section of a Changed text appears in the
+        * conflict as does any part of the original before
+        * a newline.
+        *
         */
        int i,j,k;
        int cnt = 0;
@@ -115,7 +122,14 @@ inline int isolate_conflicts(struct file af, struct file bf, struct file cf,
                                if (!m[j].in_conflict) {
                                        m[j].in_conflict = 1;
                                        m[j].lo = 0;
+                               } else if (m[j].type == Changed) {
+                                       /* This can no longer form a border */
+                                       m[j].lo = 0; m[j].hi = -1;
+                                       /* We merge these conflicts and stop searching */
+                                       cnt--;
+                                       break;
                                }
+
                                if (m[j].type == Unchanged || m[j].type == Changed) {
                                        if (words) {
                                                m[j].hi = m[j].al;
@@ -125,23 +139,40 @@ inline int isolate_conflicts(struct file af, struct file bf, struct file cf,
                                         * might be after the last newline, if there
                                         * is one, or might be at the start
                                         */
-                                       for (k=m[j].al; k>0; k--) 
+                                       for (k=m[j].al; k>0; k--)
                                                if (ends_line(af.list[m[j].a+k-1]))
                                                        break;
-                                       if (k>0) {
+                                       if (k > 0)
                                                m[j].hi = k;
-                                               break;
-                                       }
-                                       if ((m[j].a == 0 || ends_line(af.list[m[j].a-1])) &&
-                                           (m[j].b == 0 || ends_line(bf.list[m[j].b-1])) &&
-                                           (m[j].c == 0 || ends_line(cf.list[m[j].c-1]))){
+                                       else if ((m[j].a == 0 || ends_line(af.list[m[j].a-1])) &&
+                                                (m[j].b == 0 || ends_line(bf.list[m[j].b-1])) &&
+                                                (m[j].c == 0 || ends_line(cf.list[m[j].c-1])))
                                                m[j].hi = 0;
-                                               break;
+                                       else
+                                               /* no start-of-line found... */
+                                               m[j].hi = -1;
+                                       if (m[j].hi > 0 && m[j].type == Changed) {
+                                               /* this can only work if start is also a linke break */
+                                               if ((m[j].a == 0 || ends_line(af.list[m[j].a-1])) &&
+                                                   (m[j].b == 0 || ends_line(bf.list[m[j].b-1])) &&
+                                                   (m[j].c == 0 || ends_line(cf.list[m[j].c-1])))
+                                                       /* ok */;
+                                               else
+                                                       m[j].hi = -1;
                                        }
-                                       /* no start-of-line found... */
-                                       m[j].hi = -1;
+                                       if (m[j].hi >= 0)
+                                               break;
                                }
                        }
+#if 0
+                       if (j>=0 && m[j].in_conflict && m[j].type == Unchanged &&
+                           m[j].hi == m[j].lo) {
+                               /* nothing to separate conflicts, merge them */
+                               m[j].lo = 0;
+                               m[j].hi = -1;
+                               cnt--;
+                       }
+#endif
                        /* now the forward search */
                        for (j=i+1; m[j].type != End; j++) {
                                m[j].in_conflict = 1;
@@ -157,19 +188,29 @@ inline int isolate_conflicts(struct file af, struct file bf, struct file cf,
                                         */
                                        if ((m[j].a == 0 || ends_line(af.list[m[j].a-1])) &&
                                            (m[j].b == 0 || ends_line(bf.list[m[j].b-1])) &&
-                                           (m[j].c == 0 || ends_line(cf.list[m[j].c-1]))){
+                                           (m[j].c == 0 || ends_line(cf.list[m[j].c-1])))
                                                m[j].lo = 0;
-                                               break;
+                                       else {
+                                               for (k = 0 ; k < m[j].al ; k++)
+                                                       if (ends_line(af.list[m[j].a+k]))
+                                                               break;
+                                               if (k<m[j].al)
+                                                       m[j].lo = k+1;
+                                               else
+                                                       /* no start-of-line found */
+                                                       m[j].lo = m[j].al+1;
                                        }
-                                       for (k=0; k<m[j].al; k++)
-                                               if (ends_line(af.list[m[j].a+k]))
-                                                       break;
-                                       if (k<m[j].al) {
-                                               m[j].lo = k+1;
-                                               break;
+                                       if (m[j].lo <= m[j].al+1 && m[j].type == Changed) {
+                                               /* this can only work if the end is a line break */
+                                               if (ends_line(af.list[m[j].a+m[j].al-1]) &&
+                                                   ends_line(bf.list[m[j].b+m[j].bl-1]) &&
+                                                   ends_line(cf.list[m[j].c+m[j].cl-1]))
+                                                       /* ok */;
+                                               else
+                                                       m[j].lo = m[j].al+1;
                                        }
-                                       /* no start-of-line found */
-                                       m[j].lo = m[j].al+1;
+                                       if (m[j].lo < m[j].al+1)
+                                               break;
                                }
                        }
                        i = j;
@@ -346,11 +387,11 @@ struct ci print_merge2(FILE *out, struct file *a, struct file *b, struct file *c
                         * Unchanged which is < it's hi
                         */
                        int st = m->hi;
+                       if (m->hi <= m->lo)
+                               st = 0;
 
                        if (m->type == Unchanged)
                                printrange(out, a, m->a+m->lo, m->hi - m->lo);
-                       else
-                               printrange(out, c, m->c, m->cl);
 
 #if 1
                if (v)
@@ -366,7 +407,7 @@ struct ci print_merge2(FILE *out, struct file *a, struct file *b, struct file *c
                                       cm->b, cm->b+cm->bl-1,
                                       cm->c, cm->c+cm->cl-1, cm->in_conflict?" in_conflict":"",
                                       cm->lo, cm->hi);
-                               if (cm->type == Unchanged && cm != m && cm->lo < cm->hi)
+                               if ((cm->type == Unchanged ||cm->type == Changed) && cm != m && cm->lo < cm->hi)
                                        break;
                        }
 #endif
@@ -393,17 +434,19 @@ struct ci print_merge2(FILE *out, struct file *a, struct file *b, struct file *c
                        fputs(words?"===":"=======\n", out);
                        st = m->hi;
                        for (cm=m; cm->in_conflict; cm++) {
-                               if ((cm->type == Unchanged || cm->type == Changed) && cm != m && cm->lo < cm->hi) {
-                                       if (cm->type == Unchanged)
-                                               printrange(out, c, cm->c, cm->lo);
+                               if (cm->type == Unchanged && cm != m && cm->lo < cm->hi) {
+                                       printrange(out, c, cm->c, cm->lo);
                                        break;
                                }
+                               if (cm->type == Changed)
+                                       st = 0; /* All of result of change must be printed */
                                printrange(out, c, cm->c+st, cm->cl-st);
                                st = 0;
                        }
                        fputs(words?"--->>>":">>>>>>>\n", out);
                        m = cm;
-                       if (m->type == Unchanged && m->in_conflict && m->hi >= m->al) {
+                       if (m->in_conflict && m->hi >= m->al) {
+                               assert(m->type == Unchanged);
                                printrange(out, a, m->a+m->lo, m->hi-m->lo);
                                m++;
                        }
@@ -414,6 +457,21 @@ struct ci print_merge2(FILE *out, struct file *a, struct file *b, struct file *c
                 */
                if (m->type == End)
                        break;
+#if 1
+               if (v) {
+                       printf("<<%s: %d-%d,%d-%d,%d-%d%s(%d,%d)>>\n",
+                              m->type==Unmatched?"Unmatched":
+                              m->type==Unchanged?"Unchanged":
+                              m->type==Extraneous?"Extraneous":
+                              m->type==Changed?"Changed":
+                              m->type==AlreadyApplied?"AlreadyApplied":
+                              m->type==Conflict?"Conflict":"unknown",
+                              m->a, m->a+m->al-1,
+                              m->b, m->b+m->bl-1,
+                              m->c, m->c+m->cl-1, m->in_conflict?" in_conflict":"",
+                              m->lo, m->hi);
+               }
+#endif
                switch(m->type) {
                case Unchanged:
                case AlreadyApplied:
index 6bccf325601a0c1013a33a02625700f8de433ad6..664ceea1a43b07eea77ec4c89c0125be8e2be54e 100644 (file)
@@ -1,2 +1,20 @@
+<<<<<<<
+|||||||
+*** 55,6 **** 1
+#define IDMAP_STATUS_LOOKUPFAIL IDMAP_STATUS_FAIL
+
+
+/* XXX get (include) from bits/utmp.h */
+#define IDMAP_NAMESZ  128
+
+=======
+*** 55,8 **** 1
+#define IDMAP_STATUS_LOOKUPFAIL IDMAP_STATUS_FAIL
+
+
 #define IDMAP_MAXMSGSZ   256
 
+/* XXX get (include) from bits/utmp.h */
+#define IDMAP_NAMESZ  128
+
+>>>>>>>
index eb8379e4af00c4c7a774ddd497be97bbc45193be..d6ff33e1924c1fd23e0f353d51d382a57add6aca 100644 (file)
@@ -1148,7 +1148,11 @@ abort:
                mempool_destroy(conf->r1buf_pool);
                conf->r1buf_pool = NULL;
        }
+
+       print_conf(conf);
 =======
+
+       print_conf(conf);
 >>>>>>>
        return err;
 }
@@ -1314,6 +1318,10 @@ static int init_resync (conf_t *conf)
                        return -ENOMEM;
 
 <<<<<<<
+       close_sync(conf);
+
+}
+
 /*
  * perform a "sync" on one "block"
  *
@@ -1472,6 +1480,10 @@ static int raid1_sync_request (mddev_t *mddev, unsigned long sector_nr)
 
        return (bsize >> 9);
 |||||||
+       close_sync(conf);
+
+}
+
 static int init_resync(conf_t *conf)
 {
 *** 1170,9 **** 8
@@ -1485,6 +1497,19 @@ nomem:
        raid1_shrink_buffers(conf);
        return -ENOMEM;
 }
+|||||||
+       if (!sector_nr)
+               if (init_resync(conf))
+                       return -ENOMEM;
+       /*
+=======
+       if (sector_nr >= max_sector) {
+               close_sync(conf);
+               return 0;
+       }
+
+       /*
+>>>>>>>
 
 static void end_sync_read(struct buffer_head *bh, int uptodate)
 {
@@ -1513,37 +1538,7 @@ static void end_sync_write(struct buffer_head *bh, int uptodate)
                int size = bh->b_size;
                raid1_free_buf(r1_bh);
                sync_request_done(sect, mddev_to_conf(mddev));
-               md_done_sync(mddev,size>>9, uptodate);
-|||||||
-       if (!sector_nr)
-               if (init_resync(conf))
-                       return -ENOMEM;
-       /*
-        * If there is non-resync activity waiting for us then
-        * put in a delay to throttle resync.
-*** 1209,10 **** 9
-       r1_bio->sector = sector_nr;
-       r1_bio->cmd = SPECIAL;
-
-       max_sector = mddev->sb->size << 1;
-       if (sector_nr >= max_sector)
-               BUG();
-
-=======
-       if (sector_nr >= max_sector) {
-               close_sync(conf);
-               return 0;
-       }
-
-       /*
-        * If there is non-resync activity waiting for us then
-        * put in a delay to throttle resync.
-*** 1190,6 **** 9
-       r1_bio->sector = sector_nr;
-       r1_bio->cmd = SPECIAL;
-
->>>>>>>
-       }
+               md_done_sync(mddev,size>>9, uptodate    }
 }
 
 #define INVALID_LEVEL KERN_WARNING \
index 6440da96bbb236a009454c60f8689b34da10923c..4238601104e9db79015320603e016a0a67b6ae2a 100644 (file)
@@ -1436,12 +1436,6 @@ abort:
        return 1;
 }
 
-<<<<<<<
-|||||||
-#undef OLD_LEVEL
-
-=======
->>>>>>>
 static struct gendisk *md_probe(dev_t dev, int *part, void *data)
 {
        static DECLARE_MUTEX(disks_sem);
index 6440da96bbb236a009454c60f8689b34da10923c..4238601104e9db79015320603e016a0a67b6ae2a 100644 (file)
@@ -1436,12 +1436,6 @@ abort:
        return 1;
 }
 
-<<<<<<<
-|||||||
-#undef OLD_LEVEL
-
-=======
->>>>>>>
 static struct gendisk *md_probe(dev_t dev, int *part, void *data)
 {
        static DECLARE_MUTEX(disks_sem);
index 6aadb61f63bf68143e4e6bdbd09001edc1a9de67..4238601104e9db79015320603e016a0a67b6ae2a 100644 (file)
@@ -1436,9 +1436,7 @@ abort:
        return 1;
 }
 
-<<<---|||#undef OLD_LEVEL
-
-===--->>>static struct gendisk *md_probe(dev_t dev, int *part, void *data)
+static struct gendisk *md_probe(dev_t dev, int *part, void *data)
 {
        static DECLARE_MUTEX(disks_sem);
        int unit = MINOR(dev);
index 4a2ce921e05dad64e3803358e7f43be5a4f7041b..77cfac86e0d8399da6705e230fd02ef6c56575af 100644 (file)
@@ -22,8 +22,12 @@ static void raid5_build_block (struct stripe_head *sh, int i)
        dev->flags = 0;
        if (i != sh->pd_idx)
 <<<<<<<
+       bh->b_size      = sh->size;
        bh->b_list      = BUF_LOCKED;
+       return bh;
 |||||||
+       bh->b_size      = sh->size;
+       return bh;
 =======
                dev->sector = compute_blocknr(sh, i);
 >>>>>>>
index e6ffa40530356eba6b711d03cd50598cd653503d..ee56bcb0284b36b151871d72f3d54f43cfe121df 100644 (file)
@@ -1,7 +1,9 @@
 <<<<<<<
                clear_bit(BH_Uptodate, &sh->bh_cache[i]->b_state);
 |||||||
+*** 1,1 **** 1
                clear_buffer_uptodate(sh->bh_cache[i]);
 =======
+*** 1,1 **** 1
                dev->flags = 0;
 >>>>>>>
index e6ffa40530356eba6b711d03cd50598cd653503d..ee56bcb0284b36b151871d72f3d54f43cfe121df 100644 (file)
@@ -1,7 +1,9 @@
 <<<<<<<
                clear_bit(BH_Uptodate, &sh->bh_cache[i]->b_state);
 |||||||
+*** 1,1 **** 1
                clear_buffer_uptodate(sh->bh_cache[i]);
 =======
+*** 1,1 **** 1
                dev->flags = 0;
 >>>>>>>
index e2c810477cd6775a37ea651f2b0c1fbe5f56eeae..a8464d924b4b05d12d633f2345e0d185cdc4732c 100644 (file)
@@ -1 +1,3 @@
-<<<---         clear_bit(BH_Uptodate, &|||clear_buffer_uptodate(===dev--->>>-><<<---->b_state|||===flags = 0--->>>;
+<<<---         clear_bit(BH_Uptodate, &|||*** 1,1 **** 1
+               clear_buffer_uptodate(===*** 1,1 **** 1
+               dev--->>>-><<<---->b_state|||===flags = 0--->>>;
index 969115abbdd1245dbfe2e3c0f03df8d4da0130ac..c66c37a681a3ad0cfb27cb5e90b0e5b0d9ca2ef6 100644 (file)
@@ -1036,9 +1036,11 @@ svc_tcp_init(struct svc_sock *svsk)
 <<<<<<<
                /* initialise setting must have enough space to
 |||||||
+                /* initialise setting must have enough space to
 =======
                tp->nonagle = 1;        /* disable Nagle's algorithm */
 
+                /* initialise setting must have enough space to
 >>>>>>>
                 * receive and respond to one request.  
                 * svc_tcp_recvfrom will re-adjust if necessary
index 9cb2155985214877ef2a2122573c10f6de4cb811..fd526c9a267182ab8f1884d55db67a1365971e99 100644 (file)
--- a/wiggle.h
+++ b/wiggle.h
@@ -71,13 +71,36 @@ struct file {
        int elcnt;
 };
 
+/* The result of a merger is a series of text sections.
+ * Each section may occur in one or more of the three stream,
+ * and may be different in different stream (e.g. for changed text)
+ * or the same.
+ * When a conflict occurs we need to treat some surrouding
+ * sections as being involved in that conflict.  For
+ * word-based merging, all surrounding sections until an Unchanged
+ * section are part of the conflict - the Unchanged isn't.
+ * For line based merging, we need to find Unchanged sections
+ * that include a newline.  Further, text within the unchanged
+ * section upto the newline (in whichever direction) is treated
+ * as part of the whole conflict.
+ * Actually... it is possibly for a 'Changed' section to bound
+ * a conflict as it indicates a successful match of A and B.
+ * For wordwise merges, any Changed or Unchanged section bounds a conflict
+ * For linewise merges, and Changed or Unchanged section that matches
+ * a newline, or immediately follows a newline (in all files) can bound
+ * a conflict.
+ */
 struct merge {
        enum mergetype {End, Unmatched, Unchanged, Extraneous, Changed, Conflict, AlreadyApplied} type;
        int a,b,c; /* start of ranges */
        int al, bl, cl; /* length of ranges */
        int c1, c2; /* this or next commonsequence */
        int in_conflict; 
-       int lo,hi; /* region of an Unchanged that is not involved in a conflict */
+       int lo,hi; /* region of an Unchanged that is not involved in a conflict
+                   * These are distances from start of the section, not
+                   * indexes into any file
+                   */
+
 };
 extern struct stream load_file(char *name);
 extern int split_patch(struct stream, struct stream*, struct stream*);