Skip to content

Commit 8d39157

Browse files
authored
Merge pull request #112 from evolvedbinary/7.x.x/hotfix/array-set-sizing
[7.x.x] Reduce memory use and improve NodeSet sizing
2 parents 9d1a4f2 + ec0b31f commit 8d39157

File tree

5 files changed

+111
-17
lines changed

5 files changed

+111
-17
lines changed

exist-core/pom.xml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,7 @@
868868
<include>src/test/java/org/exist/deadlocks/GetReleaseBrokerDeadlocksTest.java</include>
869869
<include>src/main/java/org/exist/dom/NodeListImpl.java</include>
870870
<include>src/main/java/org/exist/dom/QName.java</include>
871-
<exclude>src/main/java/org/exist/dom/memtree/AbstractCharacterData.java</exclude>
871+
<include>src/main/java/org/exist/dom/memtree/AbstractCharacterData.java</include>
872872
<include>src/main/java/org/exist/dom/memtree/AttrImpl.java</include>
873873
<include>src/main/java/org/exist/dom/memtree/DocumentBuilderReceiver.java</include>
874874
<include>src/main/java/org/exist/dom/memtree/DocumentImpl.java</include>
@@ -879,9 +879,10 @@
879879
<include>src/main/java/org/exist/dom/memtree/ElementImpl.java</include>
880880
<include>src/test/java/org/exist/dom/memtree/MemtreeInXQueryTest.java</include>
881881
<include>src/main/java/org/exist/dom/memtree/MemTreeBuilder.java</include>
882-
<exclude>src/main/java/org/exist/dom/memtree/NamespaceNode.java</exclude>
882+
<include>src/main/java/org/exist/dom/memtree/NamespaceNode.java</include>
883883
<include>src/main/java/org/exist/dom/memtree/NodeImpl.java</include>
884-
<exclude>src/main/java/org/exist/dom/memtree/ProcessingInstructionImpl.java</exclude>
884+
<include>src/main/java/org/exist/dom/memtree/ProcessingInstructionImpl.java</include>
885+
<include>src/main/java/org/exist/dom/persistent/AbstractArrayNodeSet.java</include>
885886
<include>src/main/java/org/exist/dom/persistent/AbstractCharacterData.java</include>
886887
<include>src/main/java/org/exist/dom/persistent/AttrImpl.java</include>
887888
<include>src/main/java/org/exist/dom/persistent/BinaryDocument.java</include>
@@ -892,7 +893,9 @@
892893
<include>src/main/java/org/exist/dom/persistent/DocumentTypeImpl.java</include>
893894
<include>src/main/java/org/exist/dom/persistent/DocumentSet.java</include>
894895
<include>src/main/java/org/exist/dom/persistent/ElementImpl.java</include>
896+
<include>src/main/java/org/exist/dom/persistent/NewArrayNodeSet.java</include>
895897
<include>src/main/java/org/exist/dom/persistent/NodeProxy.java</include>
898+
<include>src/main/java/org/exist/dom/persistent/NodeSet.java</include>
896899
<include>src/test/java/org/exist/dom/persistent/NodeTest.java</include>
897900
<include>src/main/java/org/exist/dom/persistent/LockToken.java</include>
898901
<include>src/test/java/org/exist/dom/persistent/PersistentDomTest.java</include>
@@ -1466,6 +1469,7 @@
14661469
<exclude>src/main/java/org/exist/dom/memtree/reference/ElementReferenceImpl.java</exclude>
14671470
<exclude>src/main/java/org/exist/dom/memtree/reference/ProcessingInstructionReferenceImpl.java</exclude>
14681471
<exclude>src/main/java/org/exist/dom/memtree/reference/TextReferenceImpl.java</exclude>
1472+
<exclude>src/main/java/org/exist/dom/persistent/AbstractArrayNodeSet.java</exclude>
14691473
<exclude>src/main/java/org/exist/dom/persistent/AbstractCharacterData.java</exclude>
14701474
<exclude>src/main/java/org/exist/dom/persistent/AttrImpl.java</exclude>
14711475
<exclude>src/main/java/org/exist/dom/persistent/BinaryDocument.java</exclude>
@@ -1476,7 +1480,9 @@
14761480
<exclude>src/main/java/org/exist/dom/persistent/DocumentSet.java</exclude>
14771481
<exclude>src/main/java/org/exist/dom/persistent/DocumentTypeImpl.java</exclude>
14781482
<exclude>src/main/java/org/exist/dom/persistent/ElementImpl.java</exclude>
1483+
<exclude>src/main/java/org/exist/dom/persistent/NewArrayNodeSet.java</exclude>
14791484
<exclude>src/main/java/org/exist/dom/persistent/NodeProxy.java</exclude>
1485+
<exclude>src/main/java/org/exist/dom/persistent/NodeSet.java</exclude>
14801486
<exclude>src/test/java/org/exist/dom/persistent/NodeTest.java</exclude>
14811487
<exclude>src/main/java/org/exist/dom/persistent/LockToken.java</exclude>
14821488
<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: 52 additions & 12 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
*
@@ -41,7 +65,12 @@
4165
import org.w3c.dom.Node;
4266

4367
import javax.annotation.Nullable;
44-
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;
4574

4675
/**
4776
* A fast node set implementation, based on arrays to store nodes and documents.
@@ -67,7 +96,7 @@
6796
*/
6897
public class NewArrayNodeSet extends AbstractArrayNodeSet implements ExtNodeSet, DocumentSet {
6998

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

72101
private int documentCount = 0;
73102

@@ -935,10 +964,10 @@ public NodeSet getContextNodes(final int contextId) {
935964
if(contextNode.getContextId() == contextId) {
936965
final NodeProxy context = contextNode.getNode();
937966
context.addMatches(current);
938-
if(Expression.NO_CONTEXT_ID != contextId) {
967+
if (Expression.NO_CONTEXT_ID != contextId) {
939968
context.addContextNode(contextId, context);
940969
}
941-
if(lastDoc != null && lastDoc.getDocId() != context.getOwnerDocument().getDocId()) {
970+
if (lastDoc == null || lastDoc.getDocId() != context.getOwnerDocument().getDocId()) {
942971
lastDoc = context.getOwnerDocument();
943972
result.add(context, getSizeHint(lastDoc));
944973
} else {
@@ -1014,16 +1043,27 @@ public boolean equalDocs(final DocumentSet other) {
10141043

10151044
@Override
10161045
public Iterator<Collection> getCollectionIterator() {
1017-
sort();
1018-
if(cachedCollections == null) {
1019-
cachedCollections = new HashSet<>();
1020-
for(int i = 0; i < documentCount; i++) {
1021-
final DocumentImpl doc = nodes[documentNodesOffset[i]].getOwnerDocument();
1022-
if(!cachedCollections.contains(doc.getCollection())) {
1023-
cachedCollections.add(doc.getCollection());
1024-
}
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();
10251052
}
10261053
}
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+
10271067
return cachedCollections.iterator();
10281068
}
10291069

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)