Search in sources :

Example 11 with UnorderedKeyValuePage

use of org.sirix.page.UnorderedKeyValuePage 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 12 with UnorderedKeyValuePage

use of org.sirix.page.UnorderedKeyValuePage in project sirix by sirixdb.

the class XdmNodeWriterTrxImpl method rollingAdd.

/**
 * Adapting the structure with a rolling hash for all ancestors only with insert.
 *
 * @throws SirixIOException if an I/O error occurs
 */
private void rollingAdd() throws SirixIOException {
    // start with hash to add
    final ImmutableNode startNode = mNodeReader.getCurrentNode();
    final long oldDescendantCount = mNodeReader.getStructuralNode().getDescendantCount();
    final long descendantCount = oldDescendantCount == 0 ? 1 : oldDescendantCount + 1;
    long hashToAdd = startNode.getHash() == 0 ? mHash.hashLong(startNode.hashCode()).asLong() : startNode.getHash();
    long newHash = 0;
    long possibleOldHash = 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()) {
            // at the beginning, take the hashcode of the node only
            newHash = hashToAdd;
        } else if (node.getNodeKey() == startNode.getParentKey()) {
            // at the parent level, just add the node
            possibleOldHash = node.getHash();
            newHash = possibleOldHash + hashToAdd * PRIME;
            hashToAdd = newHash;
            setAddDescendants(startNode, node, descendantCount);
        } else {
            // at the rest, remove the existing old key for this element
            // and add the new one
            newHash = node.getHash() - possibleOldHash * PRIME;
            newHash = newHash + hashToAdd * PRIME;
            hashToAdd = newHash;
            possibleOldHash = node.getHash();
            setAddDescendants(startNode, node, descendantCount);
        }
        node.setHash(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 13 with UnorderedKeyValuePage

use of org.sirix.page.UnorderedKeyValuePage in project sirix by sirixdb.

the class XdmNodeWriterTrxImpl method insertAttribute.

@Override
public XdmNodeWriteTrx insertAttribute(final QNm name, final String value, final Movement move) throws SirixException {
    checkNotNull(value);
    if (!XMLToken.isValidQName(checkNotNull(name))) {
        throw new IllegalArgumentException("The QName is not valid!");
    }
    acquireLock();
    try {
        if (getCurrentNode().getKind() == Kind.ELEMENT) {
            checkAccessAndCommit();
            /*
         * Update value in case of the same attribute name is found but the attribute to insert has
         * a different value (otherwise an exception is thrown because of a duplicate attribute
         * which would otherwise be inserted!).
         */
            final ElementNode element = (ElementNode) getCurrentNode();
            final Optional<Long> attKey = element.getAttributeKeyByName(name);
            if (attKey.isPresent()) {
                moveTo(attKey.get());
                final QNm qName = getName();
                if (name.equals(qName)) {
                    if (getValue().equals(value)) {
                        throw new SirixUsageException("Duplicate attribute!");
                    } else {
                        setValue(value);
                    }
                }
                moveToParent();
            }
            // Get the path node key.
            final long pathNodeKey = mNodeReader.mResourceManager.getResourceConfig().mPathSummary ? mPathSummaryWriter.getPathNodeKey(name, Kind.ATTRIBUTE) : 0;
            final byte[] attValue = getBytes(value);
            final Optional<SirixDeweyID> id = newAttributeID();
            final long elementKey = getCurrentNode().getNodeKey();
            final AttributeNode node = mNodeFactory.createAttributeNode(elementKey, name, attValue, pathNodeKey, id);
            final Node parentNode = (Node) getPageTransaction().prepareEntryForModification(node.getParentKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
            ((ElementNode) parentNode).insertAttribute(node.getNodeKey(), node.getPrefixKey() + node.getLocalNameKey());
            mNodeReader.setCurrentNode(node);
            adaptHashesWithAdd();
            // Index text value.
            mIndexController.notifyChange(ChangeType.INSERT, node, pathNodeKey);
            if (move == Movement.TOPARENT) {
                moveToParent();
            }
            return this;
        } else {
            throw new SirixUsageException("Insert is not allowed if current node is not an ElementNode!");
        }
    } finally {
        unLock();
    }
}
Also used : AttributeNode(org.sirix.node.AttributeNode) 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) SirixUsageException(org.sirix.exception.SirixUsageException) SirixDeweyID(org.sirix.node.SirixDeweyID) QNm(org.brackit.xquery.atomic.QNm)

Example 14 with UnorderedKeyValuePage

use of org.sirix.page.UnorderedKeyValuePage in project sirix by sirixdb.

the class XdmNodeWriterTrxImpl method insertNamespace.

@Override
public XdmNodeWriteTrx insertNamespace(final QNm name, final Movement move) throws SirixException {
    if (!XMLToken.isValidQName(checkNotNull(name))) {
        throw new IllegalArgumentException("The QName is not valid!");
    }
    acquireLock();
    try {
        if (getCurrentNode().getKind() == Kind.ELEMENT) {
            checkAccessAndCommit();
            for (int i = 0, namespCount = ((ElementNode) getCurrentNode()).getNamespaceCount(); i < namespCount; i++) {
                moveToNamespace(i);
                final QNm qName = getName();
                if (name.getPrefix().equals(qName.getPrefix())) {
                    throw new SirixUsageException("Duplicate namespace!");
                }
                moveToParent();
            }
            final long pathNodeKey = mBuildPathSummary ? mPathSummaryWriter.getPathNodeKey(name, Kind.NAMESPACE) : 0;
            final long elementKey = getCurrentNode().getNodeKey();
            final Optional<SirixDeweyID> id = newNamespaceID();
            final NamespaceNode node = mNodeFactory.createNamespaceNode(elementKey, name, pathNodeKey, id);
            final Node parentNode = (Node) getPageTransaction().prepareEntryForModification(node.getParentKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
            ((ElementNode) parentNode).insertNamespace(node.getNodeKey());
            mNodeReader.setCurrentNode(node);
            adaptHashesWithAdd();
            if (move == Movement.TOPARENT) {
                moveToParent();
            }
            return this;
        } else {
            throw new SirixUsageException("Insert is not allowed if current node is not an ElementNode!");
        }
    } finally {
        unLock();
    }
}
Also used : QNm(org.brackit.xquery.atomic.QNm) 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) NamespaceNode(org.sirix.node.NamespaceNode) UnorderedKeyValuePage(org.sirix.page.UnorderedKeyValuePage) ElementNode(org.sirix.node.ElementNode) SirixUsageException(org.sirix.exception.SirixUsageException) SirixDeweyID(org.sirix.node.SirixDeweyID)

Example 15 with UnorderedKeyValuePage

use of org.sirix.page.UnorderedKeyValuePage in project sirix by sirixdb.

the class XdmNodeWriterTrxImpl method remove.

@Override
public XdmNodeWriteTrx remove() throws SirixException {
    checkAccessAndCommit();
    acquireLock();
    try {
        if (getCurrentNode().getKind() == Kind.DOCUMENT) {
            throw new SirixUsageException("Document root can not be removed.");
        } else if (getCurrentNode() instanceof StructNode) {
            final StructNode node = (StructNode) mNodeReader.getCurrentNode();
            // Remove subtree.
            for (final Axis axis = new PostOrderAxis(this); axis.hasNext(); ) {
                axis.next();
                // Remove name.
                removeName();
                // Remove namespaces and attributes.
                removeNonStructural();
                // Remove text value.
                removeValue();
                // Then remove node.
                getPageTransaction().removeEntry(getCurrentNode().getNodeKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
            }
            // Adapt hashes and neighbour nodes as well as the name from the
            // NamePage mapping if it's not a text node.
            mNodeReader.setCurrentNode(node);
            adaptHashesWithRemove();
            adaptForRemove(node, PageKind.RECORDPAGE);
            mNodeReader.setCurrentNode(node);
            // Remove the name of subtree-root.
            if (node.getKind() == Kind.ELEMENT) {
                removeName();
            }
            // of text merges.
            if (mNodeReader.hasRightSibling() && moveTo(node.getRightSiblingKey()).hasMoved()) {
            } else if (node.hasLeftSibling()) {
                moveTo(node.getLeftSiblingKey());
            } else {
                moveTo(node.getParentKey());
            }
        } else if (getCurrentNode().getKind() == Kind.ATTRIBUTE) {
            final ImmutableNode node = mNodeReader.getCurrentNode();
            final ElementNode parent = (ElementNode) getPageTransaction().prepareEntryForModification(node.getParentKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
            parent.removeAttribute(node.getNodeKey());
            adaptHashesWithRemove();
            getPageTransaction().removeEntry(node.getNodeKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
            removeName();
            mIndexController.notifyChange(ChangeType.DELETE, getNode(), parent.getPathNodeKey());
            moveToParent();
        } else if (getCurrentNode().getKind() == Kind.NAMESPACE) {
            final ImmutableNode node = mNodeReader.getCurrentNode();
            final ElementNode parent = (ElementNode) getPageTransaction().prepareEntryForModification(node.getParentKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
            parent.removeNamespace(node.getNodeKey());
            adaptHashesWithRemove();
            getPageTransaction().removeEntry(node.getNodeKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
            removeName();
            moveToParent();
        }
        return this;
    } finally {
        unLock();
    }
}
Also used : PostOrderAxis(org.sirix.axis.PostOrderAxis) ImmutableNode(org.sirix.node.interfaces.immutable.ImmutableNode) UnorderedKeyValuePage(org.sirix.page.UnorderedKeyValuePage) SirixUsageException(org.sirix.exception.SirixUsageException) ElementNode(org.sirix.node.ElementNode) Axis(org.sirix.api.Axis) LevelOrderAxis(org.sirix.axis.LevelOrderAxis) PostOrderAxis(org.sirix.axis.PostOrderAxis) DescendantAxis(org.sirix.axis.DescendantAxis) StructNode(org.sirix.node.interfaces.StructNode)

Aggregations

UnorderedKeyValuePage (org.sirix.page.UnorderedKeyValuePage)42 StructNode (org.sirix.node.interfaces.StructNode)14 ElementNode (org.sirix.node.ElementNode)12 NameNode (org.sirix.node.interfaces.NameNode)11 Node (org.sirix.node.interfaces.Node)11 AttributeNode (org.sirix.node.AttributeNode)9 CommentNode (org.sirix.node.CommentNode)9 NamespaceNode (org.sirix.node.NamespaceNode)9 PINode (org.sirix.node.PINode)9 TextNode (org.sirix.node.TextNode)9 NodeDelegate (org.sirix.node.delegates.NodeDelegate)9 ValueNode (org.sirix.node.interfaces.ValueNode)9 ImmutableNode (org.sirix.node.interfaces.immutable.ImmutableNode)9 Record (org.sirix.node.interfaces.Record)8 NameNodeDelegate (org.sirix.node.delegates.NameNodeDelegate)7 StructNodeDelegate (org.sirix.node.delegates.StructNodeDelegate)7 ValNodeDelegate (org.sirix.node.delegates.ValNodeDelegate)7 Axis (org.sirix.api.Axis)6 DescendantAxis (org.sirix.axis.DescendantAxis)6 LevelOrderAxis (org.sirix.axis.LevelOrderAxis)6