Search in sources :

Example 1 with PathKindFilter

use of org.sirix.axis.filter.PathKindFilter 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 PathKindFilter

use of org.sirix.axis.filter.PathKindFilter in project sirix by sirixdb.

the class PathSummaryWriter method processFoundPathNode.

/**
 * Process a found path node.
 *
 * @param oldPathNodeKey key of old path node
 * @param newPathNodeKey key of new path node
 * @param oldNodeKey key of old node
 * @param uriKey key of URI
 * @param prefixKey key of prefix
 * @param localNameKey key of local name
 * @param remove determines if a {@link PathNode} must be removed or not
 * @param type type of operation
 * @throws SirixException if Sirix fails to do so
 */
private void processFoundPathNode(@Nonnegative final long oldPathNodeKey, @Nonnegative final long newPathNodeKey, @Nonnegative final long oldNodeKey, final int uriKey, final int prefixKey, final int localNameKey, final Remove remove, final OPType type) throws SirixException {
    final PathSummaryReader cloned = PathSummaryReader.getInstance(mPageWriteTrx, mNodeRtx.getResourceManager());
    boolean moved = cloned.moveTo(oldPathNodeKey).hasMoved();
    assert moved;
    // Set new reference count of the root.
    if (type != OPType.MOVEDSAMELEVEL) {
        final PathNode currNode = (PathNode) mPageWriteTrx.prepareEntryForModification(mPathSummaryReader.getNodeKey(), PageKind.PATHSUMMARYPAGE, 0, Optional.<UnorderedKeyValuePage>empty());
        currNode.setReferenceCount(currNode.getReferences() + cloned.getReferences());
        currNode.setLocalNameKey(localNameKey);
        currNode.setPrefixKey(prefixKey);
        currNode.setURIKey(uriKey);
    }
    // For all old path nodes: Merge paths and adapt reference counts.
    mPathSummaryReader.moveToFirstChild();
    final int oldLevel = cloned.getLevel();
    for (final Axis oldDescendants = new DescendantAxis(cloned); oldDescendants.hasNext(); ) {
        oldDescendants.next();
        // Search for new path entry.
        final Axis axis = new FilterAxis(new LevelOrderAxis.Builder(mPathSummaryReader).filterLevel(cloned.getLevel() - oldLevel).includeSelf().build(), new NameFilter(mPathSummaryReader, Utils.buildName(cloned.getName())), new PathKindFilter(mPathSummaryReader, cloned.getPathKind()), new PathLevelFilter(mPathSummaryReader, cloned.getLevel()));
        if (axis.hasNext()) {
            axis.next();
            // Set new reference count.
            if (type != OPType.MOVEDSAMELEVEL) {
                final PathNode currNode = (PathNode) mPageWriteTrx.prepareEntryForModification(mPathSummaryReader.getNodeKey(), PageKind.PATHSUMMARYPAGE, 0, Optional.<UnorderedKeyValuePage>empty());
                currNode.setReferenceCount(currNode.getReferences() + cloned.getReferences());
            }
        } else {
            // Insert new node.
            insertPathAsFirstChild(cloned.getName(), cloned.getPathKind(), mPathSummaryReader.getLevel() + 1);
            // Set new reference count.
            final PathNode currNode = (PathNode) mPageWriteTrx.prepareEntryForModification(mPathSummaryReader.getNodeKey(), PageKind.PATHSUMMARYPAGE, 0, Optional.<UnorderedKeyValuePage>empty());
            currNode.setReferenceCount(cloned.getReferences());
        }
        mPathSummaryReader.moveTo(newPathNodeKey);
    }
    // Set new path nodes of the changed nodes, that is set their PCR
    // references.
    mPathSummaryReader.moveTo(newPathNodeKey);
    mNodeRtx.moveTo(oldNodeKey);
    boolean first = true;
    for (final Axis axis = new DescendantAxis(mNodeRtx, IncludeSelf.YES); axis.hasNext(); ) {
        axis.next();
        if (first && type == OPType.SETNAME) {
            first = false;
        } else if (mNodeRtx.getNode() instanceof ImmutableNameNode) {
            cloned.moveTo(((NameNode) mNodeRtx.getCurrentNode()).getPathNodeKey());
            resetPath(newPathNodeKey, cloned.getLevel());
            if (mNodeRtx.getNode().getKind() == Kind.ELEMENT) {
                final ElementNode element = (ElementNode) mNodeRtx.getCurrentNode();
                for (int i = 0, nspCount = element.getNamespaceCount(); i < nspCount; i++) {
                    mNodeRtx.moveToNamespace(i);
                    cloned.moveTo(((NameNode) mNodeRtx.getCurrentNode()).getPathNodeKey());
                    resetPath(newPathNodeKey, cloned.getLevel());
                    mNodeRtx.moveToParent();
                }
                for (int i = 0, attCount = element.getAttributeCount(); i < attCount; i++) {
                    mNodeRtx.moveToAttribute(i);
                    cloned.moveTo(((NameNode) mNodeRtx.getCurrentNode()).getPathNodeKey());
                    resetPath(newPathNodeKey, cloned.getLevel());
                    mNodeRtx.moveToParent();
                }
            }
        }
    }
    // Then: Remove old nodes.
    if (remove == Remove.YES) {
        mPathSummaryReader.moveTo(oldPathNodeKey);
        removePathSummaryNode(remove);
    }
}
Also used : ImmutableNameNode(org.sirix.node.interfaces.immutable.ImmutableNameNode) NameNode(org.sirix.node.interfaces.NameNode) PathLevelFilter(org.sirix.axis.filter.PathLevelFilter) UnorderedKeyValuePage(org.sirix.page.UnorderedKeyValuePage) ElementNode(org.sirix.node.ElementNode) FilterAxis(org.sirix.axis.filter.FilterAxis) NameFilter(org.sirix.axis.filter.NameFilter) ImmutableNameNode(org.sirix.node.interfaces.immutable.ImmutableNameNode) 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 PathKindFilter

