Search in sources :

Example 1 with UnorderedKeyValuePage

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

the class PathSummaryWriter method adaptForInsert.

/**
 * Adapting everything for insert operations.
 *
 * @param newNode pointer of the new node to be inserted
 * @param insertPos determines the position where to insert
 * @param pageKind kind of subtree root page
 * @throws SirixIOException if anything weird happens
 */
private void adaptForInsert(final Node newNode, final InsertPos insertPos, final PageKind pageKind) throws SirixIOException {
    assert newNode != null;
    assert insertPos != null;
    assert pageKind != null;
    if (newNode instanceof StructNode) {
        final StructNode strucNode = (StructNode) newNode;
        final StructNode parent = (StructNode) mPageWriteTrx.prepareEntryForModification(newNode.getParentKey(), pageKind, 0, Optional.<UnorderedKeyValuePage>empty());
        parent.incrementChildCount();
        if (insertPos == InsertPos.ASFIRSTCHILD) {
            parent.setFirstChildKey(newNode.getNodeKey());
        }
        if (strucNode.hasRightSibling()) {
            final StructNode rightSiblingNode = (StructNode) mPageWriteTrx.prepareEntryForModification(strucNode.getRightSiblingKey(), pageKind, 0, Optional.<UnorderedKeyValuePage>empty());
            rightSiblingNode.setLeftSiblingKey(newNode.getNodeKey());
        }
        if (strucNode.hasLeftSibling()) {
            final StructNode leftSiblingNode = (StructNode) mPageWriteTrx.prepareEntryForModification(strucNode.getLeftSiblingKey(), pageKind, 0, Optional.<UnorderedKeyValuePage>empty());
            leftSiblingNode.setRightSiblingKey(newNode.getNodeKey());
        }
    }
}
Also used : UnorderedKeyValuePage(org.sirix.page.UnorderedKeyValuePage) StructNode(org.sirix.node.interfaces.StructNode)

Example 2 with UnorderedKeyValuePage

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

the class PathSummaryWriter method adaptPathForChangedNode.

/**
 * Adapt path summary either for moves or {@code setQName(QName)}.
 *
 * @param node the node for which the path node needs to be adapted
 * @param name the new {@link QName} in case of a new one is set, the old {@link QName} otherwise
 * @param nameKey nameKey of the new node
 * @param uriKey uriKey of the new node
 * @throws SirixException if a Sirix operation fails
 * @throws NullPointerException if {@code pNode} or {@code pQName} is null
 */
