diff options
| author | Paul Eggert | 2025-11-20 08:46:44 -0800 |
|---|---|---|
| committer | Paul Eggert | 2025-11-20 09:11:59 -0800 |
| commit | 2cc6c812788281c05ca9687afd7bedf597b1e942 (patch) | |
| tree | 2d998ed896f38fe92ba260240075d1860709aba4 /lib/diffseq.h | |
| parent | cada1c3192902136214e60b82fd7f9116bc88792 (diff) | |
| download | emacs-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.h | 238 |
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 |