@@ -62,6 +62,12 @@ struct hashmap {
6262 * initially, "next" reflects only the order in file1.
6363 */
6464 struct entry * next , * previous ;
65+
66+ /*
67+ * If 1, this entry can serve as an anchor. See
68+ * Documentation/diff-options.txt for more information.
69+ */
70+ unsigned anchor : 1 ;
6571 } * entries , * first , * last ;
6672 /* were common records found? */
6773 unsigned long has_matches ;
@@ -70,8 +76,19 @@ struct hashmap {
7076 xpparam_t const * xpp ;
7177};
7278
79+ static int is_anchor (xpparam_t const * xpp , const char * line )
80+ {
81+ int i ;
82+ for (i = 0 ; i < xpp -> anchors_nr ; i ++ ) {
83+ if (!strncmp (line , xpp -> anchors [i ], strlen (xpp -> anchors [i ])))
84+ return 1 ;
85+ }
86+ return 0 ;
87+ }
88+
7389/* The argument "pass" is 1 for the first file, 2 for the second. */
74- static void insert_record (int line , struct hashmap * map , int pass )
90+ static void insert_record (xpparam_t const * xpp , int line , struct hashmap * map ,
91+ int pass )
7592{
7693 xrecord_t * * records = pass == 1 ?
7794 map -> env -> xdf1 .recs : map -> env -> xdf2 .recs ;
@@ -110,6 +127,7 @@ static void insert_record(int line, struct hashmap *map, int pass)
110127 return ;
111128 map -> entries [index ].line1 = line ;
112129 map -> entries [index ].hash = record -> ha ;
130+ map -> entries [index ].anchor = is_anchor (xpp , map -> env -> xdf1 .recs [line - 1 ]-> ptr );
113131 if (!map -> first )
114132 map -> first = map -> entries + index ;
115133 if (map -> last ) {
@@ -147,11 +165,11 @@ static int fill_hashmap(mmfile_t *file1, mmfile_t *file2,
147165
148166 /* First, fill with entries from the first file */
149167 while (count1 -- )
150- insert_record (line1 ++ , result , 1 );
168+ insert_record (xpp , line1 ++ , result , 1 );
151169
152170 /* Then search for matches in the second file */
153171 while (count2 -- )
154- insert_record (line2 ++ , result , 2 );
172+ insert_record (xpp , line2 ++ , result , 2 );
155173
156174 return 0 ;
157175}
@@ -192,14 +210,28 @@ static struct entry *find_longest_common_sequence(struct hashmap *map)
192210 int longest = 0 , i ;
193211 struct entry * entry ;
194212
213+ /*
214+ * If not -1, this entry in sequence must never be overridden.
215+ * Therefore, overriding entries before this has no effect, so
216+ * do not do that either.
217+ */
218+ int anchor_i = -1 ;
219+
195220 for (entry = map -> first ; entry ; entry = entry -> next ) {
196221 if (!entry -> line2 || entry -> line2 == NON_UNIQUE )
197222 continue ;
198223 i = binary_search (sequence , longest , entry );
199224 entry -> previous = i < 0 ? NULL : sequence [i ];
200- sequence [++ i ] = entry ;
201- if (i == longest )
225+ ++ i ;
226+ if (i <= anchor_i )
227+ continue ;
228+ sequence [i ] = entry ;
229+ if (entry -> anchor ) {
230+ anchor_i = i ;
231+ longest = anchor_i + 1 ;
232+ } else if (i == longest ) {
202233 longest ++ ;
234+ }
203235 }
204236
205237 /* No common unique lines were found */
0 commit comments