Repository navigation
Commit 2bac59f
fix(query): a node waiting on the query walk's stack holds its folder's path as the walk joins paths onto it - pieces never read - not the folder's node, whose own path a path: or in: term had read whole, so a deep chain whose every folder holds a file beside its subfolder costs memory in proportion to its depth, not its square (CI4 review F1.2)
The fix before this one let a node drop its folder once its own path was
built, which covered a bare chain only. The walk pushes a folder's
children in order and takes the last first, so a file listed before its
subfolder waits on the stack while everything under the folder is
walked. It held the folder's node, to build its own path from the
folder's, and with it the folder's own path - which a path: or in: term
had read, and reading a path copies it whole. Down a chain where every
folder holds such a file that is a whole copy of every folder's path:
185.6 MB at 8,000 deep (23 KB a folder, for path:leaf and for
in:/deep/d0 name:leaf alike), and Node 20 under a 2 GB heap aborted at
30,000 deep ("Ineffective mark-compacts near heap limit"). The Highlight
box asks on every pause in typing, and in: is a common term.
A node now holds a FolderPath: its folder's path as the walk joins its
nodes' paths onto it, made once per folder as its children are pushed.
While the walk runs it is handed only to childPath, which reads none of
it, so a chain of them stays the pieces they were joined from. A folder's
own path, the one terms and sort ties read, is a second string while the
walk runs; once the walk is over nothing waits, and a folder's path is
the one its children join onto, so each folder's path is still built once
for the page (G07's counted tests hold: a size query builds no more than
the 319 paths its hits need; with the two kept apart after the walk too,
it builds 468).
Measured (Node 20.20.2, 2 GB heap, the heap after a full collection when
the deep path is built), 8,000 deep: a file beside every folder, path:leaf
236 bytes a folder, in: 241, name:leaf 2; a bare chain, path:leaf 61. At
30,000 deep with a file beside every folder, path:leaf and in: finish
(134 and 143 MB resident). A deep chain's path is built from pieces, so
reading the deepest one walks every piece: slower than copying a flat
one, and only on depths no real tree has.
Tests (tests/queryWalkWork.test.ts):
- "a file waiting beside every folder ...": path:leaf,
in:/deep/d0 name:leaf and name:leaf, one subtest each, down that
8,000-deep chain - the one file found, its path exact and built once,
under 2 KiB a folder held. RED before the fix: 185.6 / 185.5 MB.
- "a sort tie that reads a kept folder's path while its file still
waits": folders sized by hand two at a time, type:dir, one kept, largest
first - each odd folder ties with the even one kept above it, so the
kept folder's path is read after its children were pushed. RED before
the fix (185.5 MB); proves the "once the walk is over" gate.
- The heap is now also read as the deepest folder's path is joined (the
last step of a chain joined in one go), so the existing CI4 test still
fails if the store's childPath reads the parent path again (name:leaf
184.0 MB).
Mutants, each RED for the right reason, restored and checked by SHA-256:
a folder's children join onto the path its readers read (path:leaf
184.2 MB); its path shared while the walk runs (tie: 93.6 MB, every
second folder); never shared, or the walk never marked over (paths built:
468 for 319 needed); a node's own path not kept (built twice, not once);
folders joined in the wrong order (the path is wrong); the store reading
the parent path (name:leaf 184.0 MB); size ties not broken by path (the
tie's path never built); the scanned folder not counted (total). Fixture
checks: the file listed after its folder; folders not paired by size.
Not changed: a kept hit, and a candidate of a query that looks facts up,
hold their own paths - bounded by how many are kept (the page, or the
20,000-candidate cap), not by what waits on the stack.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>1 parent 44dfcb7 commit 2bac59f
2 files changed
Lines changed: 211 additions & 59 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
413 | 413 | | |
414 | 414 | | |
415 | 415 | | |
| 416 | + | |
| 417 | + | |
416 | 418 | | |
417 | 419 | | |
418 | 420 | | |
419 | 421 | | |
420 | 422 | | |
421 | | - | |
422 | | - | |
423 | | - | |
424 | | - | |
425 | | - | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
426 | 430 | | |
427 | | - | |
| 431 | + | |
428 | 432 | | |
429 | 433 | | |
| 434 | + | |
430 | 435 | | |
431 | 436 | | |
432 | 437 | | |
| |||
439 | 444 | | |
440 | 445 | | |
441 | 446 | | |
442 | | - | |
443 | | - | |
444 | | - | |
445 | | - | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
446 | 460 | | |
447 | 461 | | |
448 | 462 | | |
449 | | - | |
450 | | - | |
451 | | - | |
452 | | - | |
453 | | - | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
454 | 506 | | |
455 | | - | |
456 | | - | |
457 | | - | |
458 | | - | |
459 | | - | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
460 | 512 | | |
461 | 513 | | |
462 | 514 | | |
| |||
490 | 542 | | |
491 | 543 | | |
492 | 544 | | |
| 545 | + | |
493 | 546 | | |
494 | 547 | | |
495 | 548 | | |
496 | | - | |
| 549 | + | |
497 | 550 | | |
498 | 551 | | |
499 | 552 | | |
500 | | - | |
| 553 | + | |
501 | 554 | | |
502 | 555 | | |
503 | 556 | | |
| |||
522 | 575 | | |
523 | 576 | | |
524 | 577 | | |
525 | | - | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
526 | 581 | | |
527 | 582 | | |
528 | 583 | | |
529 | 584 | | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
530 | 590 | | |
531 | 591 | | |
532 | 592 | | |
| |||
613 | 673 | | |
614 | 674 | | |
615 | 675 | | |
| 676 | + | |
616 | 677 | | |
617 | 678 | | |
618 | 679 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
269 | 269 | | |
270 | 270 | | |
271 | 271 | | |
272 | | - | |
273 | | - | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
274 | 278 | | |
275 | 279 | | |
276 | | - | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
277 | 284 | | |
278 | 285 | | |
279 | 286 | | |
| |||
283 | 290 | | |
284 | 291 | | |
285 | 292 | | |
286 | | - | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
287 | 297 | | |
288 | 298 | | |
289 | 299 | | |
| |||
305 | 315 | | |
306 | 316 | | |
307 | 317 | | |
308 | | - | |
309 | | - | |
310 | | - | |
311 | | - | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
312 | 322 | | |
313 | 323 | | |
314 | 324 | | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
315 | 377 | | |
316 | 378 | | |
317 | 379 | | |
| |||
320 | 382 | | |
321 | 383 | | |
322 | 384 | | |
323 | | - | |
324 | | - | |
325 | 385 | | |
326 | | - | |
327 | | - | |
328 | | - | |
329 | | - | |
330 | | - | |
331 | | - | |
332 | | - | |
333 | | - | |
334 | | - | |
335 | | - | |
336 | | - | |
337 | | - | |
338 | | - | |
339 | | - | |
340 | | - | |
341 | | - | |
342 | | - | |
343 | | - | |
344 | | - | |
345 | | - | |
346 | | - | |
347 | | - | |
348 | | - | |
349 | | - | |
350 | | - | |
351 | | - | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
352 | 413 | | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
353 | 444 | | |
0 commit comments