PureXML/Sources/XPath
Mihaela Mihaljevic d86e4effbe
fix(xpath): cache the attribute index for document-order keys (#305)
An attribute node's document-order key bands by the attribute's index among its
owner's attributes, found with owner.attributes.firstIndex { $0.name == name }.
That linear scan ran for every attribute node, so sorting an element's K
attributes into document order was O(K^2): an 8000-attribute element took ~0.18s
and grew quadratically.

Cache a per-owner attribute-name-to-index map in SiblingIndexCache, built once
on the second lookup (a single lookup still scans), exactly as the sibling-index
cache already does for child positions. The index is the same first-occurrence
position; only its cost changes.

The 8000-attribute sort drops to ~0.01s (~16x) and is now linear. The full
suite, the W3C XPath and Apache Xalan corpora, the C14N suite (which orders
attributes byte-exactly), and the WASM build stay green; AttributeDocumentOrderTests
pins declaration order through the cached sort.
2026-06-25 22:01:13 +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): fuse the node test into the following/preceding walk (#303) 2026-06-25 20:56:14 +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
EvaluationContext.swift perf(xpath): cache the document node list for following/preceding axes (#302) 2026-06-25 20:03:45 +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 perf(xpath): fuse the node test into the following/preceding walk (#303) 2026-06-25 20:56:14 +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 XSLT/XPath conformance: close 68 Apache Xalan cases (#254) 2026-06-24 00:13:14 +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 fix(xpath): cache the attribute index for document-order keys (#305) 2026-06-25 22:01:13 +02:00