Skip to content

Commit 851e285

Browse files
committed
[optimize] Reduce the memory used by intersect and except expressions
1 parent 9b60c6c commit 851e285

3 files changed

Lines changed: 90 additions & 18 deletions

File tree

exist-core/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,10 +1210,12 @@
12101210
<include>src/test/java/org/exist/xquery/EmbeddedBinariesTest.java</include>
12111211
<include>src/test/java/org/exist/xquery/EmbeddedBinariesTest.java.java</include>
12121212
<include>src/main/java/org/exist/xquery/ErrorCodes.java</include>
1213+
<include>src/main/java/org/exist/xquery/Except.java</include>
12131214
<include>src/main/java/org/exist/xquery/ExternalModuleImpl.java</include>
12141215
<include>src/test/java/org/exist/xquery/ForwardReferenceTest.java</include>
12151216
<include>src/main/java/org/exist/xquery/Function.java</include>
12161217
<include>src/main/java/org/exist/xquery/FunctionFactory.java</include>
1218+
<include>src/main/java/org/exist/xquery/Intersect.java</include>
12171219
<include>src/test/java/org/exist/xquery/LexerTest.java</include>
12181220
<include>src/main/java/org/exist/xquery/LocationStep.java</include>
12191221
<include>src/main/java/org/exist/xquery/Module.java</include>
@@ -2003,13 +2005,15 @@
20032005
<exclude>src/test/java/org/exist/xquery/EmbeddedBinariesTest.java</exclude>
20042006
<exclude>src/test/java/org/exist/xquery/EmbeddedBinariesTest.java.java</exclude>
20052007
<exclude>src/main/java/org/exist/xquery/ErrorCodes.java</exclude>
2008+
<exclude>src/main/java/org/exist/xquery/Except.java</exclude>
20062009
<exclude>src/main/java/org/exist/xquery/ExternalModuleImpl.java</exclude>
20072010
<exclude>src/test/java/org/exist/xquery/ForwardReferenceTest.java</exclude>
20082011
<exclude>src/main/java/org/exist/xquery/Function.java</exclude>
20092012
<exclude>src/main/java/org/exist/xquery/FunctionFactory.java</exclude>
20102013
<exclude>src/test/resources-filtered/org/exist/xquery/import-from-pkg-test.conf.xml</exclude>
20112014
<exclude>src/test/java/org/exist/xquery/ImportFromPkgTest.java</exclude>
20122015
<exclude>src/test/java/org/exist/xquery/ImportModuleTest.java</exclude>
2016+
<exclude>src/main/java/org/exist/xquery/Intersect.java</exclude>
20132017
<exclude>src/main/java/org/exist/xquery/JavaBinding.java</exclude>
20142018
<exclude>src/test/resources-filtered/org/exist/xquery/JavaBindingTest.conf.xml</exclude>
20152019
<exclude>src/test/java/org/exist/xquery/JavaBindingTest.java</exclude>

exist-core/src/main/java/org/exist/xquery/Except.java

Lines changed: 44 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+
* admin@evolvedbinary.com
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
*
@@ -22,14 +46,11 @@
2246
package org.exist.xquery;
2347

2448
import java.util.Set;
25-
import java.util.TreeSet;
2649

27-
import org.exist.xquery.value.Item;
28-
import org.exist.xquery.value.ItemComparator;
29-
import org.exist.xquery.value.Sequence;
30-
import org.exist.xquery.value.SequenceIterator;
31-
import org.exist.xquery.value.Type;
32-
import org.exist.xquery.value.ValueSequence;
50+
import it.unimi.dsi.fastutil.objects.ObjectAVLTreeSet;
51+
import org.exist.xquery.value.*;
52+
53+
import javax.annotation.Nullable;
3354

3455
/**
3556
* @author <a href="mailto:wolfgang@exist-db.org">Wolfgang Meier</a>
@@ -57,18 +78,29 @@ public Sequence combine(final Sequence ls, final Sequence rs) throws XPathExcept
5778
if (ls.isPersistentSet() && rs.isPersistentSet()) {
5879
result = ls.toNodeSet().except(rs.toNodeSet());
5980
} else {
60-
result = new ValueSequence();
61-
final Set<Item> set = new TreeSet<>(new ItemComparator());
81+
@Nullable Sequence values = null;
82+
@Nullable Set<Item> set = null;
6283
for (final SequenceIterator i = rs.unorderedIterator(); i.hasNext(); ) {
84+
if (set == null) {
85+
set = new ObjectAVLTreeSet<>(new ItemComparator(null));
86+
}
6387
set.add(i.nextItem());
6488
}
6589
for (final SequenceIterator i = ls.unorderedIterator(); i.hasNext(); ) {
6690
final Item next = i.nextItem();
67-
if (!set.contains(next)) {
68-
result.add(next);
91+
if (set == null || !set.contains(next)) {
92+
if (values == null) {
93+
values = new ValueSequence();
94+
}
95+
values.add(next);
6996
}
7097
}
71-
result.removeDuplicates();
98+
if (values != null) {
99+
values.removeDuplicates();
100+
result = values;
101+
} else {
102+
result = Sequence.EMPTY_SEQUENCE;
103+
}
72104
}
73105
}
74106

exist-core/src/main/java/org/exist/xquery/Intersect.java

Lines changed: 42 additions & 6 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+
* admin@evolvedbinary.com
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
*
@@ -21,10 +45,11 @@
2145
*/
2246
package org.exist.xquery;
2347

48+
import it.unimi.dsi.fastutil.objects.ObjectAVLTreeSet;
2449
import org.exist.xquery.value.*;
2550

51+
import javax.annotation.Nullable;
2652
import java.util.Set;
27-
import java.util.TreeSet;
2853

2954
/**
3055
* @author <a href="mailto:wolfgang@exist-db.org">Wolfgang Meier</a>
@@ -47,18 +72,29 @@ public Sequence combine(final Sequence ls, final Sequence rs) throws XPathExcept
4772
if (ls.isPersistentSet() && rs.isPersistentSet()) {
4873
result = ls.toNodeSet().intersection(rs.toNodeSet());
4974
} else {
50-
result = new ValueSequence(true);
51-
final Set<Item> set = new TreeSet<>(new ItemComparator());
75+
@Nullable Sequence values = null;
76+
@Nullable Set<Item> set = null;
5277
for (final SequenceIterator i = ls.unorderedIterator(); i.hasNext(); ) {
78+
if (set == null) {
79+
set = new ObjectAVLTreeSet<>(new ItemComparator(null));
80+
}
5381
set.add(i.nextItem());
5482
}
5583
for (final SequenceIterator i = rs.unorderedIterator(); i.hasNext(); ) {
5684
final Item next = i.nextItem();
57-
if (set.contains(next)) {
58-
result.add(next);
85+
if (set != null && set.contains(next)) {
86+
if (values == null) {
87+
values = new ValueSequence(true);
88+
}
89+
values.add(next);
5990
}
6091
}
61-
result.removeDuplicates();
92+
if (values != null) {
93+
values.removeDuplicates();
94+
result = values;
95+
} else {
96+
result = Sequence.EMPTY_SEQUENCE;
97+
}
6298
}
6399
}
64100

0 commit comments

Comments
 (0)