use of org.sirix.node.interfaces.Node in project sirix by sirixdb.
the class XdmNodeWriterTrxImpl method addParentHash.
/**
* Add a hash.
*
* @param startNode start node
*/
private void addParentHash(final ImmutableNode startNode) throws SirixIOException {
switch(mHashKind) {
case ROLLING:
final long hashToAdd = mHash.hashLong(startNode.hashCode()).asLong();
final Node node = (Node) getPageTransaction().prepareEntryForModification(mNodeReader.getCurrentNode().getNodeKey(), PageKind.RECORDPAGE, -1, Optional.empty());
node.setHash(node.getHash() + hashToAdd * PRIME);
if (startNode instanceof StructNode) {
((StructNode) node).setDescendantCount(((StructNode) node).getDescendantCount() + ((StructNode) startNode).getDescendantCount() + 1);
}
break;
case POSTORDER:
break;
default:
}
}
use of org.sirix.node.interfaces.Node in project sirix by sirixdb.
the class XdmNodeWriterTrxImpl method addHashAndDescendantCount.
/**
* Add a hash and the descendant count.
*/
private void addHashAndDescendantCount() throws SirixIOException {
switch(mHashKind) {
case ROLLING:
// Setup.
final ImmutableNode startNode = getCurrentNode();
final long oldDescendantCount = mNodeReader.getStructuralNode().getDescendantCount();
final long descendantCount = oldDescendantCount == 0 ? 1 : oldDescendantCount + 1;
// Set start node.
final long hashToAdd = mHash.hashLong(startNode.hashCode()).asLong();
Node node = (Node) getPageTransaction().prepareEntryForModification(mNodeReader.getCurrentNode().getNodeKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
node.setHash(hashToAdd);
// Set parent node.
if (startNode.hasParent()) {
moveToParent();
node = (Node) getPageTransaction().prepareEntryForModification(mNodeReader.getCurrentNode().getNodeKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
node.setHash(node.getHash() + hashToAdd * PRIME);
setAddDescendants(startNode, node, descendantCount);
}
mNodeReader.setCurrentNode(startNode);
break;
case POSTORDER:
postorderAdd();
break;
default:
}
}
use of org.sirix.node.interfaces.Node 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);
}
use of org.sirix.node.interfaces.Node 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.Node in project sirix by sirixdb.
the class XdmNodeWriterTrxImpl method insertAttribute.
@Override
public XdmNodeWriteTrx insertAttribute(final QNm name, final String value, final Movement move) throws SirixException {
checkNotNull(value);
if (!XMLToken.isValidQName(checkNotNull(name))) {
throw new IllegalArgumentException("The QName is not valid!");
}
acquireLock();
try {
if (getCurrentNode().getKind() == Kind.ELEMENT) {
checkAccessAndCommit();
/*
* Update value in case of the same attribute name is found but the attribute to insert has
* a different value (otherwise an exception is thrown because of a duplicate attribute
* which would otherwise be inserted!).
*/
final ElementNode element = (ElementNode) getCurrentNode();
final Optional<Long> attKey = element.getAttributeKeyByName(name);
if (attKey.isPresent()) {
moveTo(attKey.get());
final QNm qName = getName();
if (name.equals(qName)) {
if (getValue().equals(value)) {
throw new SirixUsageException("Duplicate attribute!");
} else {
setValue(value);
}
}
moveToParent();
}
// Get the path node key.
final long pathNodeKey = mNodeReader.mResourceManager.getResourceConfig().mPathSummary ? mPathSummaryWriter.getPathNodeKey(name, Kind.ATTRIBUTE) : 0;
final byte[] attValue = getBytes(value);
final Optional<SirixDeweyID> id = newAttributeID();
final long elementKey = getCurrentNode().getNodeKey();
final AttributeNode node = mNodeFactory.createAttributeNode(elementKey, name, attValue, pathNodeKey, id);
final Node parentNode = (Node) getPageTransaction().prepareEntryForModification(node.getParentKey(), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
((ElementNode) parentNode).insertAttribute(node.getNodeKey(), node.getPrefixKey() + node.getLocalNameKey());
mNodeReader.setCurrentNode(node);
adaptHashesWithAdd();
// Index text value.
mIndexController.notifyChange(ChangeType.INSERT, node, pathNodeKey);
if (move == Movement.TOPARENT) {
moveToParent();
}
return this;
} else {
throw new SirixUsageException("Insert is not allowed if current node is not an ElementNode!");
}
} finally {
unLock();
}
}
Aggregations