use of org.exist.storage.dom.DOMTransaction in project exist by eXist-db.
the class NativeBroker method storeNode.
/**
* Store a node into the database. This method is called by the parser to
* write a node to the storage backend.
*
* @param node the node to be stored
* @param currentPath path expression which points to this node's
* element-parent or to itself if it is an element.
*/
@Override
public <T extends IStoredNode> void storeNode(final Txn transaction, final IStoredNode<T> node, final NodePath currentPath, final IndexSpec indexSpec) {
checkAvailableMemory();
final DocumentImpl doc = node.getOwnerDocument();
final short nodeType = node.getNodeType();
final byte[] data = node.serialize();
new DOMTransaction(this, domDb, () -> lockManager.acquireBtreeWriteLock(domDb.getLockName()), doc) {
@Override
public Object start() throws ReadOnlyException {
final long address;
if (nodeType == Node.TEXT_NODE || nodeType == Node.ATTRIBUTE_NODE || nodeType == Node.CDATA_SECTION_NODE || node.getNodeId().getTreeLevel() > defaultIndexDepth) {
address = domDb.add(transaction, data);
} else {
address = domDb.put(transaction, new NodeRef(doc.getDocId(), node.getNodeId()), data);
}
if (address == BFile.UNKNOWN_ADDRESS) {
LOG.error("address is missing");
}
// TODO : how can we continue here ? -pb
node.setInternalAddress(address);
return null;
}
}.run();
++nodesCount;
ByteArrayPool.releaseByteArray(data);
nodeProcessor.reset(transaction, node, currentPath, indexSpec);
nodeProcessor.doIndex();
}
use of org.exist.storage.dom.DOMTransaction in project exist by eXist-db.
the class NativeBroker method removeCollectionsDocumentNodes.
private void removeCollectionsDocumentNodes(final Txn transaction, @EnsureLocked(mode = LockMode.WRITE_LOCK) final Collection collection) throws TriggerException, PermissionDeniedException, LockException, IOException {
final DocumentTrigger docTrigger = new DocumentTriggers(this, transaction, collection);
for (final Iterator<DocumentImpl> itDocument = collection.iteratorNoLock(this); itDocument.hasNext(); ) {
// NOTE: we already have a WRITE_LOCK on the collection
final DocumentImpl doc = itDocument.next();
docTrigger.beforeDeleteDocument(this, transaction, doc);
// Remove doc's metadata
// WM: now removed in one step. see above.
// removeResourceMetadata(transaction, doc);
// Remove document nodes' index entries
new DOMTransaction(this, domDb, () -> lockManager.acquireBtreeWriteLock(domDb.getLockName())) {
@Override
public Object start() {
try {
final Value ref = new NodeRef(doc.getDocId());
final IndexQuery query = new IndexQuery(IndexQuery.TRUNC_RIGHT, ref);
domDb.remove(transaction, query, null);
} catch (final BTreeException e) {
LOG.error("btree error while removing document", e);
} catch (final IOException e) {
LOG.error("io error while removing document", e);
} catch (final TerminatedException e) {
LOG.error("method terminated", e);
}
return null;
}
}.run();
// Remove nodes themselves
new DOMTransaction(this, domDb, () -> lockManager.acquireBtreeWriteLock(domDb.getLockName())) {
@Override
public Object start() {
if (doc.getResourceType() == DocumentImpl.XML_FILE) {
final NodeHandle node = (NodeHandle) doc.getFirstChild();
domDb.removeAll(transaction, node.getInternalAddress());
}
return null;
}
}.run();
// if it is a binary document remove the content from disk
if (doc instanceof BinaryDocument) {
removeCollectionBinary(transaction, (BinaryDocument) doc);
}
docTrigger.afterDeleteDocument(this, transaction, doc.getURI());
// Make doc's id available again
collectionsDb.freeResourceId(doc.getDocId());
}
}
use of org.exist.storage.dom.DOMTransaction in project exist by eXist-db.
the class NativeBroker method dropDomNodes.
private void dropDomNodes(final Txn transaction, final DocumentImpl document) {
try {
if (!document.isReferenced()) {
new DOMTransaction(this, domDb, () -> lockManager.acquireBtreeWriteLock(domDb.getLockName())) {
@Override
public Object start() {
final NodeHandle node = (NodeHandle) document.getFirstChild();
domDb.removeAll(transaction, node.getInternalAddress());
return null;
}
}.run();
}
} catch (final NullPointerException npe0) {
LOG.error("Caught NPE in DOMTransaction to actually be able to remove the document.");
}
final NodeRef ref = new NodeRef(document.getDocId());
final IndexQuery idx = new IndexQuery(IndexQuery.TRUNC_RIGHT, ref);
new DOMTransaction(this, domDb, () -> lockManager.acquireBtreeWriteLock(domDb.getLockName())) {
@Override
public Object start() {
try {
domDb.remove(transaction, idx, null);
} catch (final BTreeException | IOException e) {
LOG.error("start() - " + "error while removing doc", e);
} catch (final TerminatedException e) {
LOG.error("method terminated", e);
}
return null;
}
}.run();
}
use of org.exist.storage.dom.DOMTransaction in project exist by eXist-db.
the class NativeBroker method shutdown.
@Override
public void shutdown() {
try {
flush();
sync(Sync.MAJOR);
new DOMTransaction(NativeBroker.this, domDb, () -> lockManager.acquireBtreeWriteLock(domDb.getLockName())) {
@Override
public Object start() {
try {
domDb.close();
} catch (final DBException e) {
LOG.error(e.getMessage(), e);
}
return null;
}
}.run();
try (final ManagedLock<ReentrantLock> collectionsDbLock = lockManager.acquireBtreeWriteLock(collectionsDb.getLockName())) {
collectionsDb.close();
}
notifyClose();
} catch (final Exception e) {
LOG.error(e.getMessage(), e);
} finally {
xmlSerializerPool.close();
}
}
use of org.exist.storage.dom.DOMTransaction in project exist by eXist-db.
the class NativeBroker method defragXMLResource.
@Override
public void defragXMLResource(final Txn transaction, final DocumentImpl doc) {
// TODO : use dedicated function in XmldbURI
if (LOG.isDebugEnabled())
LOG.debug("============> Defragmenting document {}", doc.getURI());
final long start = System.currentTimeMillis();
try {
final long firstChild = doc.getFirstChildAddress();
// dropping old structure index
dropIndex(transaction, doc);
// dropping dom index
final NodeRef ref = new NodeRef(doc.getDocId());
final IndexQuery idx = new IndexQuery(IndexQuery.TRUNC_RIGHT, ref);
new DOMTransaction(this, domDb, () -> lockManager.acquireBtreeWriteLock(domDb.getLockName())) {
@Override
public Object start() {
try {
domDb.remove(transaction, idx, null);
domDb.flush();
} catch (final IOException | DBException e) {
LOG.error("start() - " + "error while removing doc", e);
} catch (final TerminatedException e) {
LOG.error("method terminated", e);
}
return null;
}
}.run();
// create a copy of the old doc to copy the nodes into it
final DocumentImpl tempDoc = new DocumentImpl(pool, doc.getCollection(), doc.getDocId(), doc.getFileURI());
tempDoc.copyOf(this, doc, doc);
final StreamListener listener = getIndexController().getStreamListener(doc, ReindexMode.STORE);
// copy the nodes
final NodeList nodes = doc.getChildNodes();
for (int i = 0; i < nodes.getLength(); i++) {
final IStoredNode<?> node = (IStoredNode<?>) nodes.item(i);
try (final INodeIterator iterator = getNodeIterator(node)) {
iterator.next();
copyNodes(transaction, iterator, node, new NodePath2(), tempDoc, true, listener);
}
}
flush();
// remove the old nodes
new DOMTransaction(this, domDb, () -> lockManager.acquireBtreeWriteLock(domDb.getLockName())) {
@Override
public Object start() {
domDb.removeAll(transaction, firstChild);
try {
domDb.flush();
} catch (final DBException e) {
LOG.error("start() - error while removing doc", e);
}
return null;
}
}.run();
doc.copyChildren(tempDoc);
doc.setSplitCount(0);
doc.setPageCount(tempDoc.getPageCount());
storeXMLResource(transaction, doc);
closeDocument();
if (LOG.isDebugEnabled()) {
LOG.debug("Defragmentation took {} ms.", (System.currentTimeMillis() - start));
}
} catch (final PermissionDeniedException | IOException e) {
LOG.error(e);
}
}
Aggregations