PureXML/Sources/XPath
Mihaela Mihaljevic b104723fed
perf(xpath): cache and fuse the following-sibling/preceding-sibling axes (#306)
siblingPosition(of:) located the context node with
parent.children.firstIndex { $0 === tree } on every call: a linear scan of the
parent's child list, independent of the result. Over a wide parent evaluated
from many context siblings (//x/following-sibling::y) that scan was quadratic,
and the axes then materialized every sibling before the node test filtered it.

Look the index up through the shared per-evaluation SiblingIndexCache (O(1)
after the per-parent table is built), and fuse the step's node test into the
walk so a rejected sibling is never wrapped (the same fusion the descendant and
following/preceding axes use). The selected siblings and their order are
unchanged.

The gratuitous per-context scan and the non-match wrapping are gone (the
remaining per-context iteration over the siblings is inherent to the axis); a
wide-parent following-sibling query is ~1.2-1.6x faster. The full suite, the
W3C XPath/XSLT and Apache Xalan corpora, and the WASM build stay green;
SiblingAxisTests pins the fused node test and document order.
2026-06-25 22:41:32 +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): cache and fuse the following-sibling/preceding-sibling axes (#306) 2026-06-25 22:41:32 +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 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 perf(xpath): cache and fuse the following-sibling/preceding-sibling axes (#306) 2026-06-25 22:41:32 +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