Skip to content

Commit 3344f29

Browse files
committed
[optimize] Reduce the memory used by intersect and except expressions
1 parent def4c8b commit 3344f29

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
@@ -1182,12 +1182,14 @@
11821182
<include>src/test/java/org/exist/xquery/EmbeddedBinariesTest.java</include>
11831183
<include>src/test/java/org/exist/xquery/EmbeddedBinariesTest.java.java</include>
11841184
<include>src/main/java/org/exist/xquery/ErrorCodes.java</include>
1185+
<include>src/main/java/org/exist/xquery/Except.java</include>
11851186
<include>src/main/java/org/exist/xquery/ExternalModuleImpl.java</include>
11861187
<include>src/main/java/org/exist/xquery/FilteredExpression.java</include>
11871188
<include>src/test/java/org/exist/xquery/ForwardReferenceTest.java</include>
11881189
<include>src/main/java/org/exist/xquery/Function.java</include>
11891190
<include>src/main/java/org/exist/xquery/FunctionFactory.java</include>
11901191
<include>src/test/java/org/exist/xquery/InternalModuleTest.java</include>
1192+
<include>src/main/java/org/exist/xquery/Intersect.java</include>
11911193
<include>src/test/java/org/exist/xquery/LexerTest.java</include>
11921194
<include>src/main/java/org/exist/xquery/LocationStep.java</include>
11931195
<include>src/main/java/org/exist/xquery/Module.java</include>
@@ -1962,6 +1964,7 @@
19621964
<exclude>src/test/java/org/exist/xquery/EmbeddedBinariesTest.java</exclude>
19631965
<exclude>src/test/java/org/exist/xquery/EmbeddedBinariesTest.java.java</exclude>
19641966
<exclude>src/main/java/org/exist/xquery/ErrorCodes.java</exclude>
1967+
<exclude>src/main/java/org/exist/xquery/Except.java</exclude>
19651968
<exclude>src/main/java/org/exist/xquery/ExternalModuleImpl.java</exclude>
19661969
<exclude>src/main/java/org/exist/xquery/FilteredExpression.java</exclude>
19671970
<exclude>src/test/java/org/exist/xquery/ForwardReferenceTest.java</exclude>
@@ -1971,6 +1974,7 @@
19711974
<exclude>src/test/java/org/exist/xquery/ImportFromPkgTest.java</exclude>
19721975
<exclude>src/test/java/org/exist/xquery/ImportModuleTest.java</exclude>
19731976
<exclude>src/test/java/org/exist/xquery/InternalModuleTest.java</exclude>
1977+
<exclude>src/main/java/org/exist/xquery/Intersect.java</exclude>
19741978
<exclude>src/main/java/org/exist/xquery/JavaBinding.java</exclude>
19751979
<exclude>src/test/resources-filtered/org/exist/xquery/JavaBindingTest.conf.xml</exclude>
19761980
<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)