Skip to content

Commit eb580a2

Browse files
committed
[feature] Implement containsReference and contains on all Sequence types
1 parent c5d9337 commit eb580a2

20 files changed

+471
-3
lines changed

exist-core/src/main/java/org/exist/dom/memtree/NodeImpl.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,16 @@ public String getBaseURI() {
741741
return null;
742742
}
743743

744+
@Override
745+
public boolean containsReference(final Item item) {
746+
return this == item;
747+
}
748+
749+
@Override
750+
public boolean contains(final Item item) {
751+
return equals(item);
752+
}
753+
744754
@Override
745755
public void destroy(final XQueryContext context, final Sequence contextSequence) {
746756
}

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,48 @@ public final boolean contains(final NodeProxy proxy) {
352352
return searchData(root, proxy) != null;
353353
}
354354

355+
@Override
356+
public boolean containsReference(final Item item) {
357+
if (root == null) {
358+
return false;
359+
}
360+
361+
return containsReference(root, item);
362+
}
363+
364+
private boolean containsReference(@Nullable final Node node, final Item item) {
365+
if (node == null) {
366+
return false;
367+
}
368+
369+
if (node.data == item) {
370+
return true;
371+
}
372+
373+
return containsReference(node.leftChild, item) || containsReference(node.rightChild, item);
374+
}
375+
376+
@Override
377+
public boolean contains(final Item item) {
378+
if (root == null) {
379+
return false;
380+
}
381+
382+
return containsReference(root, item);
383+
}
384+
385+
private boolean contains(@Nullable final Node node, final Item item) {
386+
if (node == null) {
387+
return false;
388+
}
389+
390+
if (node.data.equals(item)) {
391+
return true;
392+
}
393+
394+
return containsReference(node.leftChild, item) || containsReference(node.rightChild, item);
395+
}
396+
355397
public void removeNode(final Node node) {
356398
--size;
357399
Node tempNode = node;

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,16 @@ public NodeSet union(final NodeSet other) {
128128
return other;
129129
}
130130

131+
@Override
132+
public boolean containsReference(final Item item) {
133+
return false;
134+
}
135+
136+
@Override
137+
public boolean contains(final Item item) {
138+
return false;
139+
}
140+
131141
private static final class EmptyNodeSetIterator implements NodeSetIterator {
132142

133143
@Override

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

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@
3939
import org.exist.xquery.value.Item;
4040
import org.exist.xquery.value.SequenceIterator;
4141
import org.exist.xquery.value.Type;
42+
import org.w3c.dom.Document;
4243
import org.w3c.dom.Node;
4344

45+
import javax.annotation.Nullable;
4446
import java.util.Arrays;
4547
import java.util.Iterator;
4648
import java.util.NoSuchElementException;
@@ -448,6 +450,52 @@ public boolean contains(final int docId) {
448450
return IntArrays.binarySearch(documentIds, 0, partCount, docId) > -1;
449451
}
450452

453+
@Override
454+
public boolean containsReference(final Item item) {
455+
if (item instanceof Node) {
456+
for (int i = 0; i < partCount; i++) {
457+
if (parts[i].containsReference(item)) {
458+
return true;
459+
}
460+
}
461+
}
462+
return false;
463+
}
464+
465+
@Override
466+
public boolean contains(final Item item) {
467+
if (item instanceof Node) {
468+
@Nullable final Document doc;
469+
if (item instanceof Document) {
470+
doc = (Document) item;
471+
} else {
472+
doc = ((Node) item).getOwnerDocument();
473+
}
474+
475+
if (doc == null || !(doc instanceof DocumentImpl || doc instanceof org.exist.dom.memtree.DocumentImpl)) {
476+
return false;
477+
}
478+
479+
final int docId;
480+
if (doc instanceof DocumentImpl) {
481+
docId = ((DocumentImpl) doc).getDocId();
482+
} else {
483+
docId = (int) ((org.exist.dom.memtree.DocumentImpl) doc).getDocId();
484+
}
485+
486+
if (IntArrays.binarySearch(documentIds, 0, partCount, docId) == -1) {
487+
return false;
488+
}
489+
490+
for (int i = 0; i < partCount; i++) {
491+
if (parts[i].contains(item)) {
492+
return true;
493+
}
494+
}
495+
}
496+
return false;
497+
}
498+
451499
@Override
452500
public NodeSet docsToNodeSet() {
453501
final NodeSet result = new ExtArrayNodeSet(partCount);
@@ -663,6 +711,26 @@ boolean contains(final NodeId nodeId) {
663711
return get(nodeId) != null;
664712
}
665713

714+
boolean containsReference(final Item item) {
715+
for (int i = 0; i < length; i++) {
716+
final NodeProxy p = array[i];
717+
if (p == item) {
718+
return true;
719+
}
720+
}
721+
return false;
722+
}
723+
724+
boolean contains(final Item item) {
725+
for (int i = 0; i < length; i++) {
726+
final NodeProxy p = array[i];
727+
if (p.equals(item)) {
728+
return true;
729+
}
730+
}
731+
return false;
732+
}
733+
666734
NodeProxy get(final int pos) {
667735
return array[pos];
668736
}

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

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import org.exist.collections.Collection;
2525
import org.exist.collections.ManagedLocks;
26+
import org.exist.dom.INode;
2627
import org.exist.numbering.NodeId;
2728
import org.exist.storage.DBBroker;
2829
import org.exist.storage.lock.LockManager;
@@ -36,8 +37,10 @@
3637
import org.exist.xquery.value.Item;
3738
import org.exist.xquery.value.SequenceIterator;
3839
import org.exist.xquery.value.Type;
40+
import org.w3c.dom.Document;
3941
import org.w3c.dom.Node;
4042

43+
import javax.annotation.Nullable;
4144
import java.util.*;
4245

4346
/**
@@ -1098,6 +1101,72 @@ public boolean contains(final int docId) {
10981101
return findDoc(docId) > -1;
10991102
}
11001103

1104+
@Override
1105+
public boolean containsReference(final Item item) {
1106+
sort();
1107+
if (item instanceof Node) {
1108+
@Nullable final Document doc;
1109+
if (item instanceof Document) {
1110+
doc = (Document) item;
1111+
} else {
1112+
doc = ((Node) item).getOwnerDocument();
1113+
}
1114+
1115+
if (doc == null || !(doc instanceof DocumentImpl || doc instanceof org.exist.dom.memtree.DocumentImpl)) {
1116+
return false;
1117+
}
1118+
1119+
final int docId;
1120+
if (doc instanceof DocumentImpl) {
1121+
docId = ((DocumentImpl) doc).getDocId();
1122+
} else {
1123+
docId = (int) ((org.exist.dom.memtree.DocumentImpl) doc).getDocId();
1124+
}
1125+
1126+
final int idx = findDoc(docId);
1127+
if (idx < 0) {
1128+
return false;
1129+
}
1130+
1131+
return get(idx, ((INode) item).getNodeId()) == item;
1132+
}
1133+
1134+
return false;
1135+
}
1136+
1137+
@Override
1138+
public boolean contains(final Item item) {
1139+
sort();
1140+
if (item instanceof Node) {
1141+
@Nullable final Document doc;
1142+
if (item instanceof Document) {
1143+
doc = (Document) item;
1144+
} else {
1145+
doc = ((Node) item).getOwnerDocument();
1146+
}
1147+
1148+
if (doc == null || !(doc instanceof DocumentImpl || doc instanceof org.exist.dom.memtree.DocumentImpl)) {
1149+
return false;
1150+
}
1151+
1152+
final int docId;
1153+
if (doc instanceof DocumentImpl) {
1154+
docId = ((DocumentImpl) doc).getDocId();
1155+
} else {
1156+
docId = (int) ((org.exist.dom.memtree.DocumentImpl) doc).getDocId();
1157+
}
1158+
1159+
final int idx = findDoc(docId);
1160+
if (idx < 0) {
1161+
return false;
1162+
}
1163+
1164+
return get(idx, ((INode) item).getNodeId()).equals(item);
1165+
}
1166+
1167+
return false;
1168+
}
1169+
11011170
@Override
11021171
public NodeSet docsToNodeSet() {
11031172
sort();

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,16 @@ public boolean hasChanged(final int previousState) {
976976
return false;
977977
}
978978

979+
@Override
980+
public boolean containsReference(final Item item) {
981+
return this == item;
982+
}
983+
984+
@Override
985+
public boolean contains(final Item item) {
986+
return this.equals(item);
987+
}
988+
979989
@Override
980990
public void destroy(final XQueryContext context, final Sequence contextSequence) {
981991
// Nothing to do

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,28 @@ public boolean contains(final NodeProxy proxy) {
133133
return false;
134134
}
135135

136+
@Override
137+
public boolean containsReference(final Item item) {
138+
for (final Iterator<IteratorItem> i = list.iterator(); i.hasNext();) {
139+
final NodeProxy p = (i.next()).proxy;
140+
if (p == item) {
141+
return true;
142+
}
143+
}
144+
return false;
145+
}
146+
147+
@Override
148+
public boolean contains(final Item item) {
149+
for (final Iterator<IteratorItem> i = list.iterator(); i.hasNext();) {
150+
final NodeProxy p = (i.next()).proxy;
151+
if (p.equals(item)) {
152+
return true;
153+
}
154+
}
155+
return false;
156+
}
157+
136158
@Override
137159
public NodeProxy get(final int pos) {
138160
final IteratorItem item = (IteratorItem) list.get(pos);

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,32 @@ public boolean contains(final NodeProxy p) {
113113
return false;
114114
}
115115

116+
@Override
117+
public boolean containsReference(final Item item) {
118+
if (!(item instanceof NodeProxy)) {
119+
return false;
120+
}
121+
122+
final NodeProxy firstParent = getFirstParent((NodeProxy) item, null, axis == Constants.SELF_AXIS, 0);
123+
if (firstParent == item) {
124+
return true;
125+
}
126+
return false;
127+
}
128+
129+
@Override
130+
public boolean contains(final Item item) {
131+
if (!(item instanceof NodeProxy)) {
132+
return false;
133+
}
134+
135+
final NodeProxy firstParent = getFirstParent((NodeProxy) item, null, axis == Constants.SELF_AXIS, 0);
136+
if (firstParent.equals(item)) {
137+
return true;
138+
}
139+
return false;
140+
}
141+
116142
public void setInPredicate(final boolean predicate) {
117143
inPredicate = predicate;
118144
}

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,16 @@ protected Sequence execute() throws XPathException {
435435
context.popDocumentContext();
436436
}
437437
}
438-
438+
439+
@Override
440+
public boolean containsReference(final Item item) {
441+
return this == item;
442+
}
443+
444+
@Override
445+
public boolean contains(final Item item) {
446+
return this.equals(item);
447+
}
439448
}
440449

441450
protected void setRecursive(boolean recursive) {

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import org.exist.xquery.value.SequenceIterator;
3333
import org.exist.xquery.value.Type;
3434

35+
import java.math.BigInteger;
36+
3537
public class RangeSequence extends AbstractSequence {
3638

3739
private final static Logger LOG = LogManager.getLogger(AbstractSequence.class);
@@ -208,6 +210,25 @@ public MemoryNodeSet toMemNodeSet() throws XPathException {
208210
public void removeDuplicates() {
209211
}
210212

213+
@Override
214+
public boolean containsReference(final Item item) {
215+
return start == item || end == item;
216+
}
217+
218+
@Override
219+
public boolean contains(final Item item) {
220+
if (item instanceof IntegerValue) {
221+
try {
222+
final BigInteger other = item.toJavaObject(BigInteger.class);
223+
return other.compareTo(start.toJavaObject(BigInteger.class)) >= 0
224+
&& other.compareTo(end.toJavaObject(BigInteger.class)) <= 0;
225+
} catch (final XPathException e) {
226+
return false;
227+
}
228+
}
229+
return false;
230+
}
231+
211232
/**
212233
* Generates a string representation of the Range Sequence.
213234
*

0 commit comments

Comments
 (0)