PureXML/Sources/XPath
Mihaela Mihaljevic 3e4f596b7c
perf(xpath): order results by a per-root index, linear not quadratic in depth (#347)
Sorting a node-set into document order keyed each node by its root path, an
array as long as the node's depth, computed with a per-node ancestor walk.
Ordering the descendants of a deeply-nested document was therefore
O(n log n x depth): `//a` over an 8000-deep document took ~19s through the
reference query path.

The key is now a single O(1) pre-order index from a per-root numbering,
built once per document and shared through the evaluation's navigation
cache, with a band ordering an element before its namespace nodes, its
attribute nodes, and its children. A node-set spanning several documents
(an XSLT document() result) is grouped by root, ranked by first appearance,
so only a foreign node walks its ancestors. `appendSubtree` (the numbering
walk) is now iterative, so it no longer recurses on depth either.

Document order is unchanged: 1786 tests pass, including the XPath, XSLT,
XPointer, and Schematron conformance corpora. `Query.nodes` over a
50000-deep document now orders in a fraction of a second.
2026-06-26 18:22:20 +02:00
..
Axis.swift perf(xpath): skip the document-order sort for an already-ordered single step (#283) 2026-06-25 05:04:00 +02:00
AxisNavigation.swift perf(xpath): order results by a per-root index, linear not quadratic in depth (#347) 2026-06-26 18:22:20 +02:00
Budget.swift feat(xpath,xslt,wasm): evaluation budget, tailored collation, WASI runtime proof 2026-06-11 06:26:13 +02:00
Compiler.swift feat(xpath): expression engine and the four-type model 2026-06-08 05:33:13 +02:00
CompilerDescendantFusion.swift perf(xpath): fuse // into a descendant step for non-positional predicates (#281) 2026-06-25 03:21:03 +02:00
CompilerPaths.swift perf(xpath): fuse // into a descendant step for non-positional predicates (#281) 2026-06-25 03:21:03 +02:00
CoreFunctions.swift feat(xslt): add xsl:key/key(), format-number(), xsl:number, and document() 2026-06-08 08:01:17 +02:00
DocumentOrder.swift perf(xpath): order results by a per-root index, linear not quadratic in depth (#347) 2026-06-26 18:22:20 +02:00
EvaluationContext.swift perf(xpath): cache and fuse the following-sibling/preceding-sibling axes (#306) 2026-06-25 22:41:32 +02:00
Evaluator.swift perf(xpath): skip the document-order sort for an already-ordered single step (#283) 2026-06-25 05:04:00 +02:00
EvaluatorOperators.swift feat(xpath): expression engine and the four-type model 2026-06-08 05:33:13 +02:00
EvaluatorSteps.swift refactor: remove three dead file-scoped functions (#330) 2026-06-26 12:04:07 +02:00
Expression.swift feat(xpath): expression engine and the four-type model 2026-06-08 05:33:13 +02:00
EXSLTFunctions.swift fix(xslt): make key(), id(), and EXSLT set functions linear over wide fan-outs (#300) 2026-06-25 18:45:08 +02:00
NodeFunctions.swift perf(xpath): compute document-order keys once per sort 2026-06-10 03:39:19 +02:00
NodeTest.swift feat(xpath): all thirteen axes via parent-aware navigation 2026-06-08 05:15:14 +02:00
Query.swift fix(schema): advance XSTS valid-instances-rejected to 4 (#146) 2026-06-16 22:22:05 +02:00
QueryError.swift feat(xpath,xslt,wasm): evaluation budget, tailored collation, WASI runtime proof 2026-06-11 06:26:13 +02:00
Selection.swift feat(xpath): add an XPath 1.0 location-path subset 2026-06-08 01:32:23 +02:00
SiblingIndexCache.swift fix(xpath): cache the attribute index for document-order keys (#305) 2026-06-25 22:01:13 +02:00
Step.swift feat(xpath): expression engine and the four-type model 2026-06-08 05:33:13 +02:00
StringFunctions.swift perf(xpath): make translate() and the substring search functions linear (#308) 2026-06-26 00:11:49 +02:00
Value.swift fix(xpath): format a large integer-valued number with no decimal point (#268) 2026-06-24 04:31:19 +02:00
XPathNode.swift perf(xpath): order results by a per-root index, linear not quadratic in depth (#347) 2026-06-26 18:22:20 +02:00