use of org.sirix.api.Axis 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);
}
}
use of org.sirix.api.Axis 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();
}
}
use of org.sirix.api.Axis 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;
}
use of org.sirix.api.Axis 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);
}
use of org.sirix.api.Axis in project sirix by sirixdb.
the class FMSE method emitInsert.
/**
* Emit an insert operation.
*
* @param parent parent of the current {@link Node} implementation reference to insert
* @param child the current node to insert
* @param pos position of the insert
* @param wtx {@link XdmNodeWriteTrx} implementation reference on old revision
* @param rtx {@link XdmNodeReadTrx} implementation reference on new revision
* @return inserted {@link Node} implementation reference
* @throws SirixException if anything in sirix fails
*/
private long emitInsert(final long child, final long parent, final int pos, final XdmNodeWriteTrx wtx, final XdmNodeReadTrx rtx) {
assert child >= 0;
assert parent >= 0;
assert wtx != null;
assert rtx != null;
// Determines if node has been already inserted (for subtrees).
if (mAlreadyInserted.get(child) != null) {
// actually child'
return child;
}
wtx.moveTo(parent);
rtx.moveTo(child);
try {
switch(rtx.getKind()) {
case ATTRIBUTE:
try {
wtx.insertAttribute(rtx.getName(), rtx.getValue());
} catch (final SirixUsageException e) {
mTotalMatching.remove(wtx.getNodeKey());
wtx.setValue(rtx.getValue());
}
process(wtx.getNodeKey(), rtx.getNodeKey());
break;
case NAMESPACE:
// Note that the insertion is right (localPart as prefix).
try {
wtx.insertNamespace(new QNm(rtx.getName().getNamespaceURI(), rtx.getName().getLocalName(), ""));
} catch (final SirixUsageException e) {
mTotalMatching.remove(wtx.getNodeKey());
}
process(wtx.getNodeKey(), rtx.getNodeKey());
break;
default:
// In case of other node types.
long oldKey = 0;
if (pos == 0) {
switch(rtx.getKind()) {
case ELEMENT:
oldKey = wtx.copySubtreeAsFirstChild(rtx).getNodeKey();
break;
case TEXT:
// is inserted.
if (wtx.hasFirstChild()) {
wtx.moveToFirstChild();
if (wtx.getKind() == Kind.TEXT) {
mTotalMatching.remove(wtx.getNodeKey());
wtx.remove();
}
wtx.moveTo(parent);
}
oldKey = wtx.insertTextAsFirstChild(rtx.getValue()).getNodeKey();
break;
default:
}
} else {
assert wtx.hasFirstChild();
wtx.moveToFirstChild();
for (int i = 0; i < pos - 1; i++) {
assert wtx.hasRightSibling();
wtx.moveToRightSibling();
}
// Remove right sibl. text node if a text node already exists.
removeRightSiblingTextNode(wtx);
switch(rtx.getKind()) {
case ELEMENT:
oldKey = wtx.copySubtreeAsRightSibling(rtx).getNodeKey();
break;
case TEXT:
oldKey = wtx.insertTextAsRightSibling(rtx.getValue()).getNodeKey();
break;
default:
// Already inserted.
throw new IllegalStateException("Child should be already inserted!");
}
}
// Mark all nodes in subtree as inserted.
wtx.moveTo(oldKey);
rtx.moveTo(child);
for (final Axis oldAxis = new DescendantAxis(wtx, IncludeSelf.YES), newAxis = new DescendantAxis(rtx, IncludeSelf.YES); oldAxis.hasNext() && newAxis.hasNext(); ) {
oldAxis.next();
newAxis.next();
final XdmNodeReadTrx oldRtx = oldAxis.getTrx();
final XdmNodeReadTrx newRtx = newAxis.getTrx();
process(oldRtx.getNodeKey(), newRtx.getNodeKey());
final long newNodeKey = newRtx.getNodeKey();
final long oldNodeKey = oldRtx.getNodeKey();
if (newRtx.getKind() == Kind.ELEMENT) {
assert newRtx.getKind() == oldRtx.getKind();
if (newRtx.getAttributeCount() > 0) {
for (int i = 0, attCount = newRtx.getAttributeCount(); i < attCount; i++) {
rtx.moveToAttribute(i);
for (int j = 0, oldAttCount = oldRtx.getAttributeCount(); i < oldAttCount; j++) {
wtx.moveToAttribute(j);
if (wtx.getName().equals(rtx.getName())) {
process(oldAxis.getTrx().getNodeKey(), newAxis.getTrx().getNodeKey());
break;
}
oldAxis.getTrx().moveTo(oldNodeKey);
}
newAxis.getTrx().moveTo(newNodeKey);
}
}
if (newRtx.getNamespaceCount() > 0) {
for (int i = 0, nspCount = newRtx.getNamespaceCount(); i < nspCount; i++) {
rtx.moveToNamespace(i);
for (int j = 0, oldNspCount = oldRtx.getNamespaceCount(); j < oldNspCount; j++) {
wtx.moveToNamespace(j);
if (wtx.getName().getNamespaceURI().equals(rtx.getName().getNamespaceURI()) && wtx.getName().getPrefix().equals(wtx.getName().getPrefix())) {
process(wtx.getNodeKey(), rtx.getNodeKey());
break;
}
oldAxis.getTrx().moveTo(oldNodeKey);
}
newAxis.getTrx().moveTo(newNodeKey);
}
}
}
newAxis.getTrx().moveTo(newNodeKey);
}
}
} catch (final SirixException e) {
LOGWRAPPER.error(e.getMessage(), e);
}
return wtx.getNodeKey();
}
Aggregations