public void adaptPathForChangedNode(final ImmutableNameNode node, final QNm name, final int uriKey, final int prefixKey, final int localNameKey, final OPType type) throws SirixException {
    // Possibly either reset a path node or decrement its reference counter
    // and search for the new path node or insert it.
    movePathSummary();
    final long oldPathNodeKey = mPathSummaryReader.getNodeKey();
    // reference-counter would be 0).
    if (type == OPType.SETNAME && mPathSummaryReader.getReferences() == 1) {
        moveSummaryGetLevel(node);
        // Search for new path entry.
        final Axis axis = new FilterAxis(new ChildAxis(mPathSummaryReader), new NameFilter(mPathSummaryReader, Utils.buildName(name)), new PathKindFilter(mPathSummaryReader, node.getKind()));
        if (axis.hasNext()) {
            axis.next();
            // Found node.
            processFoundPathNode(oldPathNodeKey, mPathSummaryReader.getNodeKey(), node.getNodeKey(), uriKey, prefixKey, localNameKey, Remove.YES, type);
        } else {
            if (mPathSummaryReader.getKind() != Kind.DOCUMENT) {
                /* The path summary just needs to be updated for the new renamed node. */
                mPathSummaryReader.moveTo(oldPathNodeKey);
                final PathNode pathNode = (PathNode) mPageWriteTrx.prepareEntryForModification(mPathSummaryReader.getNodeKey(), PageKind.PATHSUMMARYPAGE, 0, Optional.<UnorderedKeyValuePage>empty());
                pathNode.setPrefixKey(prefixKey);
                pathNode.setLocalNameKey(localNameKey);
                pathNode.setURIKey(uriKey);
            }
        }
    } else {
        int level = moveSummaryGetLevel(node);
        // TODO: Johannes: Optimize? (either use this or use the name-mapping,
        // depending on the number of child nodes or nodes with a certain name).
        // Search for new path entry.
        final Axis axis = new FilterAxis(new ChildAxis(mPathSummaryReader), new NameFilter(mPathSummaryReader, Utils.buildName(name)), new PathKindFilter(mPathSummaryReader, node.getKind()));
        if (type == OPType.MOVEDSAMELEVEL || axis.hasNext()) {
            if (type != OPType.MOVEDSAMELEVEL) {
                axis.next();
            }
            // Found node.
            processFoundPathNode(oldPathNodeKey, mPathSummaryReader.getNodeKey(), node.getNodeKey(), uriKey, prefixKey, localNameKey, Remove.NO, type);
        } else {
            long nodeKey = mPathSummaryReader.getNodeKey();
            // Decrement reference count or remove path summary node.
            mNodeRtx.moveTo(node.getNodeKey());
            for (final Axis descendants = new PostOrderAxis(mNodeRtx, IncludeSelf.YES); descendants.hasNext(); ) {
                descendants.next();
                deleteOrDecrement();
                if (mNodeRtx.getKind() == Kind.ELEMENT) {
                    final ElementNode element = (ElementNode) mNodeRtx.getCurrentNode();
                    // Namespaces.
                    for (int i = 0, nsps = element.getNamespaceCount(); i < nsps; i++) {
                        mNodeRtx.moveToNamespace(i);
                        deleteOrDecrement();
                        mNodeRtx.moveToParent();
                    }
                    // Attributes.
                    for (int i = 0, atts = element.getAttributeCount(); i < atts; i++) {
                        mNodeRtx.moveToAttribute(i);
                        deleteOrDecrement();
                        mNodeRtx.moveToParent();
                    }
                }
            }
            mPathSummaryReader.moveTo(nodeKey);
            // Not found => create new path nodes for the whole subtree.
            boolean firstRun = true;
            for (final Axis descendants = new DescendantAxis(mNodeRtx, IncludeSelf.YES); descendants.hasNext(); ) {
                descendants.next();
                if (mNodeRtx.getKind() == Kind.ELEMENT) {
                    // Path Summary : New mapping.
                    if (firstRun) {
                        insertPathAsFirstChild(name, Kind.ELEMENT, ++level);
                        nodeKey = mPathSummaryReader.getNodeKey();
                    } else {
                        insertPathAsFirstChild(mNodeRtx.getName(), Kind.ELEMENT, ++level);
                    }
                    resetPathNodeKey(mNodeRtx.getNodeKey());
                    // Namespaces.
                    for (int i = 0, nsps = mNodeRtx.getNamespaceCount(); i < nsps; i++) {
                        mNodeRtx.moveToNamespace(i);
                        // Path Summary : New mapping.
                        insertPathAsFirstChild(mNodeRtx.getName(), Kind.NAMESPACE, level + 1);
                        resetPathNodeKey(mNodeRtx.getNodeKey());
                        mNodeRtx.moveToParent();
                        mPathSummaryReader.moveToParent();
                    }
                    // Attributes.
                    for (int i = 0, atts = mNodeRtx.getAttributeCount(); i < atts; i++) {
                        mNodeRtx.moveToAttribute(i);
                        // Path Summary : New mapping.
                        insertPathAsFirstChild(mNodeRtx.getName(), Kind.ATTRIBUTE, level + 1);
                        resetPathNodeKey(mNodeRtx.getNodeKey());
                        mNodeRtx.moveToParent();
                        mPathSummaryReader.moveToParent();
                    }
                    if (firstRun) {
                        firstRun = false;
                    } else {
                        mPathSummaryReader.moveToParent();
                        level--;
                    }
                }
            }
            // /*
            // * Remove path nodes with zero node references.
            // *
            // * (TODO: Johannes: might not be necessary, as it's likely that future
            // * updates will reinsert the path).
            // */
            // for (final long key : nodesToDelete) {
            // if (mPathSummaryReader.moveTo(key).hasMoved()) {
            // removePathSummaryNode(Remove.NO);
            // }
            // }
            mPathSummaryReader.moveTo(nodeKey);
        }
    }
}
Also used : ChildAxis(org.sirix.axis.ChildAxis) PostOrderAxis(org.sirix.axis.PostOrderAxis) UnorderedKeyValuePage(org.sirix.page.UnorderedKeyValuePage) ElementNode(org.sirix.node.ElementNode) FilterAxis(org.sirix.axis.filter.FilterAxis) NameFilter(org.sirix.axis.filter.NameFilter) DescendantAxis(org.sirix.axis.DescendantAxis) Axis(org.sirix.api.Axis) ChildAxis(org.sirix.axis.ChildAxis) PostOrderAxis(org.sirix.axis.PostOrderAxis) FilterAxis(org.sirix.axis.filter.FilterAxis) DescendantAxis(org.sirix.axis.DescendantAxis) LevelOrderAxis(org.sirix.axis.LevelOrderAxis) PathKindFilter(org.sirix.axis.filter.PathKindFilter)

