@@ -565,25 +565,57 @@ private Sequence selectByPosition(final Sequence outerSequence,
565
565
Type .NODE ) && (mode == Constants .ANCESTOR_AXIS ||
566
566
mode == Constants .ANCESTOR_SELF_AXIS || mode == Constants .PARENT_AXIS ||
567
567
mode == Constants .PRECEDING_AXIS || mode == Constants .PRECEDING_SIBLING_AXIS );
568
- final Set <NumericValue > set = new TreeSet <>();
569
- final ValueSequence result = new ValueSequence ();
570
- for (final SequenceIterator i = innerSeq .iterate (); i .hasNext (); ) {
571
- final NumericValue v = (NumericValue ) i .nextItem ();
568
+
569
+ Sequence result = Sequence .EMPTY_SEQUENCE ;
570
+ if (innerSeq .hasOne ()) {
571
+ // optimise for single position lookup
572
+ final NumericValue v = (NumericValue ) innerSeq .itemAt (0 );
572
573
// Non integers return... nothing, not even an error !
573
- if (!v .hasFractionalPart () && !v .isZero ()) {
574
- final int pos = (reverseAxis ? contextSequence .getItemCount ()
575
- - v .getInt () : v .getInt () - 1 );
574
+ if (isNonZeroInteger (v )) {
575
+ final int pos = calculatePos (reverseAxis , contextSequence , v );
576
576
// Other positions are ignored
577
- if (pos >= 0 && pos < contextSequence .getItemCount () && !set .contains (v )) {
578
- result .add (contextSequence .itemAt (pos ));
579
- set .add (v );
577
+ if (withinBounds (contextSequence , pos )) {
578
+ result = (Sequence ) contextSequence .itemAt (pos );
579
+ }
580
+ }
581
+ } else {
582
+ // multi-position lookup
583
+ Set <NumericValue > set = null ;
584
+ for (final SequenceIterator i = innerSeq .iterate (); i .hasNext (); ) {
585
+ final NumericValue v = (NumericValue ) i .nextItem ();
586
+ // Non integers return... nothing, not even an error !
587
+ if (isNonZeroInteger (v )) {
588
+ final int pos = calculatePos (reverseAxis , contextSequence , v );
589
+ // Other positions are ignored
590
+ if (withinBounds (contextSequence , pos ) && (set == null || !set .contains (v ))) {
591
+ if (result == Sequence .EMPTY_SEQUENCE ) {
592
+ result = new ValueSequence ();
593
+ }
594
+ result .add (contextSequence .itemAt (pos ));
595
+ if (set == null ) {
596
+ set = new TreeSet <>();
597
+ }
598
+ set .add (v );
599
+ }
580
600
}
581
601
}
582
602
}
583
603
return result ;
584
604
}
585
605
}
586
606
607
+ private static boolean isNonZeroInteger (final NumericValue v ) {
608
+ return !v .hasFractionalPart () && !v .isZero ();
609
+ }
610
+
611
+ private static int calculatePos (final boolean reverseAxis , final Sequence contextSequence , final NumericValue v ) throws XPathException {
612
+ return (reverseAxis ? contextSequence .getItemCount () - v .getInt () : v .getInt () - 1 );
613
+ }
614
+
615
+ private static boolean withinBounds (final Sequence contextSequence , final int pos ) {
616
+ return pos >= 0 && pos < contextSequence .getItemCount ();
617
+ }
618
+
587
619
@ Override
588
620
public void setContextDocSet (final DocumentSet contextSet ) {
589
621
super .setContextDocSet (contextSet );
0 commit comments