Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize fn:subsequence #1977

Merged
merged 15 commits into from Sep 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 19 additions & 3 deletions src/org/exist/dom/memtree/NodeImpl.java
Expand Up @@ -611,7 +611,7 @@ public int getItemType() {
}

@Override
public SequenceIterator iterate() throws XPathException {
public SequenceIterator iterate() {
return new SingleNodeIterator(this);
}

Expand All @@ -621,7 +621,7 @@ public SequenceIterator unorderedIterator() {
}

@Override
public int getItemCount() {
public long getItemCountLong() {
return 1;
}

Expand Down Expand Up @@ -983,7 +983,7 @@ protected DOMException unsupported() {
}

private final static class SingleNodeIterator implements SequenceIterator {
NodeImpl node;
private NodeImpl node;

public SingleNodeIterator(final NodeImpl node) {
this.node = node;
Expand All @@ -1001,5 +1001,21 @@ public Item nextItem() {
return next;
}

@Override
public long skippable() {
if (node != null) {
return 1;
}
return 0;
}

@Override
public long skip(final long n) {
final long skip = Math.min(n, node != null ? 1 : 0);
if (skip == 1) {
node = null;
}
return skip;
}
}
}
44 changes: 20 additions & 24 deletions src/org/exist/dom/persistent/AVLTreeNodeSet.java
Expand Up @@ -22,10 +22,10 @@
package org.exist.dom.persistent;

import org.exist.numbering.NodeId;
import org.exist.xquery.XPathException;
import org.exist.xquery.value.Item;
import org.exist.xquery.value.SequenceIterator;

import javax.annotation.Nullable;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Iterator;
Expand All @@ -36,17 +36,14 @@ public class AVLTreeNodeSet extends AbstractNodeSet {
private int size = 0;
private int state = 0;

/* (non-Javadoc)
* @see org.exist.dom.persistent.NodeSet#iterate()
*/
@Override
public SequenceIterator iterate() throws XPathException {
return new InorderTraversal();
public SequenceIterator iterate() {
return new InorderTraversal(root);
}

@Override
public SequenceIterator unorderedIterator() throws XPathException {
return new InorderTraversal();
public SequenceIterator unorderedIterator() {
return new InorderTraversal(root);
}

@Override
Expand All @@ -61,9 +58,8 @@ public int getLength() {
return size;
}

//TODO : evaluate both semantics
@Override
public int getItemCount() {
public long getItemCountLong() {
return size;
}

Expand All @@ -82,7 +78,7 @@ public NodeProxy get(final int pos) {

@Override
public final NodeProxy get(final NodeProxy p) {
final Node n = searchData(p);
final Node n = searchData(root, p);
return n == null ? null : n.getData();
}

Expand Down Expand Up @@ -304,7 +300,7 @@ private void balance(final Node node) {
}
}

public final Node searchData(final NodeProxy proxy) {
private static @Nullable Node searchData(@Nullable final Node root, final NodeProxy proxy) {
if(root == null) {
return null;
}
Expand Down Expand Up @@ -353,7 +349,7 @@ public final NodeProxy get(final DocumentImpl doc, final NodeId nodeId) {

@Override
public final boolean contains(final NodeProxy proxy) {
return searchData(proxy) != null;
return searchData(root, proxy) != null;
}

public void removeNode(final Node node) {
Expand Down Expand Up @@ -398,7 +394,7 @@ public void removeNode(final Node node) {

@Override
public NodeSetIterator iterator() {
return new InorderTraversal();
return new InorderTraversal(root);
}

@Override
Expand All @@ -420,11 +416,12 @@ private void setHasChanged() {
state = (state == Integer.MAX_VALUE ? 0 : state + 1);
}

class InorderTraversal implements NodeSetIterator, SequenceIterator {

private static class InorderTraversal implements NodeSetIterator, SequenceIterator {
@Nullable private final Node root;
private final Deque<Node> nodes = new ArrayDeque<>();

public InorderTraversal() {
public InorderTraversal(@Nullable final Node root) {
this.root = root;
if(root != null) {
Node tempNode = root;
do {
Expand All @@ -441,10 +438,10 @@ public boolean hasNext() {

@Override
public NodeProxy next() {
final Node currentNode = nodes.poll();
if (currentNode == null) {
if(nodes.isEmpty()) {
return null;
}
final Node currentNode = nodes.pop();
if(currentNode.hasRightChild()) {
Node tempNode = currentNode.rightChild;
do {
Expand All @@ -466,7 +463,7 @@ public NodeProxy peekNode() {

@Override
public void setPosition(final NodeProxy proxy) {
final Node n = searchData(proxy);
final Node n = searchData(root, proxy);
nodes.clear();
if(n != null) {
Node tempNode = n;
Expand All @@ -484,11 +481,11 @@ public void remove() {

@Override
public Item nextItem() {
final Node currentNode = nodes.poll();
if (currentNode == null) {
if(nodes.isEmpty()) {
return null;
}
if(currentNode.hasRightChild()) {
final Node currentNode = nodes.pop();
if (currentNode.hasRightChild()) {
Node tempNode = currentNode.rightChild;
do {
nodes.push(tempNode);
Expand All @@ -505,7 +502,6 @@ public String toString() {
}

private static final class Node {

private NodeProxy data;
private Node parent;
private Node leftChild;
Expand Down
2 changes: 1 addition & 1 deletion src/org/exist/dom/persistent/AbstractArrayNodeSet.java
Expand Up @@ -154,7 +154,7 @@ public int getLength() {
}

@Override
public int getItemCount() {
public long getItemCountLong() {
return getLength();
}

Expand Down
7 changes: 3 additions & 4 deletions src/org/exist/dom/persistent/EmptyNodeSet.java
Expand Up @@ -24,7 +24,6 @@

import org.exist.collections.Collection;
import org.exist.numbering.NodeId;
import org.exist.xquery.XPathException;
import org.exist.xquery.value.Item;
import org.exist.xquery.value.SequenceIterator;
import org.w3c.dom.Node;
Expand All @@ -40,12 +39,12 @@ public NodeSetIterator iterator() {
}

@Override
public SequenceIterator iterate() throws XPathException {
public SequenceIterator iterate() {
return SequenceIterator.EMPTY_ITERATOR;
}

@Override
public SequenceIterator unorderedIterator() throws XPathException {
public SequenceIterator unorderedIterator() {
return SequenceIterator.EMPTY_ITERATOR;
}

Expand Down Expand Up @@ -78,7 +77,7 @@ public int getLength() {
}

@Override
public int getItemCount() {
public long getItemCountLong() {
return 0;
}

Expand Down
4 changes: 2 additions & 2 deletions src/org/exist/dom/persistent/ExtArrayNodeSet.java
Expand Up @@ -197,13 +197,13 @@ public NodeSetIterator iterator() {
}

@Override
public SequenceIterator iterate() throws XPathException {
public SequenceIterator iterate() {
sortInDocumentOrder();
return new ExtArrayIterator();
}

@Override
public SequenceIterator unorderedIterator() throws XPathException {
public SequenceIterator unorderedIterator() {
if(!isSorted()) {
sort();
}
Expand Down
24 changes: 19 additions & 5 deletions src/org/exist/dom/persistent/NewArrayNodeSet.java
Expand Up @@ -161,13 +161,13 @@ public NodeSetIterator iterator() {
}

@Override
public SequenceIterator iterate() throws XPathException {
public SequenceIterator iterate() {
sortInDocumentOrder();
return new NewArrayIterator();
}

@Override
public SequenceIterator unorderedIterator() throws XPathException {
public SequenceIterator unorderedIterator() {
if(!isSorted()) {
sort();
}
Expand Down Expand Up @@ -1109,9 +1109,8 @@ public void clearContext(final int contextId) throws XPathException {
}
}

private class NewArrayIterator implements NodeSetIterator, SequenceIterator {

int pos = 0;
protected class NewArrayIterator implements NodeSetIterator, SequenceIterator {
private int pos = 0;

@Override
public final boolean hasNext() {
Expand All @@ -1127,6 +1126,21 @@ public final NodeProxy next() {
return nodes[pos++];
}

@Override
public long skippable() {
if (pos == -1) {
return 0;
}
return size - pos;
}

@Override
public long skip(final long n) {
final long skip = Math.min(n, pos == -1 ? 0 : size - pos);
pos += skip;
return skip;
}

@Override
public final void remove() {
throw new UnsupportedOperationException();
Expand Down
22 changes: 19 additions & 3 deletions src/org/exist/dom/persistent/NodeProxy.java
Expand Up @@ -829,7 +829,7 @@ public NodeSetIterator iterator() {
}

@Override
public SequenceIterator iterate() throws XPathException {
public SequenceIterator iterate() {
return new SingleNodeIterator(this);
}

Expand Down Expand Up @@ -893,9 +893,8 @@ public int getLength() {
return 1;
}

//TODO : evaluate both semantics
@Override
public int getItemCount() {
public long getItemCountLong() {
return 1;
}

Expand Down Expand Up @@ -1304,6 +1303,23 @@ public final NodeProxy next() {
}
}

@Override
public long skippable() {
if (hasNext) {
return 1;
}
return 0;
}

@Override
public long skip(final long n) {
final long skip = Math.min(n, hasNext ? 1 : 0);
if(skip == 1) {
hasNext = false;
}
return skip;
}

@Override
public final NodeProxy peekNode() {
return node;
Expand Down
7 changes: 3 additions & 4 deletions src/org/exist/dom/persistent/SortedNodeSet.java
Expand Up @@ -175,9 +175,8 @@ public int getLength() {
return list.size();
}

//TODO : evaluate both semantics (length/item count)
@Override
public int getItemCount() {
public long getItemCountLong() {
return list.size();
}

Expand All @@ -200,12 +199,12 @@ public NodeSetIterator iterator() {
}

@Override
public SequenceIterator iterate() throws XPathException {
public SequenceIterator iterate() {
return new SortedNodeSetIterator(list.iterator());
}

@Override
public SequenceIterator unorderedIterator() throws XPathException {
public SequenceIterator unorderedIterator() {
return new SortedNodeSetIterator(list.iterator());
}

Expand Down
4 changes: 2 additions & 2 deletions src/org/exist/dom/persistent/VirtualNodeSet.java
Expand Up @@ -621,10 +621,10 @@ public int getItemType() {
}

@Override
public int getItemCount() {
public long getItemCountLong() {
//TODO : evaluate both semantics
realize();
return realSet.getItemCount();
return realSet.getItemCountLong();
}

@Override
Expand Down