Search in sources :

Example 1 with PostOrderAxis

use of org.sirix.axis.PostOrderAxis 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 2 with PostOrderAxis

use of org.sirix.axis.PostOrderAxis in project sirix by sirixdb.

the class MultipleCommitTest method testAttributeRemove.

@Test
public void testAttributeRemove() throws SirixException {
    DocumentCreater.create(holder.getWriter());
    holder.getWriter().commit();
    holder.getWriter().moveToDocumentRoot();
    final AbstractAxis postorderAxis = new PostOrderAxis(holder.getWriter());
    while (postorderAxis.hasNext()) {
        postorderAxis.next();
        if (holder.getWriter().getKind() == Kind.ELEMENT && holder.getWriter().getAttributeCount() > 0) {
            for (int i = 0, attrCount = holder.getWriter().getAttributeCount(); i < attrCount; i++) {
                holder.getWriter().moveToAttribute(i);
                holder.getWriter().remove();
            }
        }
    }
    holder.getWriter().commit();
    holder.getWriter().moveToDocumentRoot();
    int attrTouch = 0;
    final Axis descAxis = new DescendantAxis(holder.getWriter());
    while (descAxis.hasNext()) {
        descAxis.next();
        if (holder.getWriter().getKind() == Kind.ELEMENT) {
            for (int i = 0, attrCount = holder.getWriter().getAttributeCount(); i < attrCount; i++) {
                if (holder.getWriter().moveToAttribute(i).hasMoved()) {
                    attrTouch++;
                } else {
                    throw new IllegalStateException("Should never occur!");
                }
            }
        }
    }
    assertEquals(0, attrTouch);
}
Also used : PostOrderAxis(org.sirix.axis.PostOrderAxis) AbstractAxis(org.sirix.axis.AbstractAxis) DescendantAxis(org.sirix.axis.DescendantAxis) Axis(org.sirix.api.Axis) PostOrderAxis(org.sirix.axis.PostOrderAxis) DescendantAxis(org.sirix.axis.DescendantAxis) AbstractAxis(org.sirix.axis.AbstractAxis) Test(org.junit.Test)

Example 3 with PostOrderAxis

use of org.sirix.axis.PostOrderAxis 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)

Example 4 with PostOrderAxis

use of org.sirix.axis.PostOrderAxis 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)

Example 5 with PostOrderAxis

use of org.sirix.axis.PostOrderAxis in project sirix by sirixdb.

the class FMSE method init.

/**
 * Initialize data structures.
 *
 * @param rtx {@link IRriteTransaction} implementation reference on old revision
 * @param visitor {@link Visitor} reference
 * @throws SirixException if anything in sirix fails
 */
private void init(final XdmNodeReadTrx rtx, final Visitor visitor) {
    assert visitor != null;
    final long nodeKey = rtx.getNodeKey();
    for (final Axis axis = new PostOrderAxis(rtx); axis.hasNext(); ) {
        axis.next();
        if (axis.getTrx().getNodeKey() == nodeKey) {
            break;
        }
        axis.getTrx().acceptVisitor(visitor);
    }
    rtx.acceptVisitor(visitor);
}
Also used : PostOrderAxis(org.sirix.axis.PostOrderAxis) Axis(org.sirix.api.Axis) VisitorDescendantAxis(org.sirix.axis.visitor.VisitorDescendantAxis) AbstractAxis(org.sirix.axis.AbstractAxis) ChildAxis(org.sirix.axis.ChildAxis) PostOrderAxis(org.sirix.axis.PostOrderAxis) DescendantAxis(org.sirix.axis.DescendantAxis) LevelOrderAxis(org.sirix.axis.LevelOrderAxis)

Aggregations

PostOrderAxis (org.sirix.axis.PostOrderAxis)6 Axis (org.sirix.api.Axis)4 DescendantAxis (org.sirix.axis.DescendantAxis)4 AbstractAxis (org.sirix.axis.AbstractAxis)3 LevelOrderAxis (org.sirix.axis.LevelOrderAxis)3 ElementNode (org.sirix.node.ElementNode)3 ChildAxis (org.sirix.axis.ChildAxis)2 StructNode (org.sirix.node.interfaces.StructNode)2 UnorderedKeyValuePage (org.sirix.page.UnorderedKeyValuePage)2 Test (org.junit.Test)1 FilterAxis (org.sirix.axis.filter.FilterAxis)1 NameFilter (org.sirix.axis.filter.NameFilter)1 PathKindFilter (org.sirix.axis.filter.PathKindFilter)1 VisitorDescendantAxis (org.sirix.axis.visitor.VisitorDescendantAxis)1 SirixUsageException (org.sirix.exception.SirixUsageException)1 ImmutableNode (org.sirix.node.interfaces.immutable.ImmutableNode)1