use of org.sirix.node.interfaces.StructNode in project sirix by sirixdb.
the class XdmNodeWriterTrxImpl method moveSubtreeToFirstChild.
@Override
public XdmNodeWriteTrx moveSubtreeToFirstChild(@Nonnegative final long fromKey) throws SirixException, IllegalArgumentException {
acquireLock();
try {
Preconditions.checkArgument(fromKey >= 0 && fromKey <= getMaxNodeKey(), "Argument must be a valid node key!");
Preconditions.checkArgument(fromKey != getCurrentNode().getNodeKey(), "Can't move itself to right sibling of itself!");
@SuppressWarnings("unchecked") final Optional<? extends Node> node = (Optional<? extends Node>) getPageTransaction().getRecord(fromKey, PageKind.RECORDPAGE, -1);
if (!node.isPresent()) {
throw new IllegalStateException("Node to move must exist!");
}
final Node nodeToMove = node.get();
if (nodeToMove instanceof StructNode && getCurrentNode().getKind() == Kind.ELEMENT) {
// Safe to cast (because IStructNode is a subtype of INode).
checkAncestors(nodeToMove);
checkAccessAndCommit();
final ElementNode nodeAnchor = (ElementNode) getCurrentNode();
// Check that it's not already the first child.
if (nodeAnchor.getFirstChildKey() != nodeToMove.getNodeKey()) {
final StructNode toMove = (StructNode) nodeToMove;
// Adapt index-structures (before move).
adaptSubtreeForMove(toMove, ChangeType.DELETE);
// Adapt hashes.
adaptHashesForMove(toMove);
// Adapt pointers and merge sibling text nodes.
adaptForMove(toMove, nodeAnchor, InsertPos.ASFIRSTCHILD);
mNodeReader.moveTo(toMove.getNodeKey());
adaptHashesWithAdd();
// Adapt path summary.
if (mBuildPathSummary && toMove instanceof NameNode) {
final NameNode moved = (NameNode) toMove;
mPathSummaryWriter.adaptPathForChangedNode(moved, getName(), moved.getURIKey(), moved.getPrefixKey(), moved.getLocalNameKey(), OPType.MOVED);
}
// Adapt index-structures (after move).
adaptSubtreeForMove(toMove, ChangeType.INSERT);
// Compute and assign new DeweyIDs.
if (mDeweyIDsStored) {
computeNewDeweyIDs();
}
}
return this;
} else {
throw new SirixUsageException("Move is not allowed if moved node is not an ElementNode and the node isn't inserted at an element node!");
}
} finally {
unLock();
}
}
use of org.sirix.node.interfaces.StructNode in project sirix by sirixdb.
the class XdmNodeWriterTrxImpl method computeNewDeweyIDs.
/**
* Compute the new DeweyIDs.
*
* @throws SirixException if anything went wrong
*/
private void computeNewDeweyIDs() throws SirixException {
SirixDeweyID id = null;
if (hasLeftSibling() && hasRightSibling()) {
id = SirixDeweyID.newBetween(getLeftSiblingDeweyID().get(), getRightSiblingDeweyID().get());
} else if (hasLeftSibling()) {
id = SirixDeweyID.newBetween(getLeftSiblingDeweyID().get(), null);
} else if (hasRightSibling()) {
id = SirixDeweyID.newBetween(null, getRightSiblingDeweyID().get());
} else {
id = mNodeReader.getParentDeweyID().get().getNewChildID();
}
assert id != null;
final long nodeKey = mNodeReader.getCurrentNode().getNodeKey();
final StructNode root = (StructNode) getPageTransaction().prepareEntryForModification(nodeKey, PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
root.setDeweyID(Optional.of(id));
if (root.hasFirstChild()) {
final Node firstChild = (Node) getPageTransaction().prepareEntryForModification(root.getFirstChildKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
firstChild.setDeweyID(Optional.of(id.getNewChildID()));
int previousLevel = getDeweyID().get().getLevel();
mNodeReader.moveTo(firstChild.getNodeKey());
int attributeNr = 0;
int nspNr = 0;
for (@SuppressWarnings("unused") final long key : LevelOrderAxis.newBuilder(this).includeNonStructuralNodes().build()) {
Optional<SirixDeweyID> deweyID = Optional.<SirixDeweyID>empty();
if (isAttribute()) {
final long attNodeKey = mNodeReader.getNodeKey();
if (attributeNr == 0) {
deweyID = Optional.of(mNodeReader.getParentDeweyID().get().getNewAttributeID());
} else {
mNodeReader.moveTo(attributeNr - 1);
deweyID = Optional.of(SirixDeweyID.newBetween(mNodeReader.getNode().getDeweyID().get(), null));
}
mNodeReader.moveTo(attNodeKey);
attributeNr++;
} else if (isNamespace()) {
final long nspNodeKey = mNodeReader.getNodeKey();
if (nspNr == 0) {
deweyID = Optional.of(mNodeReader.getParentDeweyID().get().getNewNamespaceID());
} else {
mNodeReader.moveTo(nspNr - 1);
deweyID = Optional.of(SirixDeweyID.newBetween(mNodeReader.getNode().getDeweyID().get(), null));
}
mNodeReader.moveTo(nspNodeKey);
nspNr++;
} else {
attributeNr = 0;
nspNr = 0;
if (previousLevel + 1 == getDeweyID().get().getLevel()) {
if (mNodeReader.hasLeftSibling()) {
deweyID = Optional.of(SirixDeweyID.newBetween(getLeftSiblingDeweyID().get(), null));
} else {
deweyID = Optional.of(getParentDeweyID().get().getNewChildID());
}
} else {
previousLevel++;
deweyID = Optional.of(getParentDeweyID().get().getNewChildID());
}
}
final Node node = (Node) getPageTransaction().prepareEntryForModification(mNodeReader.getCurrentNode().getNodeKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
node.setDeweyID(deweyID);
}
mNodeReader.moveTo(nodeKey);
}
}
use of org.sirix.node.interfaces.StructNode in project sirix by sirixdb.
the class XdmNodeWriterTrxImpl method insertSubtree.
private XdmNodeWriteTrx insertSubtree(final XMLEventReader reader, final Insert insert) throws SirixException {
checkNotNull(reader);
assert insert != null;
acquireLock();
try {
if (getCurrentNode() instanceof StructNode) {
checkAccessAndCommit();
mBulkInsert = true;
long nodeKey = getCurrentNode().getNodeKey();
final XMLShredder shredder = new XMLShredder.Builder(this, reader, insert).commitAfterwards().build();
shredder.call();
moveTo(nodeKey);
switch(insert) {
case ASFIRSTCHILD:
moveToFirstChild();
break;
case ASRIGHTSIBLING:
moveToRightSibling();
break;
case ASLEFTSIBLING:
moveToLeftSibling();
break;
}
nodeKey = getCurrentNode().getNodeKey();
postOrderTraversalHashes();
final ImmutableNode startNode = getCurrentNode();
moveToParent();
while (getCurrentNode().hasParent()) {
moveToParent();
addParentHash(startNode);
}
moveTo(nodeKey);
mBulkInsert = false;
}
} finally {
unLock();
}
return this;
}
use of org.sirix.node.interfaces.StructNode in project sirix by sirixdb.
the class XdmNodeWriterTrxImpl method adaptForRemove.
// ////////////////////////////////////////////////////////////
// end of insert operation
// ////////////////////////////////////////////////////////////
// ////////////////////////////////////////////////////////////
// remove operation
// ////////////////////////////////////////////////////////////
/**
* Adapting everything for remove operations.
*
* @param oldNode pointer of the old node to be replaced
* @throws SirixException if anything weird happens
*/
private void adaptForRemove(final StructNode oldNode, final PageKind page) throws SirixException {
assert oldNode != null;
// Concatenate neighbor text nodes if they exist (the right sibling is
// deleted afterwards).
boolean concatenated = false;
if (oldNode.hasLeftSibling() && oldNode.hasRightSibling() && moveTo(oldNode.getRightSiblingKey()).hasMoved() && getCurrentNode().getKind() == Kind.TEXT && moveTo(oldNode.getLeftSiblingKey()).hasMoved() && getCurrentNode().getKind() == Kind.TEXT) {
final StringBuilder builder = new StringBuilder(getValue());
moveTo(oldNode.getRightSiblingKey());
builder.append(getValue());
moveTo(oldNode.getLeftSiblingKey());
setValue(builder.toString());
concatenated = true;
}
// Adapt left sibling node if there is one.
if (oldNode.hasLeftSibling()) {
final StructNode leftSibling = (StructNode) getPageTransaction().prepareEntryForModification(oldNode.getLeftSiblingKey(), page, -1, Optional.<UnorderedKeyValuePage>empty());
if (concatenated) {
moveTo(oldNode.getRightSiblingKey());
leftSibling.setRightSiblingKey(((StructNode) getCurrentNode()).getRightSiblingKey());
} else {
leftSibling.setRightSiblingKey(oldNode.getRightSiblingKey());
}
}
// Adapt right sibling node if there is one.
if (oldNode.hasRightSibling()) {
StructNode rightSibling;
if (concatenated) {
moveTo(oldNode.getRightSiblingKey());
moveTo(mNodeReader.getStructuralNode().getRightSiblingKey());
rightSibling = (StructNode) getPageTransaction().prepareEntryForModification(mNodeReader.getCurrentNode().getNodeKey(), page, -1, Optional.<UnorderedKeyValuePage>empty());
rightSibling.setLeftSiblingKey(oldNode.getLeftSiblingKey());
} else {
rightSibling = (StructNode) getPageTransaction().prepareEntryForModification(oldNode.getRightSiblingKey(), page, -1, Optional.<UnorderedKeyValuePage>empty());
rightSibling.setLeftSiblingKey(oldNode.getLeftSiblingKey());
}
}
// Adapt parent, if node has now left sibling it is a first child.
StructNode parent = (StructNode) getPageTransaction().prepareEntryForModification(oldNode.getParentKey(), page, -1, Optional.<UnorderedKeyValuePage>empty());
if (!oldNode.hasLeftSibling()) {
parent.setFirstChildKey(oldNode.getRightSiblingKey());
}
parent.decrementChildCount();
if (concatenated) {
parent.decrementDescendantCount();
parent.decrementChildCount();
}
if (concatenated) {
// Adjust descendant count.
moveTo(parent.getNodeKey());
while (parent.hasParent()) {
moveToParent();
final StructNode ancestor = (StructNode) getPageTransaction().prepareEntryForModification(mNodeReader.getCurrentNode().getNodeKey(), page, -1, Optional.<UnorderedKeyValuePage>empty());
ancestor.decrementDescendantCount();
parent = ancestor;
}
}
// concatenated/merged.
if (concatenated) {
moveTo(oldNode.getRightSiblingKey());
getPageTransaction().removeEntry(mNodeReader.getNodeKey(), page, -1, Optional.<UnorderedKeyValuePage>empty());
}
// Remove non structural nodes of old node.
if (oldNode.getKind() == Kind.ELEMENT) {
moveTo(oldNode.getNodeKey());
removeNonStructural();
}
// Remove old node.
moveTo(oldNode.getNodeKey());
getPageTransaction().removeEntry(oldNode.getNodeKey(), page, -1, Optional.<UnorderedKeyValuePage>empty());
}
use of org.sirix.node.interfaces.StructNode in project sirix by sirixdb.
the class XdmNodeWriterTrxImpl method pi.
/**
* Processing instruction.
*
* @param target target PI
* @param content content of PI
* @param insert insertion location
* @throws SirixException if any unexpected error occurs
*/
private XdmNodeWriteTrx pi(final String target, final String content, final Insert insert) throws SirixException {
final byte[] targetBytes = getBytes(target);
if (!XMLToken.isNCName(checkNotNull(targetBytes))) {
throw new IllegalArgumentException("The target is not valid!");
}
if (content.contains("?>-")) {
throw new SirixUsageException("The content must not contain '?>-'");
}
acquireLock();
try {
if (getCurrentNode() instanceof StructNode) {
checkAccessAndCommit();
// Insert new processing instruction node.
final byte[] processingContent = getBytes(content);
long parentKey = 0;
long leftSibKey = 0;
long rightSibKey = 0;
InsertPos pos = InsertPos.ASFIRSTCHILD;
Optional<SirixDeweyID> id = Optional.<SirixDeweyID>empty();
switch(insert) {
case ASFIRSTCHILD:
parentKey = getCurrentNode().getNodeKey();
leftSibKey = Fixed.NULL_NODE_KEY.getStandardProperty();
rightSibKey = ((StructNode) getCurrentNode()).getFirstChildKey();
id = newFirstChildID();
break;
case ASRIGHTSIBLING:
parentKey = getCurrentNode().getParentKey();
leftSibKey = getCurrentNode().getNodeKey();
rightSibKey = ((StructNode) getCurrentNode()).getRightSiblingKey();
pos = InsertPos.ASRIGHTSIBLING;
id = newRightSiblingID();
break;
case ASLEFTSIBLING:
parentKey = getCurrentNode().getParentKey();
leftSibKey = ((StructNode) getCurrentNode()).getLeftSiblingKey();
rightSibKey = getCurrentNode().getNodeKey();
pos = InsertPos.ASLEFTSIBLING;
id = newLeftSiblingID();
break;
default:
throw new IllegalStateException("Insert location not known!");
}
final QNm targetName = new QNm(target);
final long pathNodeKey = mBuildPathSummary ? mPathSummaryWriter.getPathNodeKey(targetName, Kind.PROCESSING_INSTRUCTION) : 0;
final PINode node = mNodeFactory.createPINode(parentKey, leftSibKey, rightSibKey, targetName, processingContent, mCompression, pathNodeKey, id);
// Adapt local nodes and hashes.
mNodeReader.setCurrentNode(node);
adaptForInsert(node, pos, PageKind.RECORDPAGE);
mNodeReader.setCurrentNode(node);
adaptHashesWithAdd();
return this;
} else {
throw new SirixUsageException("Current node must be a structural node!");
}
} finally {
unLock();
}
}
Aggregations