use of org.sirix.page.UnorderedKeyValuePage 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.page.UnorderedKeyValuePage 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.page.UnorderedKeyValuePage in project sirix by sirixdb.
the class XdmNodeWriterTrxImpl method adaptForInsert.
// ////////////////////////////////////////////////////////////
// insert operation
// ////////////////////////////////////////////////////////////
/**
* Adapting everything for insert operations.
*
* @param newNode pointer of the new node to be inserted
* @param insertPos determines the position where to insert
* @param pageKind kind of subtree root page
* @throws SirixIOException if anything weird happens
*/
private void adaptForInsert(final Node newNode, final InsertPos insertPos, final PageKind pageKind) throws SirixIOException {
assert newNode != null;
assert insertPos != null;
assert pageKind != null;
if (newNode instanceof StructNode) {
final StructNode strucNode = (StructNode) newNode;
final StructNode parent = (StructNode) getPageTransaction().prepareEntryForModification(newNode.getParentKey(), pageKind, -1, Optional.<UnorderedKeyValuePage>empty());
parent.incrementChildCount();
if (!((StructNode) newNode).hasLeftSibling()) {
parent.setFirstChildKey(newNode.getNodeKey());
}
if (strucNode.hasRightSibling()) {
final StructNode rightSiblingNode = (StructNode) getPageTransaction().prepareEntryForModification(strucNode.getRightSiblingKey(), pageKind, -1, Optional.<UnorderedKeyValuePage>empty());
rightSiblingNode.setLeftSiblingKey(newNode.getNodeKey());
}
if (strucNode.hasLeftSibling()) {
final StructNode leftSiblingNode = (StructNode) getPageTransaction().prepareEntryForModification(strucNode.getLeftSiblingKey(), pageKind, -1, Optional.<UnorderedKeyValuePage>empty());
leftSiblingNode.setRightSiblingKey(newNode.getNodeKey());
}
}
}
use of org.sirix.page.UnorderedKeyValuePage in project sirix by sirixdb.
the class XdmResourceManager method beginNodeWriteTrx.
@Override
public synchronized XdmNodeWriteTrx beginNodeWriteTrx(@Nonnegative final int maxNodeCount, @Nonnull final TimeUnit timeUnit, @Nonnegative final int maxTime) {
// Checks.
assertAccess(mLastCommittedUberPage.get().getRevision());
if (maxNodeCount < 0 || maxTime < 0) {
throw new SirixUsageException("maxNodeCount may not be < 0!");
}
checkNotNull(timeUnit);
// Make sure not to exceed available number of write transactions.
try {
if (!mWriteSemaphore.tryAcquire(20, TimeUnit.SECONDS)) {
throw new SirixUsageException("No write transaction available, please close the write transaction first.");
}
} catch (final InterruptedException e) {
throw new SirixThreadedException(e);
}
// Create new page write transaction (shares the same ID with the node write trx).
final long currentTrxID = mNodeTrxIDCounter.incrementAndGet();
final int lastRev = mLastCommittedUberPage.get().getRevisionNumber();
final PageWriteTrx<Long, Record, UnorderedKeyValuePage> pageWtx = createPageWriteTransaction(currentTrxID, lastRev, lastRev, Abort.NO);
final Node documentNode = getDocumentNode(pageWtx);
// Create new node write transaction.
final XdmNodeWriteTrx wtx = new XdmNodeWriterTrxImpl(currentTrxID, this, pageWtx, maxNodeCount, timeUnit, maxTime, documentNode);
// Remember node transaction for debugging and safe close.
if (mNodeReaderMap.put(currentTrxID, wtx) != null || mNodePageTrxMap.put(currentTrxID, pageWtx) != null) {
throw new SirixThreadedException("ID generation is bogus because of duplicate ID.");
}
return wtx;
}
use of org.sirix.page.UnorderedKeyValuePage in project sirix by sirixdb.
the class NodeFactoryImpl method createCommentNode.
@Override
public CommentNode createCommentNode(@Nonnegative final long parentKey, @Nonnegative final long leftSibKey, @Nonnegative final long rightSibKey, final byte[] value, final boolean isCompressed, final Optional<SirixDeweyID> id) throws SirixIOException {
final long revision = mPageWriteTrx.getRevisionNumber();
final NodeDelegate nodeDel = new NodeDelegate(mPageWriteTrx.getActualRevisionRootPage().getMaxNodeKey() + 1, parentKey, 0, revision, id);
final boolean compression = isCompressed && value.length > 10;
final byte[] compressedValue = compression ? Compression.compress(value, Deflater.HUFFMAN_ONLY) : value;
final ValNodeDelegate valDel = new ValNodeDelegate(nodeDel, compressedValue, compression);
final StructNodeDelegate structDel = new StructNodeDelegate(nodeDel, Fixed.NULL_NODE_KEY.getStandardProperty(), rightSibKey, leftSibKey, 0, 0);
return (CommentNode) mPageWriteTrx.createEntry(nodeDel.getNodeKey(), new CommentNode(valDel, structDel), PageKind.RECORDPAGE, -1, Optional.<UnorderedKeyValuePage>empty());
}
Aggregations