Search in sources :

Example 16 with StructNode

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

the class XdmNodeWriterTrxImpl method postorderAdd.

/**
 * Adapting the structure with a rolling hash for all ancestors only with insert.
 *
 * @throws SirixIOException if anything weird happened
 */
private void postorderAdd() throws SirixIOException {
    // start with hash to add
    final ImmutableNode startNode = getCurrentNode();
    // long for adapting the hash of the parent
    long hashCodeForParent = 0;
    // adapting the parent if the current node is no structural one.
    if (!(startNode instanceof StructNode)) {
        final Node node = (Node) getPageTransaction().prepareEntryForModification(mNodeReader.getCurrentNode().getNodeKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
        node.setHash(mHash.hashLong(mNodeReader.getCurrentNode().hashCode()).asLong());
        moveTo(mNodeReader.getCurrentNode().getParentKey());
    }
    // Cursor to root
    StructNode cursorToRoot;
    do {
        cursorToRoot = (StructNode) getPageTransaction().prepareEntryForModification(mNodeReader.getCurrentNode().getNodeKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
        hashCodeForParent = mNodeReader.getCurrentNode().hashCode() + hashCodeForParent * PRIME;
        // Caring about attributes and namespaces if node is an element.
        if (cursorToRoot.getKind() == Kind.ELEMENT) {
            final ElementNode currentElement = (ElementNode) cursorToRoot;
            // setting the attributes and namespaces
            final int attCount = ((ElementNode) cursorToRoot).getAttributeCount();
            for (int i = 0; i < attCount; i++) {
                moveTo(currentElement.getAttributeKey(i));
                hashCodeForParent = mNodeReader.getCurrentNode().hashCode() + hashCodeForParent * PRIME;
            }
            final int nspCount = ((ElementNode) cursorToRoot).getNamespaceCount();
            for (int i = 0; i < nspCount; i++) {
                moveTo(currentElement.getNamespaceKey(i));
                hashCodeForParent = mNodeReader.getCurrentNode().hashCode() + hashCodeForParent * PRIME;
            }
            moveTo(cursorToRoot.getNodeKey());
        }
        // Caring about the children of a node
        if (moveTo(mNodeReader.getStructuralNode().getFirstChildKey()).hasMoved()) {
            do {
                hashCodeForParent = mNodeReader.getCurrentNode().getHash() + hashCodeForParent * PRIME;
            } while (moveTo(mNodeReader.getStructuralNode().getRightSiblingKey()).hasMoved());
            moveTo(mNodeReader.getStructuralNode().getParentKey());
        }
        // setting hash and resetting hash
        cursorToRoot.setHash(hashCodeForParent);
        hashCodeForParent = 0;
    } while (moveTo(cursorToRoot.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) ElementNode(org.sirix.node.ElementNode) StructNode(org.sirix.node.interfaces.StructNode)

Example 17 with StructNode

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

the class XdmNodeWriterTrxImpl method adaptForMove.

/**
 * Adapting everything for move operations.
 *
 * @param fromNode root {@link StructNode} of the subtree to be moved
 * @param toNode the {@link StructNode} which is the anchor of the new subtree
 * @param insertPos determines if it has to be inserted as a first child or a right sibling
 * @throws SirixException if removing a node fails after merging text nodes
 */
private void adaptForMove(final StructNode fromNode, final StructNode toNode, final InsertPos insertPos) throws SirixException {
    assert fromNode != null;
    assert toNode != null;
    assert insertPos != null;
    // Modify nodes where the subtree has been moved from.
    // ==============================================================================
    final StructNode parent = (StructNode) getPageTransaction().prepareEntryForModification(fromNode.getParentKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
    switch(insertPos) {
        case ASRIGHTSIBLING:
            if (fromNode.getParentKey() != toNode.getParentKey()) {
                parent.decrementChildCount();
            }
            break;
        case ASFIRSTCHILD:
            if (fromNode.getParentKey() != toNode.getNodeKey()) {
                parent.decrementChildCount();
            }
            break;
        case ASNONSTRUCTURAL:
            // Do not decrement child count.
            break;
        default:
    }
    // Adapt first child key of former parent.
    if (parent.getFirstChildKey() == fromNode.getNodeKey()) {
        parent.setFirstChildKey(fromNode.getRightSiblingKey());
    }
    // Adapt left sibling key of former right sibling.
    if (fromNode.hasRightSibling()) {
        final StructNode rightSibling = (StructNode) getPageTransaction().prepareEntryForModification(fromNode.getRightSiblingKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
        rightSibling.setLeftSiblingKey(fromNode.getLeftSiblingKey());
    }
    // Adapt right sibling key of former left sibling.
    if (fromNode.hasLeftSibling()) {
        final StructNode leftSibling = (StructNode) getPageTransaction().prepareEntryForModification(fromNode.getLeftSiblingKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
        leftSibling.setRightSiblingKey(fromNode.getRightSiblingKey());
    }
    // Merge text nodes.
    if (fromNode.hasLeftSibling() && fromNode.hasRightSibling()) {
        moveTo(fromNode.getLeftSiblingKey());
        if (getCurrentNode() != null && getCurrentNode().getKind() == Kind.TEXT) {
            final StringBuilder builder = new StringBuilder(getValue());
            moveTo(fromNode.getRightSiblingKey());
            if (getCurrentNode() != null && getCurrentNode().getKind() == Kind.TEXT) {
                builder.append(getValue());
                if (fromNode.getRightSiblingKey() == toNode.getNodeKey()) {
                    moveTo(fromNode.getLeftSiblingKey());
                    if (mNodeReader.getStructuralNode().hasLeftSibling()) {
                        final StructNode leftSibling = (StructNode) getPageTransaction().prepareEntryForModification(mNodeReader.getStructuralNode().getLeftSiblingKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
                        leftSibling.setRightSiblingKey(fromNode.getRightSiblingKey());
                    }
                    final long leftSiblingKey = mNodeReader.getStructuralNode().hasLeftSibling() == true ? mNodeReader.getStructuralNode().getLeftSiblingKey() : getCurrentNode().getNodeKey();
                    moveTo(fromNode.getRightSiblingKey());
                    final StructNode rightSibling = (StructNode) getPageTransaction().prepareEntryForModification(getCurrentNode().getNodeKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
                    rightSibling.setLeftSiblingKey(leftSiblingKey);
                    moveTo(fromNode.getLeftSiblingKey());
                    remove();
                    moveTo(fromNode.getRightSiblingKey());
                } else {
                    if (mNodeReader.getStructuralNode().hasRightSibling()) {
                        final StructNode rightSibling = (StructNode) getPageTransaction().prepareEntryForModification(mNodeReader.getStructuralNode().getRightSiblingKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
                        rightSibling.setLeftSiblingKey(fromNode.getLeftSiblingKey());
                    }
                    final long rightSiblingKey = mNodeReader.getStructuralNode().hasRightSibling() == true ? mNodeReader.getStructuralNode().getRightSiblingKey() : getCurrentNode().getNodeKey();
                    moveTo(fromNode.getLeftSiblingKey());
                    final StructNode leftSibling = (StructNode) getPageTransaction().prepareEntryForModification(getCurrentNode().getNodeKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
                    leftSibling.setRightSiblingKey(rightSiblingKey);
                    moveTo(fromNode.getRightSiblingKey());
                    remove();
                    moveTo(fromNode.getLeftSiblingKey());
                }
                setValue(builder.toString());
            }
        }
    }
    // Modify nodes where the subtree has been moved to.
    // ==============================================================================
    insertPos.processMove(fromNode, toNode, this);
}
Also used : UnorderedKeyValuePage(org.sirix.page.UnorderedKeyValuePage) StructNode(org.sirix.node.interfaces.StructNode)

Example 18 with StructNode

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

the class XdmNodeWriterTrxImpl method insertTextAsRightSibling.

@Override
public XdmNodeWriteTrx insertTextAsRightSibling(final String value) throws SirixException {
    checkNotNull(value);
    acquireLock();
    try {
        if (getCurrentNode() instanceof StructNode && getCurrentNode().getKind() != Kind.DOCUMENT && !value.isEmpty()) {
            checkAccessAndCommit();
            final long parentKey = getCurrentNode().getParentKey();
            final long leftSibKey = getCurrentNode().getNodeKey();
            final long rightSibKey = ((StructNode) getCurrentNode()).getRightSiblingKey();
            // Update value in case of adjacent text nodes.
            final StringBuilder builder = new StringBuilder();
            if (getCurrentNode().getKind() == Kind.TEXT) {
                builder.append(getValue());
            }
            builder.append(value);
            if (!value.equals(builder.toString())) {
                setValue(builder.toString());
                return this;
            }
            if (hasNode(rightSibKey)) {
                moveTo(rightSibKey);
                if (getCurrentNode().getKind() == Kind.TEXT) {
                    builder.append(getValue());
                }
                if (!value.equals(builder.toString())) {
                    setValue(builder.toString());
                    return this;
                }
            }
            // Insert new text node if no adjacent text nodes are found.
            moveTo(leftSibKey);
            final byte[] textValue = getBytes(builder.toString());
            final Optional<SirixDeweyID> id = newRightSiblingID();
            final TextNode node = mNodeFactory.createTextNode(parentKey, leftSibKey, rightSibKey, textValue, mCompression, id);
            // Adapt local nodes and hashes.
            mNodeReader.setCurrentNode(node);
            adaptForInsert(node, InsertPos.ASRIGHTSIBLING, PageKind.RECORDPAGE);
            mNodeReader.setCurrentNode(node);
            adaptHashesWithAdd();
            // Get the path node key.
            final long pathNodeKey = moveToParent().get().isElement() ? getNameNode().getPathNodeKey() : -1;
            mNodeReader.setCurrentNode(node);
            // Index text value.
            mIndexController.notifyChange(ChangeType.INSERT, node, pathNodeKey);
            return this;
        } else {
            throw new SirixUsageException("Insert is not allowed if current node is not an Element- or Text-node or value is empty!");
        }
    } finally {
        unLock();
    }
}
Also used : TextNode(org.sirix.node.TextNode) SirixDeweyID(org.sirix.node.SirixDeweyID) SirixUsageException(org.sirix.exception.SirixUsageException) StructNode(org.sirix.node.interfaces.StructNode)

Example 19 with StructNode

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

the class XdmNodeWriterTrxImpl method replaceWithTextNode.

/**
 * Replace current node with a {@link TextNode}.
 *
 * @param value text value
 * @return inserted node
 * @throws SirixException if anything fails
 */
private ImmutableNode replaceWithTextNode(final String value) throws SirixException {
    assert value != null;
    final StructNode currentNode = mNodeReader.getStructuralNode();
    long key = currentNode.getNodeKey();
    if (currentNode.hasLeftSibling()) {
        moveToLeftSibling();
        key = insertTextAsRightSibling(value).getNodeKey();
    } else {
        moveToParent();
        key = insertTextAsFirstChild(value).getNodeKey();
        moveTo(key);
    }
    moveTo(currentNode.getNodeKey());
    remove();
    moveTo(key);
    return mNodeReader.getCurrentNode();
}
Also used : StructNode(org.sirix.node.interfaces.StructNode)

Example 20 with StructNode

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

the class XdmNodeWriterTrxImpl method postOrderTraversalHashes.

/**
 * Modifying hashes in a postorder-traversal.
 *
 * @throws SirixIOException if an I/O error occurs
 */
private void postOrderTraversalHashes() throws SirixIOException {
    new PostOrderAxis(this, IncludeSelf.YES).forEach((unused) -> {
        final StructNode node = mNodeReader.getStructuralNode();
        if (node.getKind() == Kind.ELEMENT) {
            final ElementNode element = (ElementNode) node;
            for (int i = 0, nspCount = element.getNamespaceCount(); i < nspCount; i++) {
                moveToNamespace(i);
                addHashAndDescendantCount();
                moveToParent();
            }
            for (int i = 0, attCount = element.getAttributeCount(); i < attCount; i++) {
                moveToAttribute(i);
                addHashAndDescendantCount();
                moveToParent();
            }
        }
        addHashAndDescendantCount();
    });
}
Also used : PostOrderAxis(org.sirix.axis.PostOrderAxis) ElementNode(org.sirix.node.ElementNode) StructNode(org.sirix.node.interfaces.StructNode)

Aggregations

StructNode (org.sirix.node.interfaces.StructNode)41 SirixDeweyID (org.sirix.node.SirixDeweyID)12 SirixUsageException (org.sirix.exception.SirixUsageException)11 ElementNode (org.sirix.node.ElementNode)10 TextNode (org.sirix.node.TextNode)8 ImmutableNode (org.sirix.node.interfaces.immutable.ImmutableNode)8 UnorderedKeyValuePage (org.sirix.page.UnorderedKeyValuePage)8 CommentNode (org.sirix.node.CommentNode)6 PINode (org.sirix.node.PINode)6 AttributeNode (org.sirix.node.AttributeNode)5 Kind (org.sirix.node.Kind)5 NamespaceNode (org.sirix.node.NamespaceNode)5 NameNode (org.sirix.node.interfaces.NameNode)5 Node (org.sirix.node.interfaces.Node)5 ValueNode (org.sirix.node.interfaces.ValueNode)5 PageKind (org.sirix.page.PageKind)5 Optional (java.util.Optional)3 PostOrderAxis (org.sirix.axis.PostOrderAxis)3 Axis (org.sirix.api.Axis)2 DescendantAxis (org.sirix.axis.DescendantAxis)2