Search in sources :

Example 16 with Node

use of org.sirix.node.interfaces.Node in project sirix by sirixdb.

the class XdmNodeWriterTrxImpl method moveSubtreeToFirstChild.

@Override
public XdmNodeWriteTrx moveSubtreeToFirstChild(@Nonnegative final long fromKey) throws SirixException, IllegalArgumentException {
    acquireLock();
    try {
        Preconditions.checkArgument(fromKey >= 0 && fromKey <= getMaxNodeKey(), "Argument must be a valid node key!");
        Preconditions.checkArgument(fromKey != getCurrentNode().getNodeKey(), "Can't move itself to right sibling of itself!");
        @SuppressWarnings("unchecked") final Optional<? extends Node> node = (Optional<? extends Node>) getPageTransaction().getRecord(fromKey, PageKind.RECORDPAGE, -1);
        if (!node.isPresent()) {
            throw new IllegalStateException("Node to move must exist!");
        }
        final Node nodeToMove = node.get();
        if (nodeToMove instanceof StructNode && getCurrentNode().getKind() == Kind.ELEMENT) {
            // Safe to cast (because IStructNode is a subtype of INode).
            checkAncestors(nodeToMove);
            checkAccessAndCommit();
            final ElementNode nodeAnchor = (ElementNode) getCurrentNode();
            // Check that it's not already the first child.
            if (nodeAnchor.getFirstChildKey() != nodeToMove.getNodeKey()) {
                final StructNode toMove = (StructNode) nodeToMove;
                // Adapt index-structures (before move).
                adaptSubtreeForMove(toMove, ChangeType.DELETE);
                // Adapt hashes.
                adaptHashesForMove(toMove);
                // Adapt pointers and merge sibling text nodes.
                adaptForMove(toMove, nodeAnchor, InsertPos.ASFIRSTCHILD);
                mNodeReader.moveTo(toMove.getNodeKey());
                adaptHashesWithAdd();
                // Adapt path summary.
                if (mBuildPathSummary && toMove instanceof NameNode) {
                    final NameNode moved = (NameNode) toMove;
                    mPathSummaryWriter.adaptPathForChangedNode(moved, getName(), moved.getURIKey(), moved.getPrefixKey(), moved.getLocalNameKey(), OPType.MOVED);
                }
                // Adapt index-structures (after move).
                adaptSubtreeForMove(toMove, ChangeType.INSERT);
                // Compute and assign new DeweyIDs.
                if (mDeweyIDsStored) {
                    computeNewDeweyIDs();
                }
            }
            return this;
        } else {
            throw new SirixUsageException("Move is not allowed if moved node is not an ElementNode and the node isn't inserted at an element node!");
        }
    } finally {
        unLock();
    }
}
Also used : NameNode(org.sirix.node.interfaces.NameNode) Optional(java.util.Optional) TextNode(org.sirix.node.TextNode) CommentNode(org.sirix.node.CommentNode) PINode(org.sirix.node.PINode) Node(org.sirix.node.interfaces.Node) ValueNode(org.sirix.node.interfaces.ValueNode) AttributeNode(org.sirix.node.AttributeNode) ImmutableNode(org.sirix.node.interfaces.immutable.ImmutableNode) StructNode(org.sirix.node.interfaces.StructNode) ElementNode(org.sirix.node.ElementNode) NamespaceNode(org.sirix.node.NamespaceNode) NameNode(org.sirix.node.interfaces.NameNode) ElementNode(org.sirix.node.ElementNode) SirixUsageException(org.sirix.exception.SirixUsageException) StructNode(org.sirix.node.interfaces.StructNode)

Example 17 with Node

use of org.sirix.node.interfaces.Node in project sirix by sirixdb.

the class XdmNodeWriterTrxImpl method computeNewDeweyIDs.

/**
 * Compute the new DeweyIDs.
 *
 * @throws SirixException if anything went wrong
 */
