Search in sources :

Example 1 with ElementNode

use of org.sirix.node.ElementNode 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 ElementNode

use of org.sirix.node.ElementNode in project sirix by sirixdb.

the class NodePageTest method testSerializeDeserialize.

@Test
public void testSerializeDeserialize() throws IOException {
    final UnorderedKeyValuePage page1 = new UnorderedKeyValuePage(0L, PageKind.RECORDPAGE, Constants.NULL_ID_LONG, mPageReadTrx);
    assertEquals(0L, page1.getPageKey());
    final NodeDelegate del = new NodeDelegate(0, 1, 0, 0, Optional.of(SirixDeweyID.newRootID()));
    final StructNodeDelegate strucDel = new StructNodeDelegate(del, 12l, 4l, 3l, 1l, 0l);
    final NameNodeDelegate nameDel = new NameNodeDelegate(del, 5, 6, 7, 1);
    final ElementNode node1 = new ElementNode(strucDel, nameDel, new ArrayList<Long>(), HashBiMap.<Long, Long>create(), new ArrayList<Long>(), new QNm("a", "b", "c"));
    node1.insertAttribute(88L, 100);
    node1.insertAttribute(87L, 101);
    node1.insertNamespace(99L);
    node1.insertNamespace(98L);
    assertEquals(0L, node1.getNodeKey());
    page1.setEntry(node1.getNodeKey(), node1);
    final ByteArrayOutputStream out = new ByteArrayOutputStream();
    final DataOutputStream dataOut = new DataOutputStream(out);
    PagePersistenter.serializePage(dataOut, page1, SerializationType.DATA);
    final ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
    final UnorderedKeyValuePage page2 = (UnorderedKeyValuePage) PagePersistenter.deserializePage(new DataInputStream(in), mPageReadTrx, SerializationType.DATA);
    // assertEquals(position, out.position());
    final ElementNode element = (ElementNode) page2.getValue(0l);
    assertEquals(0L, page2.getValue(0l).getNodeKey());
    assertEquals(1L, element.getParentKey());
    assertEquals(12L, element.getFirstChildKey());
    assertEquals(3L, element.getLeftSiblingKey());
    assertEquals(4L, element.getRightSiblingKey());
    assertEquals(1, element.getChildCount());
    assertEquals(2, element.getAttributeCount());
    assertEquals(2, element.getNamespaceCount());
    assertEquals(88L, element.getAttributeKey(0));
    assertEquals(87L, element.getAttributeKey(1));
    assertEquals(99L, element.getNamespaceKey(0));
    assertEquals(98L, element.getNamespaceKey(1));
    assertEquals(5, ((NameNode) page2.getValue(0l)).getURIKey());
    assertEquals(6, ((NameNode) page2.getValue(0l)).getPrefixKey());
    assertEquals(7, ((NameNode) page2.getValue(0l)).getLocalNameKey());
    assertEquals(NamePageHash.generateHashForString("xs:untyped"), element.getTypeKey());
}
Also used : QNm(org.brackit.xquery.atomic.QNm) StructNodeDelegate(org.sirix.node.delegates.StructNodeDelegate) ByteArrayInputStream(java.io.ByteArrayInputStream) DataOutputStream(java.io.DataOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ElementNode(org.sirix.node.ElementNode) DataInputStream(java.io.DataInputStream) NodeDelegate(org.sirix.node.delegates.NodeDelegate) StructNodeDelegate(org.sirix.node.delegates.StructNodeDelegate) NameNodeDelegate(org.sirix.node.delegates.NameNodeDelegate) NameNodeDelegate(org.sirix.node.delegates.NameNodeDelegate) Test(org.junit.Test)

Example 3 with ElementNode

use of org.sirix.node.ElementNode in project sirix by sirixdb.

the class XdmNodeReadTrxImpl method moveToAttributeByName.

@Override
public Move<? extends XdmNodeReadTrx> moveToAttributeByName(final QNm name) {
    assertNotClosed();
    if (mCurrentNode.getKind() == Kind.ELEMENT) {
        final ElementNode element = ((ElementNode) mCurrentNode);
        final Optional<Long> attrKey = element.getAttributeKeyByName(name);
        if (attrKey.isPresent()) {
            final Move<? extends XdmNodeReadTrx> moved = moveTo(attrKey.get());
            return moved;
        }
    }
    return Move.notMoved();
}
Also used : ElementNode(org.sirix.node.ElementNode)

Example 4 with ElementNode

use of org.sirix.node.ElementNode in project sirix by sirixdb.

the class XdmNodeWriterTrxImpl method insertElementAsLeftSibling.

@Override
public XdmNodeWriteTrx insertElementAsLeftSibling(final QNm name) throws SirixException {
    if (!XMLToken.isValidQName(checkNotNull(name))) {
        throw new IllegalArgumentException("The QName is not valid!");
    }
    acquireLock();
    try {
        if (getCurrentNode() instanceof StructNode && getCurrentNode().getKind() != Kind.DOCUMENT) {
            checkAccessAndCommit();
            final long key = getCurrentNode().getNodeKey();
            moveToParent();
            final long pathNodeKey = mBuildPathSummary ? mPathSummaryWriter.getPathNodeKey(name, Kind.ELEMENT) : 0;
            moveTo(key);
            final long parentKey = getCurrentNode().getParentKey();
            final long leftSibKey = ((StructNode) getCurrentNode()).getLeftSiblingKey();
            final long rightSibKey = getCurrentNode().getNodeKey();
            final Optional<SirixDeweyID> id = newLeftSiblingID();
            final ElementNode node = mNodeFactory.createElementNode(parentKey, leftSibKey, rightSibKey, 0, name, pathNodeKey, id);
            mNodeReader.setCurrentNode(node);
            adaptForInsert(node, InsertPos.ASLEFTSIBLING, PageKind.RECORDPAGE);
            mNodeReader.setCurrentNode(node);
            adaptHashesWithAdd();
            return this;
        } else {
            throw new SirixUsageException("Insert is not allowed if current node is not an StructuralNode (either Text or Element)!");
        }
    } finally {
        unLock();
    }
}
Also used : SirixDeweyID(org.sirix.node.SirixDeweyID) ElementNode(org.sirix.node.ElementNode) SirixUsageException(org.sirix.exception.SirixUsageException) StructNode(org.sirix.node.interfaces.StructNode)

Example 5 with ElementNode

use of org.sirix.node.ElementNode 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)

Aggregations

ElementNode (org.sirix.node.ElementNode)15 StructNode (org.sirix.node.interfaces.StructNode)10 SirixUsageException (org.sirix.exception.SirixUsageException)8 UnorderedKeyValuePage (org.sirix.page.UnorderedKeyValuePage)7 NameNode (org.sirix.node.interfaces.NameNode)6 ImmutableNode (org.sirix.node.interfaces.immutable.ImmutableNode)6 AttributeNode (org.sirix.node.AttributeNode)5 CommentNode (org.sirix.node.CommentNode)5 NamespaceNode (org.sirix.node.NamespaceNode)5 PINode (org.sirix.node.PINode)5 SirixDeweyID (org.sirix.node.SirixDeweyID)5 TextNode (org.sirix.node.TextNode)5 Node (org.sirix.node.interfaces.Node)5 ValueNode (org.sirix.node.interfaces.ValueNode)5 PostOrderAxis (org.sirix.axis.PostOrderAxis)4 QNm (org.brackit.xquery.atomic.QNm)3 Axis (org.sirix.api.Axis)3 DescendantAxis (org.sirix.axis.DescendantAxis)3 LevelOrderAxis (org.sirix.axis.LevelOrderAxis)3 Optional (java.util.Optional)2