Example 3 with UnorderedKeyValuePage

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

the class PathSummaryWriter method removePathSummaryNode.

/**
 * Remove a path summary node with the specified PCR.
 *
 * @throws SirixException if Sirix fails to remove the path node
 */
private void removePathSummaryNode(final Remove remove) throws SirixException {
    // Remove all descendant nodes.
    if (remove == Remove.YES) {
        for (final Axis axis = new DescendantAxis(mPathSummaryReader); axis.hasNext(); ) {
            axis.next();
            mPathSummaryReader.removeMapping(mPathSummaryReader.getNodeKey());
            mPathSummaryReader.removeQNameMapping(mPathSummaryReader.getPathNode(), mPathSummaryReader.getName());
            mPageWriteTrx.removeEntry(mPathSummaryReader.getNodeKey(), PageKind.PATHSUMMARYPAGE, 0, Optional.<UnorderedKeyValuePage>empty());
        }
    }
    // Adapt left sibling node if there is one.
    if (mPathSummaryReader.hasLeftSibling()) {
        final StructNode leftSibling = (StructNode) mPageWriteTrx.prepareEntryForModification(mPathSummaryReader.getLeftSiblingKey(), PageKind.PATHSUMMARYPAGE, 0, Optional.<UnorderedKeyValuePage>empty());
        leftSibling.setRightSiblingKey(mPathSummaryReader.getRightSiblingKey());
    }
    // Adapt right sibling node if there is one.
    if (mPathSummaryReader.hasRightSibling()) {
        final StructNode rightSibling = (StructNode) mPageWriteTrx.prepareEntryForModification(mPathSummaryReader.getRightSiblingKey(), PageKind.PATHSUMMARYPAGE, 0, Optional.<UnorderedKeyValuePage>empty());
        rightSibling.setLeftSiblingKey(mPathSummaryReader.getLeftSiblingKey());
    }
    // Adapt parent. If node has no left sibling it is a first child.
    StructNode parent = (StructNode) mPageWriteTrx.prepareEntryForModification(mPathSummaryReader.getParentKey(), PageKind.PATHSUMMARYPAGE, 0, Optional.<UnorderedKeyValuePage>empty());
    if (!mPathSummaryReader.hasLeftSibling()) {
        parent.setFirstChildKey(mPathSummaryReader.getRightSiblingKey());
    }
    parent.decrementChildCount();
    // Remove node.
    mPathSummaryReader.removeMapping(mPathSummaryReader.getNodeKey());
    mPathSummaryReader.removeQNameMapping(mPathSummaryReader.getPathNode(), mPathSummaryReader.getName());
    mPageWriteTrx.removeEntry(mPathSummaryReader.getNodeKey(), PageKind.PATHSUMMARYPAGE, 0, Optional.<UnorderedKeyValuePage>empty());
}
Also used : UnorderedKeyValuePage(org.sirix.page.UnorderedKeyValuePage) DescendantAxis(org.sirix.axis.DescendantAxis) Axis(org.sirix.api.Axis) ChildAxis(org.sirix.axis.ChildAxis) PostOrderAxis(org.sirix.axis.PostOrderAxis) FilterAxis(org.sirix.axis.filter.FilterAxis) DescendantAxis(org.sirix.axis.DescendantAxis) LevelOrderAxis(org.sirix.axis.LevelOrderAxis) StructNode(org.sirix.node.interfaces.StructNode)

