Skip to content

Commit b1b14f6

Browse files
committed
[optimize] Reduce opportunities for over eager retrieval of persistent Nodes
1 parent 8b08052 commit b1b14f6

File tree

3 files changed

+39
-21
lines changed

3 files changed

+39
-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: 22 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;
@@ -447,14 +454,7 @@ public DocumentImpl getOwnerDocument() {
447454
* @return a <code>boolean</code> value
448455
*/
449456
public boolean isDocument() {
450-
return nodeType == Node.DOCUMENT_NODE;
451-
}
452-
453-
454-
private @Nullable WeakReference<Node> cachedNode = null;
455-
456-
private void invalidateCachedNode() {
457-
this.cachedNode = null;
457+
return getNodeType() == Node.DOCUMENT_NODE;
458458
}
459459

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

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

@@ -490,6 +491,10 @@ public Node getNode() {
490491

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

@@ -851,12 +856,9 @@ public void toSAX(final DBBroker broker, final ContentHandler handler, final Pro
851856

852857
@Override
853858
public void copyTo(final DBBroker broker, final DocumentBuilderReceiver receiver) throws SAXException {
854-
NodeImpl node = null;
855-
if(nodeType < 0) {
856-
node = (NodeImpl) getNode();
857-
}
858-
if(nodeType == Node.ATTRIBUTE_NODE) {
859-
final AttrImpl attr = (node == null ? (AttrImpl) getNode() : (AttrImpl) node);
859+
final Node node = getNode();
860+
if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
861+
final AttrImpl attr = (AttrImpl) node;
860862
receiver.attribute(attr.getQName(), attr.getValue());
861863
} else {
862864
receiver.addReferenceNode(this);
@@ -1344,6 +1346,7 @@ public NodeSet selectFollowing(final NodeSet following, final int position, fina
13441346

13451347
@Override
13461348
public NodeSet directSelectAttribute(final DBBroker broker, final NodeTest test, final int contextId) {
1349+
final short nodeType = getNodeType();
13471350
if(nodeType != UNKNOWN_NODE_TYPE && nodeType != Node.ELEMENT_NODE) {
13481351
return NodeSet.EMPTY_SET;
13491352
}
@@ -1387,6 +1390,7 @@ public NodeSet directSelectAttribute(final DBBroker broker, final NodeTest test,
13871390
}
13881391

13891392
public NodeSet directSelectChild(final QName qname, final int contextId) {
1393+
final short nodeType = getNodeType();
13901394
if(nodeType != UNKNOWN_NODE_TYPE && nodeType != Node.ELEMENT_NODE) {
13911395
return NodeSet.EMPTY_SET;
13921396
}
@@ -1609,6 +1613,7 @@ public boolean equalDocs(final DocumentSet other) {
16091613

16101614
@Override
16111615
public boolean directMatchAttribute(final DBBroker broker, final NodeTest test, final int contextId) {
1616+
final short nodeType = getNodeType();
16121617
if(nodeType != UNKNOWN_NODE_TYPE && nodeType != Node.ELEMENT_NODE) {
16131618
return false;
16141619
}
@@ -1638,6 +1643,7 @@ public boolean directMatchAttribute(final DBBroker broker, final NodeTest test,
16381643
}
16391644

16401645
public boolean directMatchChild(final QName qname, final int contextId) {
1646+
final short nodeType = getNodeType();
16411647
if(nodeType != UNKNOWN_NODE_TYPE && nodeType != Node.ELEMENT_NODE) {
16421648
return false;
16431649
}

0 commit comments

Comments
 (0)