Skip to content

Commit 747cebe

Browse files
committed
HV-2127 Use an array for a path iterator and "cache" it
Signed-off-by: marko-bekhta <[email protected]>
1 parent 7e4ca80 commit 747cebe

File tree

1 file changed

+35
-11
lines changed
  • engine/src/main/java/org/hibernate/validator/internal/engine/path

1 file changed

+35
-11
lines changed

engine/src/main/java/org/hibernate/validator/internal/engine/path/NodeImpl.java

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
import java.lang.invoke.MethodHandles;
99
import java.util.Arrays;
1010
import java.util.Iterator;
11-
import java.util.LinkedList;
1211
import java.util.List;
1312
import java.util.Map;
13+
import java.util.NoSuchElementException;
1414

1515
import jakarta.validation.ElementKind;
1616
import jakarta.validation.Path;
@@ -44,9 +44,11 @@ public class NodeImpl
4444
private static final Log LOG = LoggerFactory.make( MethodHandles.lookup() );
4545

4646
static final NodeImpl ROOT_NODE;
47+
4748
static {
4849
ROOT_NODE = NodeImpl.createBeanNode( null );
4950
ROOT_NODE.valueSet = true;
51+
ROOT_NODE.nodes = new NodeImpl[] { ROOT_NODE };
5052
ROOT_NODE.hashCode();
5153
}
5254

@@ -81,6 +83,7 @@ public class NodeImpl
8183

8284
private int hashCode = -1;
8385
private String asString;
86+
private NodeImpl[] nodes;
8487

8588
private NodeImpl(
8689
String name, NodeImpl parent, boolean isIterable, Integer index, Object key, ElementKind kind, Class<?>[] parameterTypes,
@@ -568,17 +571,16 @@ boolean isRootPath() {
568571

569572
@Override
570573
public Iterator<Path.Node> iterator() {
571-
// TODO: keep the initialized list so next iterator calls can reuse it?
572-
if ( parent == null ) {
573-
return List.of( (Path.Node) this ).iterator();
574-
}
575-
List<Path.Node> result = new LinkedList<>();
576-
NodeImpl curr = this;
577-
while ( !curr.isRootPath() ) {
578-
result.add( 0, curr );
579-
curr = curr.parent;
574+
if ( nodes == null ) {
575+
nodes = new NodeImpl[size - 1];
576+
NodeImpl curr = this;
577+
while ( curr.parent != null ) {
578+
nodes[curr.size - 2] = curr;
579+
curr = curr.parent;
580+
}
580581
}
581-
return result.iterator();
582+
583+
return new NodeIterator( nodes );
582584
}
583585

584586
boolean isSubPathOf(NodeImpl other) {
@@ -649,4 +651,26 @@ boolean samePath(NodeImpl other) {
649651

650652
return curr == null && otherCurr == null;
651653
}
654+
655+
private static class NodeIterator implements Iterator<Path.Node> {
656+
private final NodeImpl[] array;
657+
private int index;
658+
659+
public NodeIterator(NodeImpl[] array) {
660+
this.array = array;
661+
}
662+
663+
@Override
664+
public boolean hasNext() {
665+
return index < array.length;
666+
}
667+
668+
@Override
669+
public Path.Node next() {
670+
if ( index < array.length ) {
671+
return array[index++];
672+
}
673+
throw new NoSuchElementException();
674+
}
675+
}
652676
}

0 commit comments

Comments
 (0)