use of org.sirix.node.interfaces.immutable.ImmutableNode in project sirix by sirixdb.
the class XdmNodeWriterTrxImpl method rollingAdd.
/**
* Adapting the structure with a rolling hash for all ancestors only with insert.
*
* @throws SirixIOException if an I/O error occurs
*/
private void rollingAdd() throws SirixIOException {
// start with hash to add
final ImmutableNode startNode = mNodeReader.getCurrentNode();
final long oldDescendantCount = mNodeReader.getStructuralNode().getDescendantCount();
final long descendantCount = oldDescendantCount == 0 ? 1 : oldDescendantCount + 1;
long hashToAdd = startNode.getHash() == 0 ? mHash.hashLong(startNode.hashCode()).asLong() : startNode.getHash();
long newHash = 0;
long possibleOldHash = 0;
// go the path to the root
do {
final Node node = (Node) getPageTransaction().prepareEntryForModification(mNodeReader.getCurrentNode().getNodeKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
if (node.getNodeKey() == startNode.getNodeKey()) {
// at the beginning, take the hashcode of the node only
newHash = hashToAdd;
} else if (node.getNodeKey() == startNode.getParentKey()) {
// at the parent level, just add the node
possibleOldHash = node.getHash();
newHash = possibleOldHash + hashToAdd * PRIME;
hashToAdd = newHash;
setAddDescendants(startNode, node, descendantCount);
} else {
// at the rest, remove the existing old key for this element
// and add the new one
newHash = node.getHash() - possibleOldHash * PRIME;
newHash = newHash + hashToAdd * PRIME;
hashToAdd = newHash;
possibleOldHash = node.getHash();
setAddDescendants(startNode, node, descendantCount);
}
node.setHash(newHash);
} while (moveTo(mNodeReader.getCurrentNode().getParentKey()).hasMoved());
mNodeReader.setCurrentNode(startNode);
}
use of org.sirix.node.interfaces.immutable.ImmutableNode 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();
}
}
use of org.sirix.node.interfaces.immutable.ImmutableNode 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.immutable.ImmutableNode in project sirix by sirixdb.
the class XdmNodeWriterTrxImpl method rollingRemove.
/**
* Adapting the structure with a rolling hash for all ancestors only with remove.
*
* @throws SirixIOException if anything weird happened
*/
private void rollingRemove() throws SirixIOException {
final ImmutableNode startNode = getCurrentNode();
long hashToRemove = startNode.getHash();
long hashToAdd = 0;
long newHash = 0;
// go the path to the root
do {
final Node node = (Node) getPageTransaction().prepareEntryForModification(mNodeReader.getCurrentNode().getNodeKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
if (node.getNodeKey() == startNode.getNodeKey()) {
// the begin node is always null
newHash = 0;
} else if (node.getNodeKey() == startNode.getParentKey()) {
// the parent node is just removed
newHash = node.getHash() - hashToRemove * PRIME;
hashToRemove = node.getHash();
setRemoveDescendants(startNode);
} else {
// the ancestors are all touched regarding the modification
newHash = node.getHash() - hashToRemove * PRIME;
newHash = newHash + hashToAdd * PRIME;
hashToRemove = node.getHash();
setRemoveDescendants(startNode);
}
node.setHash(newHash);
hashToAdd = newHash;
} while (moveTo(mNodeReader.getCurrentNode().getParentKey()).hasMoved());
mNodeReader.setCurrentNode(startNode);
}
use of org.sirix.node.interfaces.immutable.ImmutableNode in project sirix by sirixdb.
the class XdmNodeWriterTrxImpl method replaceNode.
@Override
public XdmNodeWriteTrx replaceNode(final String xml) throws SirixException, IOException, XMLStreamException {
checkNotNull(xml);
acquireLock();
try {
checkAccessAndCommit();
final XMLEventReader reader = XMLShredder.createStringReader(checkNotNull(xml));
ImmutableNode insertedRootNode = null;
if (getCurrentNode() instanceof StructNode) {
final StructNode currentNode = mNodeReader.getStructuralNode();
if (xml.startsWith("<")) {
while (reader.hasNext()) {
final XMLEvent event = reader.peek();
if (event.isStartDocument()) {
reader.nextEvent();
continue;
}
switch(event.getEventType()) {
case XMLStreamConstants.START_ELEMENT:
Insert pos = Insert.ASFIRSTCHILD;
if (currentNode.hasLeftSibling()) {
moveToLeftSibling();
pos = Insert.ASRIGHTSIBLING;
} else {
moveToParent();
}
final XMLShredder shredder = new XMLShredder.Builder(this, reader, pos).build();
shredder.call();
if (reader.hasNext()) {
// End document.
reader.nextEvent();
}
insertedRootNode = mNodeReader.getCurrentNode();
moveTo(currentNode.getNodeKey());
remove();
moveTo(insertedRootNode.getNodeKey());
break;
}
}
} else {
insertedRootNode = replaceWithTextNode(xml);
}
if (insertedRootNode != null) {
moveTo(insertedRootNode.getNodeKey());
}
} else {
}
} finally {
unLock();
}
return this;
}
Aggregations