Skip to content

Commit 108457c

Browse files
authored
Merge pull request #113 from evolvedbinary/6.x.x/hotfix/array-set-sizing
[6.x.x] Reduce memory use and improve NodeSet sizing
2 parents 416b980 + 3ab1174 commit 108457c

File tree

5 files changed

+85
-17
lines changed

5 files changed

+85
-17
lines changed

exist-core/pom.xml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,7 @@
813813
<include>src/test/java/org/exist/deadlocks/GetReleaseBrokerDeadlocksTest.java</include>
814814
<include>src/main/java/org/exist/dom/NodeListImpl.java</include>
815815
<include>src/main/java/org/exist/dom/QName.java</include>
816-
<exclude>src/main/java/org/exist/dom/memtree/AbstractCharacterData.java</exclude>
816+
<include>src/main/java/org/exist/dom/memtree/AbstractCharacterData.java</include>
817817
<include>src/main/java/org/exist/dom/memtree/AttrImpl.java</include>
818818
<include>src/main/java/org/exist/dom/memtree/DocumentBuilderReceiver.java</include>
819819
<include>src/main/java/org/exist/dom/memtree/DocumentImpl.java</include>
@@ -824,9 +824,10 @@
824824
<include>src/main/java/org/exist/dom/memtree/ElementImpl.java</include>
825825
<include>src/test/java/org/exist/dom/memtree/MemtreeInXQueryTest.java</include>
826826
<include>src/main/java/org/exist/dom/memtree/MemTreeBuilder.java</include>
827-
<exclude>src/main/java/org/exist/dom/memtree/NamespaceNode.java</exclude>
827+
<include>src/main/java/org/exist/dom/memtree/NamespaceNode.java</include>
828828
<include>src/main/java/org/exist/dom/memtree/NodeImpl.java</include>
829-
<exclude>src/main/java/org/exist/dom/memtree/ProcessingInstructionImpl.java</exclude>
829+
<include>src/main/java/org/exist/dom/memtree/ProcessingInstructionImpl.java</include>
830+
<include>src/main/java/org/exist/dom/persistent/AbstractArrayNodeSet.java</include>
830831
<include>src/main/java/org/exist/dom/persistent/AbstractCharacterData.java</include>
831832
<include>src/main/java/org/exist/dom/persistent/AttrImpl.java</include>
832833
<include>src/main/java/org/exist/dom/persistent/BinaryDocument.java</include>
@@ -840,6 +841,7 @@
840841
<include>src/main/java/org/exist/dom/persistent/Match.java</include>
841842
<include>src/main/java/org/exist/dom/persistent/NewArrayNodeSet.java</include>
842843
<include>src/main/java/org/exist/dom/persistent/NodeProxy.java</include>
844+
<include>src/main/java/org/exist/dom/persistent/NodeSet.java</include>
843845
<include>src/test/java/org/exist/dom/persistent/NodeTest.java</include>
844846
<include>src/main/java/org/exist/dom/persistent/LockToken.java</include>
845847
<include>src/test/java/org/exist/dom/persistent/PersistentDomTest.java</include>
@@ -1402,6 +1404,7 @@
14021404
<exclude>src/main/java/org/exist/dom/memtree/reference/ElementReferenceImpl.java</exclude>
14031405
<exclude>src/main/java/org/exist/dom/memtree/reference/ProcessingInstructionReferenceImpl.java</exclude>
14041406
<exclude>src/main/java/org/exist/dom/memtree/reference/TextReferenceImpl.java</exclude>
1407+
<exclude>src/main/java/org/exist/dom/persistent/AbstractArrayNodeSet.java</exclude>
14051408
<exclude>src/main/java/org/exist/dom/persistent/AbstractCharacterData.java</exclude>
14061409
<exclude>src/main/java/org/exist/dom/persistent/AttrImpl.java</exclude>
14071410
<exclude>src/main/java/org/exist/dom/persistent/BinaryDocument.java</exclude>
@@ -1415,6 +1418,7 @@
14151418
<exclude>src/main/java/org/exist/dom/persistent/Match.java</exclude>
14161419
<exclude>src/main/java/org/exist/dom/persistent/NewArrayNodeSet.java</exclude>
14171420
<exclude>src/main/java/org/exist/dom/persistent/NodeProxy.java</exclude>
1421+
<exclude>src/main/java/org/exist/dom/persistent/NodeSet.java</exclude>
14181422
<exclude>src/test/java/org/exist/dom/persistent/NodeTest.java</exclude>
14191423
<exclude>src/main/java/org/exist/dom/persistent/LockToken.java</exclude>
14201424
<exclude>src/test/java/org/exist/dom/persistent/PersistentDomTest.java</exclude>

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
11
/*
2+
* Elemental
3+
* Copyright (C) 2024, Evolved Binary Ltd
4+
*
5+
6+
* https://www.evolvedbinary.com | https://www.elemental.xyz
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation; version 2.1.
11+
*
12+
* This library is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* Lesser General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public
18+
* License along with this library; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+
*
21+
* NOTE: Parts of this file contain code from 'The eXist-db Authors'.
22+
* The original license header is included below.
23+
*
24+
* =====================================================================
25+
*
226
* eXist-db Open Source Native XML Database
327
* Copyright (C) 2001 The eXist-db Authors
428
*

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ public NodeSet getContextNodes(final int contextId) {
547547
if (Expression.NO_CONTEXT_ID != contextId) {
548548
context.addContextNode(contextId, context);
549549
}
550-
if (lastDoc != null && lastDoc.getDocId() != context.getOwnerDocument().getDocId()) {
550+
if (lastDoc == null || lastDoc.getDocId() != context.getOwnerDocument().getDocId()) {
551551
lastDoc = context.getOwnerDocument();
552552
result.add(context, getSizeHint(lastDoc));
553553
} else {

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

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,12 @@
6565
import org.w3c.dom.Node;
6666

6767
import javax.annotation.Nullable;
68-
import java.util.*;
68+
import java.lang.ref.WeakReference;
69+
import java.util.Arrays;
70+
import java.util.HashSet;
71+
import java.util.Iterator;
72+
import java.util.NoSuchElementException;
73+
import java.util.Set;
6974

7075
/**
7176
* A fast node set implementation, based on arrays to store nodes and documents.
@@ -91,7 +96,7 @@
9196
*/
9297
public class NewArrayNodeSet extends AbstractArrayNodeSet implements ExtNodeSet, DocumentSet {
9398

94-
private Set<Collection> cachedCollections = null;
99+
@Nullable private WeakReference<Set<Collection>> cachedCollectionsRef = null;
95100

96101
private int documentCount = 0;
97102

@@ -959,10 +964,10 @@ public NodeSet getContextNodes(final int contextId) {
959964
if(contextNode.getContextId() == contextId) {
960965
final NodeProxy context = contextNode.getNode();
961966
context.addMatches(current);
962-
if(Expression.NO_CONTEXT_ID != contextId) {
967+
if (Expression.NO_CONTEXT_ID != contextId) {
963968
context.addContextNode(contextId, context);
964969
}
965-
if(lastDoc != null && lastDoc.getDocId() != context.getOwnerDocument().getDocId()) {
970+
if (lastDoc == null || lastDoc.getDocId() != context.getOwnerDocument().getDocId()) {
966971
lastDoc = context.getOwnerDocument();
967972
result.add(context, getSizeHint(lastDoc));
968973
} else {
@@ -1038,16 +1043,27 @@ public boolean equalDocs(final DocumentSet other) {
10381043

10391044
@Override
10401045
public Iterator<Collection> getCollectionIterator() {
1041-
sort();
1042-
if(cachedCollections == null) {
1043-
cachedCollections = new HashSet<>();
1044-
for(int i = 0; i < documentCount; i++) {
1045-
final DocumentImpl doc = nodes[documentNodesOffset[i]].getOwnerDocument();
1046-
if(!cachedCollections.contains(doc.getCollection())) {
1047-
cachedCollections.add(doc.getCollection());
1048-
}
1046+
// First, try and retrieve from Cache
1047+
Set<Collection> cachedCollections;
1048+
if (this.cachedCollectionsRef != null) {
1049+
cachedCollections = this.cachedCollectionsRef.get();
1050+
if (cachedCollections != null) {
1051+
return cachedCollections.iterator();
10491052
}
10501053
}
1054+
1055+
sort();
1056+
1057+
// Second, Cache is empty, so create a Cache and return
1058+
cachedCollections = new HashSet<>();
1059+
for (int i = 0; i < documentCount; i++) {
1060+
final DocumentImpl doc = nodes[documentNodesOffset[i]].getOwnerDocument();
1061+
final Collection collection = doc.getCollection();
1062+
cachedCollections.add(collection);
1063+
}
1064+
1065+
this.cachedCollectionsRef = new WeakReference<>(cachedCollections);
1066+
10511067
return cachedCollections.iterator();
10521068
}
10531069

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

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,28 @@
11
/*
2+
* Elemental
3+
* Copyright (C) 2024, Evolved Binary Ltd
4+
*
5+
6+
* https://www.evolvedbinary.com | https://www.elemental.xyz
7+
*
8+
* This library is free software; you can redistribute it and/or
9+
* modify it under the terms of the GNU Lesser General Public
10+
* License as published by the Free Software Foundation; version 2.1.
11+
*
12+
* This library is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* Lesser General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public
18+
* License along with this library; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20+
*
21+
* NOTE: Parts of this file contain code from 'The eXist-db Authors'.
22+
* The original license header is included below.
23+
*
24+
* =====================================================================
25+
*
226
* eXist-db Open Source Native XML Database
327
* Copyright (C) 2001 The eXist-db Authors
428
*
@@ -377,7 +401,7 @@ boolean matchAncestorDescendant(NodeSet al, int mode, boolean includeSelf,
377401
*
378402
* @param contextId used to track context nodes when evaluating predicate
379403
* expressions. If contextId != {@link org.exist.xquery.Expression#NO_CONTEXT_ID}, the current context
380-
* will be added to each result of the of the selection.
404+
* will be added to each result of the selection.
381405
* @return all context nodes associated with the nodes in this node set.
382406
*/
383407
NodeSet getContextNodes(int contextId);

0 commit comments

Comments
 (0)