Example 4 with UnorderedKeyValuePage

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

the class AVLTreeWriter method index.

/**
 * Checks if the specified token is already indexed; if yes, returns its reference. Otherwise,
 * creates a new index entry and returns a reference of the indexed token.
 *
 * @param key token to be indexed
 * @param value node key references
 * @param move determines if AVLNode cursor must be moved to document root/root node or not
 * @return indexed node key references
 * @throws SirixIOException if an I/O error occurs
 */
@SuppressWarnings("unchecked")
public V index(final K key, final V value, final MoveCursor move) throws SirixIOException {
    if (move == MoveCursor.TO_DOCUMENT_ROOT) {
        moveToDocumentRoot();
    }
    final RevisionRootPage root = mPageWriteTrx.getActualRevisionRootPage();
    if (mAVLTreeReader.getAVLNode() == null && ((DocumentRootNode) getNode()).getFirstChildKey() == Fixed.NULL_NODE_KEY.getStandardProperty()) {
        // Index is empty.. create root node.
        final long nodeKey = getNewNodeKey(root);
        final AVLNode<K, V> treeRoot = (AVLNode<K, V>) mPageWriteTrx.createEntry(nodeKey, new AVLNode<>(key, value, new NodeDelegate(nodeKey, Fixed.DOCUMENT_NODE_KEY.getStandardProperty(), 0, 0, Optional.<SirixDeweyID>empty())), mAVLTreeReader.mPageKind, mAVLTreeReader.mIndex, Optional.<UnorderedKeyValuePage>empty());
        final DocumentRootNode document = (DocumentRootNode) mPageWriteTrx.prepareEntryForModification(Fixed.DOCUMENT_NODE_KEY.getStandardProperty(), mAVLTreeReader.mPageKind, mAVLTreeReader.mIndex, Optional.<UnorderedKeyValuePage>empty());
        document.setFirstChildKey(treeRoot.getNodeKey());
        document.incrementChildCount();
        document.incrementDescendantCount();
        return value;
    }
    if (move == MoveCursor.TO_DOCUMENT_ROOT || mAVLTreeReader.getAVLNode() == null) {
        moveToDocumentRoot();
        moveToFirstChild();
    }
    AVLNode<K, V> node = mAVLTreeReader.getAVLNode();
    while (true) {
        final int c = key.compareTo(node.getKey());
        if (c == 0) {
            if (!value.equals(node.getValue())) {
                final AVLNode<K, V> avlNode = (AVLNode<K, V>) mPageWriteTrx.prepareEntryForModification(node.getNodeKey(), mAVLTreeReader.mPageKind, mAVLTreeReader.mIndex, Optional.<UnorderedKeyValuePage>empty());
                avlNode.setValue(value);
            }
            return node.getValue();
        }
        final boolean moved = c < 0 ? moveToFirstChild().hasMoved() : moveToLastChild().hasMoved();
        if (moved) {
            node = mAVLTreeReader.getAVLNode();
            continue;
        }
        final long nodeKey = getNewNodeKey(root);
        final AVLNode<K, V> child = (AVLNode<K, V>) mPageWriteTrx.createEntry(nodeKey, new AVLNode<>(key, value, new NodeDelegate(nodeKey, node.getNodeKey(), 0, 0, Optional.<SirixDeweyID>empty())), mAVLTreeReader.mPageKind, mAVLTreeReader.mIndex, Optional.<UnorderedKeyValuePage>empty());
        node = (AVLNode<K, V>) mPageWriteTrx.prepareEntryForModification(node.getNodeKey(), mAVLTreeReader.mPageKind, mAVLTreeReader.mIndex, Optional.<UnorderedKeyValuePage>empty());
        if (c < 0) {
            node.setLeftChildKey(child.getNodeKey());
            adjust(child);
        } else {
            node.setRightChildKey(child.getNodeKey());
            adjust(child);
        }
        final DocumentRootNode document = (DocumentRootNode) mPageWriteTrx.prepareEntryForModification(Fixed.DOCUMENT_NODE_KEY.getStandardProperty(), mAVLTreeReader.mPageKind, mAVLTreeReader.mIndex, Optional.<UnorderedKeyValuePage>empty());
        document.incrementDescendantCount();
        return value;
    }
}
Also used : DocumentRootNode(org.sirix.node.DocumentRootNode) UnorderedKeyValuePage(org.sirix.page.UnorderedKeyValuePage) SirixDeweyID(org.sirix.node.SirixDeweyID) NodeDelegate(org.sirix.node.delegates.NodeDelegate) RevisionRootPage(org.sirix.page.RevisionRootPage)

