Skip to content

Commit 696112c

Browse files
committed
[optimize] Reduce opportunities for over eager retrieval of persistent Nodes
1 parent bf262bd commit 696112c

File tree

3 files changed

+40
-21
lines changed

3 files changed

+40
-21
lines changed

exist-core/src/main/java/org/exist/dom/memtree/reference/AbstractReferenceNodeImpl.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,20 @@ public String toString() {
7171

7272
@Override
7373
public String getNamespaceURI() {
74-
return getProxiedNode().getNamespaceURI();
74+
final QName qname = getNodeProxy().getQName();
75+
if (qname == null) {
76+
return null;
77+
}
78+
return qname.getNamespaceURI();
7579
}
7680

7781
@Override
7882
public String getLocalName() {
79-
return getProxiedNode().getLocalName();
83+
final QName qname = getNodeProxy().getQName();
84+
if (qname == null) {
85+
return null;
86+
}
87+
return qname.getLocalPart();
8088
}
8189

8290
@Override
@@ -158,11 +166,11 @@ public String getNodeValue() throws DOMException {
158166

159167
@Override
160168
public short getNodeType() {
161-
return getProxiedNode().getNodeType();
169+
return getNodeProxy().getNodeType();
162170
}
163171

164172
@Override
165173
public QName getQName() {
166-
return getProxiedNode().getQName();
174+
return getNodeProxy().getQName();
167175
}
168176
}

exist-core/src/main/java/org/exist/dom/memtree/reference/ElementReferenceImpl.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@ public int compareTo(final ElementReferenceImpl other) {
5151

5252
@Override
5353
public String getTagName() {
54-
return getProxiedNode().getTagName();
54+
final QName qname = getNodeProxy().getQName();
55+
if (qname == null) {
56+
return null;
57+
}
58+
return qname.getStringValue();
5559
}
5660

5761
@Override

exist-core/src/main/java/org/exist/dom/persistent/NodeProxy.java

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ public class NodeProxy implements NodeSet, NodeValue, NodeHandle, DocumentSet, C
137137

138138
private final Expression expression;
139139

140+
private @Nullable WeakReference<Node> cachedNode = null;
141+
140142
/**
141143
* Creates a new <code>NodeProxy</code> instance.
142144
*
@@ -233,6 +235,10 @@ public NodeProxy(final Expression expression, final DocumentImpl doc, final Node
233235
this.nodeId = nodeId;
234236
}
235237

238+
private void invalidateCachedNode() {
239+
this.cachedNode = null;
240+
}
241+
236242
public void update(final ElementImpl element) {
237243
invalidateCachedNode();
238244
this.doc = element.getOwnerDocument();
@@ -322,6 +328,7 @@ public NodeId getNodeId() {
322328
@Override
323329
public QName getQName() {
324330
if (qname == null) {
331+
// NOTE(AR) get the node from the database, which will also update the `qname`
325332
getNode();
326333
}
327334
return qname;
@@ -446,14 +453,7 @@ public DocumentImpl getOwnerDocument() {
446453
* @return a <code>boolean</code> value
447454
*/
448455
public boolean isDocument() {
449-
return nodeType == Node.DOCUMENT_NODE;
450-
}
451-
452-
453-
private @Nullable WeakReference<Node> cachedNode = null;
454-
455-
private void invalidateCachedNode() {
456-
this.cachedNode = null;
456+
return getNodeType() == Node.DOCUMENT_NODE;
457457
}
458458

459459
/**
@@ -463,7 +463,8 @@ private void invalidateCachedNode() {
463463
*/
464464
@Override
465465
public Node getNode() {
466-
if (isDocument()) {
466+
// NOTE(AR) we don't call isDocument() or getNodeType() here as it would call back to getNode() and cause a StackOverflowError
467+
if (nodeType == Node.DOCUMENT_NODE) {
467468
return doc;
468469
}
469470

@@ -480,7 +481,7 @@ public Node getNode() {
480481
this.nodeType = realNode.getNodeType();
481482
this.qname = realNode.getQName();
482483
}
483-
cachedNode = new WeakReference<>(realNode);
484+
this.cachedNode = new WeakReference<>(realNode);
484485
node = realNode;
485486
}
486487

@@ -489,6 +490,10 @@ public Node getNode() {
489490

490491
@Override
491492
public short getNodeType() {
493+
if (nodeType == UNKNOWN_NODE_TYPE) {
494+
// NOTE(AR) get the node from the database, which will also update the `nodeType`
495+
getNode();
496+
}
492497
return nodeType;
493498
}
494499

@@ -738,6 +743,7 @@ public String debugContext() {
738743
// methods of interface Item
739744
@Override
740745
public int getType() {
746+
final short nodeType = getNodeType();
741747
if (nodeType == UNKNOWN_NODE_TYPE) {
742748
return Type.NODE;
743749
}
@@ -835,12 +841,9 @@ public void toSAX(final DBBroker broker, final ContentHandler handler, final Pro
835841

836842
@Override
837843
public void copyTo(final DBBroker broker, final DocumentBuilderReceiver receiver) throws SAXException {
838-
NodeImpl node = null;
839-
if(nodeType < 0) {
840-
node = (NodeImpl) getNode();
841-
}
842-
if(nodeType == Node.ATTRIBUTE_NODE) {
843-
final AttrImpl attr = (node == null ? (AttrImpl) getNode() : (AttrImpl) node);
844+
final Node node = getNode();
845+
if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
846+
final AttrImpl attr = (AttrImpl) node;
844847
receiver.attribute(attr.getQName(), attr.getValue());
845848
} else {
846849
receiver.addReferenceNode(this);
@@ -1328,6 +1331,7 @@ public NodeSet selectFollowing(final NodeSet following, final int position, fina
13281331

13291332
@Override
13301333
public NodeSet directSelectAttribute(final DBBroker broker, final NodeTest test, final int contextId) {
1334+
final short nodeType = getNodeType();
13311335
if(nodeType != UNKNOWN_NODE_TYPE && nodeType != Node.ELEMENT_NODE) {
13321336
return NodeSet.EMPTY_SET;
13331337
}
@@ -1371,6 +1375,7 @@ public NodeSet directSelectAttribute(final DBBroker broker, final NodeTest test,
13711375
}
13721376

13731377
public NodeSet directSelectChild(final QName qname, final int contextId) {
1378+
final short nodeType = getNodeType();
13741379
if(nodeType != UNKNOWN_NODE_TYPE && nodeType != Node.ELEMENT_NODE) {
13751380
return NodeSet.EMPTY_SET;
13761381
}
@@ -1593,6 +1598,7 @@ public boolean equalDocs(final DocumentSet other) {
15931598

15941599
@Override
15951600
public boolean directMatchAttribute(final DBBroker broker, final NodeTest test, final int contextId) {
1601+
final short nodeType = getNodeType();
15961602
if(nodeType != UNKNOWN_NODE_TYPE && nodeType != Node.ELEMENT_NODE) {
15971603
return false;
15981604
}
@@ -1622,6 +1628,7 @@ public boolean directMatchAttribute(final DBBroker broker, final NodeTest test,
16221628
}
16231629

16241630
public boolean directMatchChild(final QName qname, final int contextId) {
1631+
final short nodeType = getNodeType();
16251632
if(nodeType != UNKNOWN_NODE_TYPE && nodeType != Node.ELEMENT_NODE) {
16261633
return false;
16271634
}

0 commit comments

Comments
 (0)