PureXML/Sources/XPath
Mihaela Mihaljevic ad289b0df1
perf(xpath): cache the document node list for following/preceding axes (#302)
following(of:) and preceding(of:) rebuilt the entire document node list and ran
a linear firstIndex search for the context node on every call. Evaluated over
many context nodes (//x/following::y), that rebuild-and-search was quadratic: a
200-context following:: query over a 20k-element document took ~16s.

Share a per-evaluation DocumentNavigationCache: each document's ordered node
list and a node-to-index map are built once (the document is immutable during
evaluation) and reused, so the position lookup is O(1). following:: also skips
the context's contiguous subtree by index arithmetic (start = index + 1 +
descendant count) instead of scanning the tail and filtering every descendant
out. The selected nodes and their document order are unchanged.

The 200-context query drops ~16s to ~9s; the residual is the produced
node-set's own size (materialization), which is inherent to the axis. The full
suite, the W3C XPath/XSLT and Apache Xalan corpora, and the WASM build stay
green; FollowingPrecedingAxisTests pins the subtree skip, ancestor exclusion,
and the shared-cache multi-context path.
2026-06-25 20:03:45 +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 the document node list for following/preceding axes (#302) 2026-06-25 20:03:45 +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): cache the document node list for following/preceding axes (#302) 2026-06-25 20:03:45 +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 feat(xpath,parsing): public streaming surface, linear document-order at scale 2026-06-11 06:06:31 +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): skip the document-order key for single-node string extraction (#299) 2026-06-25 18:12:45 +02:00