aboutsummaryrefslogtreecommitdiffstats
path: root/lib/diffseq.h
diff options
context:
space:
mode:
authorPaul Eggert2025-11-20 08:46:44 -0800
committerPaul Eggert2025-11-20 09:11:59 -0800
commit2cc6c812788281c05ca9687afd7bedf597b1e942 (patch)
tree2d998ed896f38fe92ba260240075d1860709aba4 /lib/diffseq.h
parentcada1c3192902136214e60b82fd7f9116bc88792 (diff)
downloademacs-2cc6c812788281c05ca9687afd7bedf597b1e942.tar.gz
emacs-2cc6c812788281c05ca9687afd7bedf597b1e942.zip
Update from Gnulib by running admin/merge-gnulib
Diffstat (limited to 'lib/diffseq.h')
-rw-r--r--lib/diffseq.h238
1 files changed, 117 insertions, 121 deletions
diff --git a/lib/diffseq.h b/lib/diffseq.h
index 914bc643bb4..b4959813d7f 100644
--- a/lib/diffseq.h
+++ b/lib/diffseq.h
@@ -286,160 +286,156 @@ diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal,
286 } 286 }
287 } 287 }
288 288
289 if (find_minimal) 289 if (!find_minimal)
290 continue; 290 {
291
292#ifdef USE_HEURISTIC 291#ifdef USE_HEURISTIC
293 bool heuristic = ctxt->heuristic; 292 bool heuristic = ctxt->heuristic;
294#else 293#else
295 bool heuristic = false; 294 bool heuristic = false;
296#endif 295#endif
297 296
298 /* Heuristic: check occasionally for a diagonal that has made lots 297 /* Heuristic: check occasionally for a diagonal that has made lots
299 of progress compared with the edit distance. If we have any 298 of progress compared with the edit distance. If we have any
300 such, find the one that has made the most progress and return it 299 such, find the one that has made the most progress and return it
301 as if it had succeeded. 300 as if it had succeeded.
302 301
303 With this heuristic, for vectors with a constant small density 302 With this heuristic, for vectors with a constant small density
304 of changes, the algorithm is linear in the vector size. */ 303 of changes, the algorithm is linear in the vector size. */
305
306 if (200 < c && big_snake && heuristic)
307 {
308 {
309 OFFSET best = 0;
310 304
311 for (d = fmax; d >= fmin; d -= 2) 305 if (200 < c && big_snake && heuristic)
306 {
312 { 307 {
313 OFFSET dd = d - fmid; 308 OFFSET best = 0;
314 OFFSET x = fd[d];
315 OFFSET y = x - d;
316 OFFSET v = (x - xoff) * 2 - dd;
317 309
318 if (v > 12 * (c + (dd < 0 ? -dd : dd))) 310 for (d = fmax; d >= fmin; d -= 2)
319 { 311 {
320 if (v > best 312 OFFSET dd = d - fmid;
321 && xoff + SNAKE_LIMIT <= x && x < xlim 313 OFFSET x = fd[d];
322 && yoff + SNAKE_LIMIT <= y && y < ylim) 314 OFFSET y = x - d;
315 OFFSET v = (x - xoff) * 2 - dd;
316
317 if (v > 12 * (c + (dd < 0 ? -dd : dd)))
323 { 318 {
324 /* We have a good enough best diagonal; now insist 319 if (v > best
325 that it end with a significant snake. */ 320 && xoff + SNAKE_LIMIT <= x && x < xlim
326 int k; 321 && yoff + SNAKE_LIMIT <= y && y < ylim)
327 322 {
328 for (k = 1; XREF_YREF_EQUAL (x - k, y - k); k++) 323 /* We have a good enough best diagonal; now insist
329 if (k == SNAKE_LIMIT) 324 that it end with a significant snake. */
330 { 325 for (int k = 1; XREF_YREF_EQUAL (x - k, y - k); k++)
331 best = v; 326 if (k == SNAKE_LIMIT)
332 part->xmid = x; 327 {
333 part->ymid = y; 328 best = v;
334 break; 329 part->xmid = x;
335 } 330 part->ymid = y;
331 break;
332 }
333 }
336 } 334 }
337 } 335 }
336 if (best > 0)
337 {
338 part->lo_minimal = true;
339 part->hi_minimal = false;
340 return;
341 }
338 } 342 }
339 if (best > 0)
340 {
341 part->lo_minimal = true;
342 part->hi_minimal = false;
343 return;
344 }
345 }
346
347 {
348 OFFSET best = 0;
349 343
350 for (d = bmax; d >= bmin; d -= 2)
351 { 344 {
352 OFFSET dd = d - bmid; 345 OFFSET best = 0;
353 OFFSET x = bd[d];
354 OFFSET y = x - d;
355 OFFSET v = (xlim - x) * 2 + dd;
356 346
357 if (v > 12 * (c + (dd < 0 ? -dd : dd))) 347 for (d = bmax; d >= bmin; d -= 2)
358 { 348 {
359 if (v > best 349 OFFSET dd = d - bmid;
360 && xoff < x && x <= xlim - SNAKE_LIMIT 350 OFFSET x = bd[d];
361 && yoff < y && y <= ylim - SNAKE_LIMIT) 351 OFFSET y = x - d;
352 OFFSET v = (xlim - x) * 2 + dd;
353
354 if (v > 12 * (c + (dd < 0 ? -dd : dd)))
362 { 355 {
363 /* We have a good enough best diagonal; now insist 356 if (v > best
364 that it end with a significant snake. */ 357 && xoff < x && x <= xlim - SNAKE_LIMIT
365 int k; 358 && yoff < y && y <= ylim - SNAKE_LIMIT)
366 359 {
367 for (k = 0; XREF_YREF_EQUAL (x + k, y + k); k++) 360 /* We have a good enough best diagonal; now insist
368 if (k == SNAKE_LIMIT - 1) 361 that it end with a significant snake. */
369 { 362 for (int k = 0; XREF_YREF_EQUAL (x + k, y + k); k++)
370 best = v; 363 if (k == SNAKE_LIMIT - 1)
371 part->xmid = x; 364 {
372 part->ymid = y; 365 best = v;
373 break; 366 part->xmid = x;
374 } 367 part->ymid = y;
368 break;
369 }
370 }
375 } 371 }
376 } 372 }
373 if (best > 0)
374 {
375 part->lo_minimal = false;
376 part->hi_minimal = true;
377 return;
378 }
377 } 379 }
378 if (best > 0) 380 }
379 {
380 part->lo_minimal = false;
381 part->hi_minimal = true;
382 return;
383 }
384 }
385 }
386 381
387 /* Heuristic: if we've gone well beyond the call of duty, give up 382 /* Heuristic: if we've gone well beyond the call of duty, give up
388 and report halfway between our best results so far. */ 383 and report halfway between our best results so far. */
389 if (c >= ctxt->too_expensive) 384 if (c >= ctxt->too_expensive)
390 {
391 /* Find forward diagonal that maximizes X + Y. */
392 OFFSET fxybest = -1, fxbest;
393 for (d = fmax; d >= fmin; d -= 2)
394 { 385 {
395 OFFSET x = MIN (fd[d], xlim); 386 /* Find forward diagonal that maximizes X + Y. */
396 OFFSET y = x - d; 387 OFFSET fxybest = -1, fxbest;
397 if (ylim < y) 388 for (d = fmax; d >= fmin; d -= 2)
398 { 389 {
399 x = ylim + d; 390 OFFSET x = MIN (fd[d], xlim);
400 y = ylim; 391 OFFSET y = x - d;
392 if (ylim < y)
393 {
394 x = ylim + d;
395 y = ylim;
396 }
397 if (fxybest < x + y)
398 {
399 fxybest = x + y;
400 fxbest = x;
401 }
401 } 402 }
402 if (fxybest < x + y) 403
404 /* Find backward diagonal that minimizes X + Y. */
405 OFFSET bxybest = OFFSET_MAX, bxbest;
406 for (d = bmax; d >= bmin; d -= 2)
403 { 407 {
404 fxybest = x + y; 408 OFFSET x = MAX (xoff, bd[d]);
405 fxbest = x; 409 OFFSET y = x - d;
410 if (y < yoff)
411 {
412 x = yoff + d;
413 y = yoff;
414 }
415 if (x + y < bxybest)
416 {
417 bxybest = x + y;
418 bxbest = x;
419 }
406 } 420 }
407 }
408 421
409 /* Find backward diagonal that minimizes X + Y. */ 422 /* Use the better of the two diagonals. */
410 OFFSET bxybest = OFFSET_MAX, bxbest; 423 if ((xlim + ylim) - bxybest < fxybest - (xoff + yoff))
411 for (d = bmax; d >= bmin; d -= 2)
412 {
413 OFFSET x = MAX (xoff, bd[d]);
414 OFFSET y = x - d;
415 if (y < yoff)
416 { 424 {
417 x = yoff + d; 425 part->xmid = fxbest;
418 y = yoff; 426 part->ymid = fxybest - fxbest;
427 part->lo_minimal = true;
428 part->hi_minimal = false;
419 } 429 }
420 if (x + y < bxybest) 430 else
421 { 431 {
422 bxybest = x + y; 432 part->xmid = bxbest;
423 bxbest = x; 433 part->ymid = bxybest - bxbest;
434 part->lo_minimal = false;
435 part->hi_minimal = true;
424 } 436 }
437 return;
425 } 438 }
426
427 /* Use the better of the two diagonals. */
428 if ((xlim + ylim) - bxybest < fxybest - (xoff + yoff))
429 {
430 part->xmid = fxbest;
431 part->ymid = fxybest - fxbest;
432 part->lo_minimal = true;
433 part->hi_minimal = false;
434 }
435 else
436 {
437 part->xmid = bxbest;
438 part->ymid = bxybest - bxbest;
439 part->lo_minimal = false;
440 part->hi_minimal = true;
441 }
442 return;
443 } 439 }
444 } 440 }
445 #undef XREF_YREF_EQUAL 441 #undef XREF_YREF_EQUAL