Example 5 with UnorderedKeyValuePage

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

the class AVLTreeWriter method rotateRight.

/**
 * Right rotation.
 *
 * @param node node to be rotated
 * @throws SirixIOException if an I/O error occurs
 */
@SuppressWarnings({ "unchecked" })
private void rotateRight(AVLNode<K, V> node) throws SirixIOException {
    moveTo(node.getNodeKey());
    AVLNode<K, V> leftChild = ((AVLTreeReader<K, V>) moveToFirstChild().get()).getAVLNode();
    node = (AVLNode<K, V>) mPageWriteTrx.prepareEntryForModification(node.getNodeKey(), mAVLTreeReader.mPageKind, mAVLTreeReader.mIndex, Optional.<UnorderedKeyValuePage>empty());
    node.setLeftChildKey(leftChild.getRightChildKey());
    if (leftChild.hasRightChild()) {
        final Node leftRightChild = (Node) mPageWriteTrx.prepareEntryForModification(leftChild.getRightChildKey(), mAVLTreeReader.mPageKind, mAVLTreeReader.mIndex, Optional.<UnorderedKeyValuePage>empty());
        leftRightChild.setParentKey(node.getNodeKey());
    }
    leftChild = (AVLNode<K, V>) mPageWriteTrx.prepareEntryForModification(leftChild.getNodeKey(), mAVLTreeReader.mPageKind, mAVLTreeReader.mIndex, Optional.<UnorderedKeyValuePage>empty());
    leftChild.setParentKey(node.getParentKey());
    if (node.getParentKey() == Fixed.DOCUMENT_NODE_KEY.getStandardProperty()) {
        final DocumentRootNode parent = (DocumentRootNode) mPageWriteTrx.prepareEntryForModification(Fixed.DOCUMENT_NODE_KEY.getStandardProperty(), mAVLTreeReader.mPageKind, mAVLTreeReader.mIndex, Optional.<UnorderedKeyValuePage>empty());
        parent.setFirstChildKey(leftChild.getNodeKey());
    } else if (moveTo(node.getParentKey()).hasMoved() && mAVLTreeReader.getAVLNode().getRightChildKey() == node.getNodeKey()) {
        final AVLNode<K, V> parent = (AVLNode<K, V>) mPageWriteTrx.prepareEntryForModification(mAVLTreeReader.getNodeKey(), mAVLTreeReader.mPageKind, mAVLTreeReader.mIndex, Optional.<UnorderedKeyValuePage>empty());
        parent.setRightChildKey(leftChild.getNodeKey());
    } else {
        final AVLNode<K, V> parent = (AVLNode<K, V>) mPageWriteTrx.prepareEntryForModification(mAVLTreeReader.getNodeKey(), mAVLTreeReader.mPageKind, mAVLTreeReader.mIndex, Optional.<UnorderedKeyValuePage>empty());
        parent.setLeftChildKey(leftChild.getNodeKey());
    }
    leftChild = (AVLNode<K, V>) mPageWriteTrx.prepareEntryForModification(leftChild.getNodeKey(), mAVLTreeReader.mPageKind, mAVLTreeReader.mIndex, Optional.<UnorderedKeyValuePage>empty());
    leftChild.setRightChildKey(node.getNodeKey());
    node = (AVLNode<K, V>) mPageWriteTrx.prepareEntryForModification(node.getNodeKey(), mAVLTreeReader.mPageKind, mAVLTreeReader.mIndex, Optional.<UnorderedKeyValuePage>empty());
    node.setParentKey(leftChild.getNodeKey());
}
Also used : DocumentRootNode(org.sirix.node.DocumentRootNode) Node(org.sirix.node.interfaces.Node) DocumentRootNode(org.sirix.node.DocumentRootNode) UnorderedKeyValuePage(org.sirix.page.UnorderedKeyValuePage)

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