Skip to content

Commit ba2441a

Browse files
committed
[bugfix] Ensure that the collection cache used by NewArrayNodeSet can be released if there is memory pressure
1 parent a33e34e commit ba2441a

File tree

2 files changed

+52
-10
lines changed

2 files changed

+52
-10
lines changed

exist-core/pom.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,6 +874,7 @@
874874
<include>src/main/java/org/exist/dom/persistent/DocumentTypeImpl.java</include>
875875
<include>src/main/java/org/exist/dom/persistent/DocumentSet.java</include>
876876
<include>src/main/java/org/exist/dom/persistent/ElementImpl.java</include>
877+
<include>src/main/java/org/exist/dom/persistent/NewArrayNodeSet.java</include>
877878
<include>src/main/java/org/exist/dom/persistent/NodeProxy.java</include>
878879
<include>src/test/java/org/exist/dom/persistent/NodeTest.java</include>
879880
<include>src/main/java/org/exist/dom/persistent/LockToken.java</include>
@@ -1318,6 +1319,7 @@
13181319
<exclude>src/main/java/org/exist/dom/persistent/DocumentSet.java</exclude>
13191320
<exclude>src/main/java/org/exist/dom/persistent/DocumentTypeImpl.java</exclude>
13201321
<exclude>src/main/java/org/exist/dom/persistent/ElementImpl.java</exclude>
1322+
<exclude>src/main/java/org/exist/dom/persistent/NewArrayNodeSet.java</exclude>
13211323
<exclude>src/main/java/org/exist/dom/persistent/NodeProxy.java</exclude>
13221324
<exclude>src/test/java/org/exist/dom/persistent/NodeTest.java</exclude>
13231325
<exclude>src/main/java/org/exist/dom/persistent/LockToken.java</exclude>

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

Lines changed: 50 additions & 10 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

@@ -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

0 commit comments

Comments
 (0)