private void computeNewDeweyIDs() throws SirixException {
    SirixDeweyID id = null;
    if (hasLeftSibling() && hasRightSibling()) {
        id = SirixDeweyID.newBetween(getLeftSiblingDeweyID().get(), getRightSiblingDeweyID().get());
    } else if (hasLeftSibling()) {
        id = SirixDeweyID.newBetween(getLeftSiblingDeweyID().get(), null);
    } else if (hasRightSibling()) {
        id = SirixDeweyID.newBetween(null, getRightSiblingDeweyID().get());
    } else {
        id = mNodeReader.getParentDeweyID().get().getNewChildID();
    }
    assert id != null;
    final long nodeKey = mNodeReader.getCurrentNode().getNodeKey();
    final StructNode root = (StructNode) getPageTransaction().prepareEntryForModification(nodeKey, PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
    root.setDeweyID(Optional.of(id));
    if (root.hasFirstChild()) {
        final Node firstChild = (Node) getPageTransaction().prepareEntryForModification(root.getFirstChildKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
        firstChild.setDeweyID(Optional.of(id.getNewChildID()));
        int previousLevel = getDeweyID().get().getLevel();
        mNodeReader.moveTo(firstChild.getNodeKey());
        int attributeNr = 0;
        int nspNr = 0;
        for (@SuppressWarnings("unused") final long key : LevelOrderAxis.newBuilder(this).includeNonStructuralNodes().build()) {
            Optional<SirixDeweyID> deweyID = Optional.<SirixDeweyID>empty();
            if (isAttribute()) {
                final long attNodeKey = mNodeReader.getNodeKey();
                if (attributeNr == 0) {
                    deweyID = Optional.of(mNodeReader.getParentDeweyID().get().getNewAttributeID());
                } else {
                    mNodeReader.moveTo(attributeNr - 1);
                    deweyID = Optional.of(SirixDeweyID.newBetween(mNodeReader.getNode().getDeweyID().get(), null));
                }
                mNodeReader.moveTo(attNodeKey);
                attributeNr++;
            } else if (isNamespace()) {
                final long nspNodeKey = mNodeReader.getNodeKey();
                if (nspNr == 0) {
                    deweyID = Optional.of(mNodeReader.getParentDeweyID().get().getNewNamespaceID());
                } else {
                    mNodeReader.moveTo(nspNr - 1);
                    deweyID = Optional.of(SirixDeweyID.newBetween(mNodeReader.getNode().getDeweyID().get(), null));
                }
                mNodeReader.moveTo(nspNodeKey);
                nspNr++;
            } else {
                attributeNr = 0;
                nspNr = 0;
                if (previousLevel + 1 == getDeweyID().get().getLevel()) {
                    if (mNodeReader.hasLeftSibling()) {
                        deweyID = Optional.of(SirixDeweyID.newBetween(getLeftSiblingDeweyID().get(), null));
                    } else {
                        deweyID = Optional.of(getParentDeweyID().get().getNewChildID());
                    }
                } else {
                    previousLevel++;
                    deweyID = Optional.of(getParentDeweyID().get().getNewChildID());
                }
            }
            final Node node = (Node) getPageTransaction().prepareEntryForModification(mNodeReader.getCurrentNode().getNodeKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
            node.setDeweyID(deweyID);
        }
        mNodeReader.moveTo(nodeKey);
    }
}
Also used : TextNode(org.sirix.node.TextNode) CommentNode(org.sirix.node.CommentNode) PINode(org.sirix.node.PINode) Node(org.sirix.node.interfaces.Node) ValueNode(org.sirix.node.interfaces.ValueNode) AttributeNode(org.sirix.node.AttributeNode) ImmutableNode(org.sirix.node.interfaces.immutable.ImmutableNode) StructNode(org.sirix.node.interfaces.StructNode) ElementNode(org.sirix.node.ElementNode) NamespaceNode(org.sirix.node.NamespaceNode) NameNode(org.sirix.node.interfaces.NameNode) UnorderedKeyValuePage(org.sirix.page.UnorderedKeyValuePage) SirixDeweyID(org.sirix.node.SirixDeweyID) StructNode(org.sirix.node.interfaces.StructNode)

Example 18 with Node

use of org.sirix.node.interfaces.Node in project sirix by sirixdb.

the class XdmNodeWriterTrxImpl method rollingRemove.

/**
 * Adapting the structure with a rolling hash for all ancestors only with remove.
 *
 * @throws SirixIOException if anything weird happened
 */
private void rollingRemove() throws SirixIOException {
    final ImmutableNode startNode = getCurrentNode();
    long hashToRemove = startNode.getHash();
    long hashToAdd = 0;
    long newHash = 0;
    // go the path to the root
    do {
        final Node node = (Node) getPageTransaction().prepareEntryForModification(mNodeReader.getCurrentNode().getNodeKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
        if (node.getNodeKey() == startNode.getNodeKey()) {
            // the begin node is always null
            newHash = 0;
        } else if (node.getNodeKey() == startNode.getParentKey()) {
            // the parent node is just removed
            newHash = node.getHash() - hashToRemove * PRIME;
            hashToRemove = node.getHash();
            setRemoveDescendants(startNode);
        } else {
            // the ancestors are all touched regarding the modification
            newHash = node.getHash() - hashToRemove * PRIME;
            newHash = newHash + hashToAdd * PRIME;
            hashToRemove = node.getHash();
            setRemoveDescendants(startNode);
        }
        node.setHash(newHash);
        hashToAdd = newHash;
    } while (moveTo(mNodeReader.getCurrentNode().getParentKey()).hasMoved());
    mNodeReader.setCurrentNode(startNode);
}
Also used : ImmutableNode(org.sirix.node.interfaces.immutable.ImmutableNode) TextNode(org.sirix.node.TextNode) CommentNode(org.sirix.node.CommentNode) PINode(org.sirix.node.PINode) Node(org.sirix.node.interfaces.Node) ValueNode(org.sirix.node.interfaces.ValueNode) AttributeNode(org.sirix.node.AttributeNode) ImmutableNode(org.sirix.node.interfaces.immutable.ImmutableNode) StructNode(org.sirix.node.interfaces.StructNode) ElementNode(org.sirix.node.ElementNode) NamespaceNode(org.sirix.node.NamespaceNode) NameNode(org.sirix.node.interfaces.NameNode) UnorderedKeyValuePage(org.sirix.page.UnorderedKeyValuePage)

Example 19 with Node

use of org.sirix.node.interfaces.Node in project sirix by sirixdb.

the class XdmNodeWriterTrxImpl method moveSubtreeToRightSibling.

@Override
public XdmNodeWriteTrx moveSubtreeToRightSibling(@Nonnegative final long fromKey) throws SirixException {
    acquireLock();
    try {
        if (fromKey < 0 || fromKey > getMaxNodeKey()) {
            throw new IllegalArgumentException("Argument must be a valid node key!");
        }
        if (fromKey == getCurrentNode().getNodeKey()) {
            throw new IllegalArgumentException("Can't move itself to first child of itself!");
        }
        // Save: Every node in the "usual" node page is of type Node.
        @SuppressWarnings("unchecked") final Optional<? extends Node> node = (Optional<? extends Node>) getPageTransaction().getRecord(fromKey, PageKind.RECORDPAGE, -1);
        if (!node.isPresent()) {
            throw new IllegalStateException("Node to move must exist!");
        }
        final Node nodeToMove = node.get();
        if (nodeToMove instanceof StructNode && getCurrentNode() instanceof StructNode) {
            final StructNode toMove = (StructNode) nodeToMove;
            checkAncestors(toMove);
            checkAccessAndCommit();
            final StructNode nodeAnchor = (StructNode) getCurrentNode();
            if (nodeAnchor.getRightSiblingKey() != nodeToMove.getNodeKey()) {
                final long parentKey = toMove.getParentKey();
                // Adapt hashes.
                adaptHashesForMove(toMove);
                // Adapt pointers and merge sibling text nodes.
                adaptForMove(toMove, nodeAnchor, InsertPos.ASRIGHTSIBLING);
                mNodeReader.moveTo(toMove.getNodeKey());
                adaptHashesWithAdd();
                // Adapt path summary.
                if (mBuildPathSummary && toMove instanceof NameNode) {
                    final NameNode moved = (NameNode) toMove;
                    final OPType type = moved.getParentKey() == parentKey ? OPType.MOVEDSAMELEVEL : OPType.MOVED;
                    mPathSummaryWriter.adaptPathForChangedNode(moved, getName(), moved.getURIKey(), moved.getPrefixKey(), moved.getLocalNameKey(), type);
                }
                // Recompute DeweyIDs if they are used.
                if (mDeweyIDsStored) {
                    computeNewDeweyIDs();
                }
            }
            return this;
        } else {
            throw new SirixUsageException("Move is not allowed if moved node is not an ElementNode or TextNode and the node isn't inserted at an ElementNode or TextNode!");
        }
    } finally {
        unLock();
    }
}
Also used : NameNode(org.sirix.node.interfaces.NameNode) Optional(java.util.Optional) OPType(org.sirix.index.path.summary.PathSummaryWriter.OPType) TextNode(org.sirix.node.TextNode) CommentNode(org.sirix.node.CommentNode) PINode(org.sirix.node.PINode) Node(org.sirix.node.interfaces.Node) ValueNode(org.sirix.node.interfaces.ValueNode) AttributeNode(org.sirix.node.AttributeNode) ImmutableNode(org.sirix.node.interfaces.immutable.ImmutableNode) StructNode(org.sirix.node.interfaces.StructNode) ElementNode(org.sirix.node.ElementNode) NamespaceNode(org.sirix.node.NamespaceNode) NameNode(org.sirix.node.interfaces.NameNode) SirixUsageException(org.sirix.exception.SirixUsageException) StructNode(org.sirix.node.interfaces.StructNode)

Example 20 with Node

use of org.sirix.node.interfaces.Node in project sirix by sirixdb.

the class XdmResourceManager method beginNodeReadTrx.

@Override
public synchronized XdmNodeReadTrx beginNodeReadTrx(@Nonnegative final int revisionKey) {
    assertAccess(revisionKey);
    // Make sure not to exceed available number of read transactions.
    try {
        if (!mReadSemaphore.tryAcquire(20, TimeUnit.SECONDS)) {
            throw new SirixUsageException("No read transactions available, please close at least one read transaction at first!");
        }
    } catch (final InterruptedException e) {
        throw new SirixThreadedException(e);
    }
    final PageReadTrx pageReadTrx = beginPageReadTrx(revisionKey);
    final Node documentNode = getDocumentNode(pageReadTrx);
    // Create new reader.
    final XdmNodeReadTrx reader = new XdmNodeReadTrxImpl(this, mNodeTrxIDCounter.incrementAndGet(), pageReadTrx, documentNode);
    // Remember reader for debugging and safe close.
    if (mNodeReaderMap.put(reader.getId(), reader) != null) {
        throw new SirixUsageException("ID generation is bogus because of duplicate ID.");
    }
    return reader;
}
Also used : SirixThreadedException(org.sirix.exception.SirixThreadedException) XdmNodeReadTrx(org.sirix.api.XdmNodeReadTrx) Node(org.sirix.node.interfaces.Node) SirixUsageException(org.sirix.exception.SirixUsageException) PageReadTrx(org.sirix.api.PageReadTrx)

Aggregations

Node (org.sirix.node.interfaces.Node)22 StructNode (org.sirix.node.interfaces.StructNode)12 ImmutableNode (org.sirix.node.interfaces.immutable.ImmutableNode)12 AttributeNode (org.sirix.node.AttributeNode)11 CommentNode (org.sirix.node.CommentNode)11 ElementNode (org.sirix.node.ElementNode)11 NamespaceNode (org.sirix.node.NamespaceNode)11 PINode (org.sirix.node.PINode)11 TextNode (org.sirix.node.TextNode)11 NameNode (org.sirix.node.interfaces.NameNode)11 ValueNode (org.sirix.node.interfaces.ValueNode)11 UnorderedKeyValuePage (org.sirix.page.UnorderedKeyValuePage)11 SirixUsageException (org.sirix.exception.SirixUsageException)6 Optional (java.util.Optional)4 SirixDeweyID (org.sirix.node.SirixDeweyID)4 QNm (org.brackit.xquery.atomic.QNm)3 Record (org.sirix.node.interfaces.Record)3 SirixThreadedException (org.sirix.exception.SirixThreadedException)2 DocumentRootNode (org.sirix.node.DocumentRootNode)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1