use of org.sirix.axis.filter.PathKindFilter in project sirix by sirixdb.

the class PathSummaryWriter method resetPath.

/**
 * Reset the path node key of a node.
 *
 * @param newPathNodeKey path node key of new path node
 * @param oldLevel old level of node
 * @throws SirixIOException if an I/O error occurs
 */
private void resetPath(@Nonnegative final long newPathNodeKey, @Nonnegative final int oldLevel) throws SirixIOException {
    // Search for new path entry.
    mPathSummaryReader.moveTo(newPathNodeKey);
    final Axis filterAxis = new FilterAxis(new LevelOrderAxis.Builder(mPathSummaryReader).includeSelf().build(), new NameFilter(mPathSummaryReader, Utils.buildName(mNodeRtx.getName())), new PathKindFilter(mPathSummaryReader, mNodeRtx.getKind()), new PathLevelFilter(mPathSummaryReader, oldLevel));
    if (filterAxis.hasNext()) {
        filterAxis.next();
        // Set new path node.
        final NameNode node = (NameNode) mPageWriteTrx.prepareEntryForModification(mNodeRtx.getNodeKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
        node.setPathNodeKey(mPathSummaryReader.getNodeKey());
    } else {
        throw new IllegalStateException();
    }
}
Also used : ImmutableNameNode(org.sirix.node.interfaces.immutable.ImmutableNameNode) NameNode(org.sirix.node.interfaces.NameNode) NameFilter(org.sirix.axis.filter.NameFilter) PathLevelFilter(org.sirix.axis.filter.PathLevelFilter) UnorderedKeyValuePage(org.sirix.page.UnorderedKeyValuePage) 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) FilterAxis(org.sirix.axis.filter.FilterAxis) PathKindFilter(org.sirix.axis.filter.PathKindFilter) LevelOrderAxis(org.sirix.axis.LevelOrderAxis)

Example 4 with PathKindFilter

use of org.sirix.axis.filter.PathKindFilter in project sirix by sirixdb.

the class PathSummaryWriter method getPathNodeKey.

/**
 * Insert a new path node or increment the counter of an existing node and return the path node
 * key.
 *
 * @param name the name of the path node to search for
 * @param pathKind the kind of the path node to search for
 * @return a path node key of the found node, or the path node key of a new inserted node
 * @throws SirixException if anything went wrong
 */
public long getPathNodeKey(final QNm name, final Kind pathKind) throws SirixException {
    final Kind kind = mNodeRtx.getNode().getKind();
    int level = 0;
    if (kind == Kind.DOCUMENT) {
        mPathSummaryReader.moveTo(Fixed.DOCUMENT_NODE_KEY.getStandardProperty());
    } else {
        movePathSummary();
        level = mPathSummaryReader.getLevel();
    }
    final long nodeKey = mPathSummaryReader.getNodeKey();
    final Axis axis = new FilterAxis(new ChildAxis(mPathSummaryReader), new NameFilter(mPathSummaryReader, pathKind == Kind.NAMESPACE ? name.getPrefix() : Utils.buildName(name)), new PathKindFilter(mPathSummaryReader, pathKind));
    long retVal = nodeKey;
    if (axis.hasNext()) {
        axis.next();
        retVal = mPathSummaryReader.getNodeKey();
        final PathNode pathNode = (PathNode) mPageWriteTrx.prepareEntryForModification(retVal, PageKind.PATHSUMMARYPAGE, 0, Optional.<UnorderedKeyValuePage>empty());
        pathNode.incrementReferenceCount();
    } else {
        assert nodeKey == mPathSummaryReader.getNodeKey();
        insertPathAsFirstChild(name, pathKind, level + 1);
        retVal = mPathSummaryReader.getNodeKey();
    }
    return retVal;
}
Also used : ChildAxis(org.sirix.axis.ChildAxis) NameFilter(org.sirix.axis.filter.NameFilter) PageKind(org.sirix.page.PageKind) Kind(org.sirix.node.Kind) UnorderedKeyValuePage(org.sirix.page.UnorderedKeyValuePage) 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) FilterAxis(org.sirix.axis.filter.FilterAxis) PathKindFilter(org.sirix.axis.filter.PathKindFilter)

Aggregations

Axis (org.sirix.api.Axis)4 ChildAxis (org.sirix.axis.ChildAxis)4 DescendantAxis (org.sirix.axis.DescendantAxis)4 LevelOrderAxis (org.sirix.axis.LevelOrderAxis)4 PostOrderAxis (org.sirix.axis.PostOrderAxis)4 FilterAxis (org.sirix.axis.filter.FilterAxis)4 NameFilter (org.sirix.axis.filter.NameFilter)4 PathKindFilter (org.sirix.axis.filter.PathKindFilter)4 UnorderedKeyValuePage (org.sirix.page.UnorderedKeyValuePage)4 PathLevelFilter (org.sirix.axis.filter.PathLevelFilter)2 ElementNode (org.sirix.node.ElementNode)2 NameNode (org.sirix.node.interfaces.NameNode)2 ImmutableNameNode (org.sirix.node.interfaces.immutable.ImmutableNameNode)2 Kind (org.sirix.node.Kind)1 PageKind (org.sirix.page.PageKind)1