use of org.exist.storage.dom.DOMTransaction in project exist by eXist-db.
the class NativeBroker method sync.
@Override
public void sync(final Sync syncEvent) {
if (isReadOnly()) {
return;
}
try {
new DOMTransaction(this, domDb, () -> lockManager.acquireBtreeWriteLock(domDb.getLockName())) {
@Override
public Object start() {
try {
domDb.flush();
} catch (final DBException e) {
LOG.error("error while flushing dom.dbx", e);
}
return null;
}
}.run();
if (syncEvent == Sync.MAJOR) {
try (final ManagedLock<ReentrantLock> collectionsDbLock = lockManager.acquireBtreeWriteLock(collectionsDb.getLockName())) {
collectionsDb.flush();
} catch (final LockException e) {
LOG.error("Failed to acquire lock on {}", FileUtils.fileName(collectionsDb.getFile()), e);
}
notifySync();
pool.getIndexManager().sync();
if (System.currentTimeMillis() > nextReportTS) {
final NumberFormat nf = NumberFormat.getNumberInstance();
LOG_STATS.info("Memory: {}K total; {}K max; {}K free", nf.format(run.totalMemory() / 1024), nf.format(run.maxMemory() / 1024), nf.format(run.freeMemory() / 1024));
domDb.printStatistics();
collectionsDb.printStatistics();
notifyPrintStatistics();
// occurs after 10 minutes from now
nextReportTS = System.currentTimeMillis() + (10 * 60 * 1000);
}
}
} catch (final DBException dbe) {
dbe.printStackTrace();
LOG.error(dbe);
}
}
use of org.exist.storage.dom.DOMTransaction in project exist by eXist-db.
the class NativeBroker method insertNodeAfter.
/**
* Physically insert a node into the DOM storage.
*/
@Override
public void insertNodeAfter(final Txn transaction, final NodeHandle previous, final IStoredNode node) {
final byte[] data = node.serialize();
final DocumentImpl doc = previous.getOwnerDocument();
new DOMTransaction(this, domDb, () -> lockManager.acquireBtreeWriteLock(domDb.getLockName()), doc) {
@Override
public Object start() {
long address = previous.getInternalAddress();
if (address != BFile.UNKNOWN_ADDRESS) {
address = domDb.insertAfter(transaction, doc, address, data);
} else {
final NodeRef ref = new NodeRef(doc.getDocId(), previous.getNodeId());
address = domDb.insertAfter(transaction, doc, ref, data);
}
node.setInternalAddress(address);
return null;
}
}.run();
ByteArrayPool.releaseByteArray(data);
}
use of org.exist.storage.dom.DOMTransaction in project exist by eXist-db.
the class NativeBroker method dropCollectionIndex.
private void dropCollectionIndex(final Txn transaction, @EnsureLocked(mode = LockMode.WRITE_LOCK) final Collection collection, final boolean reindex) throws PermissionDeniedException, IOException, LockException {
if (isReadOnly()) {
throw new IOException(DATABASE_IS_READ_ONLY);
}
if (!collection.getPermissionsNoLock().validate(getCurrentSubject(), Permission.WRITE)) {
throw new PermissionDeniedException("Account " + getCurrentSubject().getName() + " have insufficient privileges on collection " + collection.getURI());
}
notifyDropIndex(collection);
getIndexController().removeCollection(collection, this, reindex);
for (final Iterator<DocumentImpl> i = collection.iterator(this); i.hasNext(); ) {
final DocumentImpl doc = i.next();
LOG.debug("Dropping index for document {}", doc.getFileURI());
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);
domDb.flush();
} catch (final TerminatedException | IOException | DBException e) {
LOG.error("Error while removing Document '{}' from Collection index: {}", doc.getURI().lastSegment(), collection.getURI(), e);
}
return null;
}
}.run();
}
}
use of org.exist.storage.dom.DOMTransaction in project exist by eXist-db.
the class NativeBroker method removeNode.
/**
* Removes the Node Reference from the database.
* The index will be updated later, i.e. after all nodes have been physically
* removed. See {@link #endRemove(org.exist.storage.txn.Txn)}.
* removeNode() just adds the node ids to the list in elementIndex
* for later removal.
*/
@Override
public <T extends IStoredNode> void removeNode(final Txn transaction, final IStoredNode<T> node, final NodePath currentPath, final String content) {
final DocumentImpl doc = node.getOwnerDocument();
new DOMTransaction(this, domDb, () -> lockManager.acquireBtreeWriteLock(domDb.getLockName()), doc) {
@Override
public Object start() {
final long address = node.getInternalAddress();
if (StorageAddress.hasAddress(address)) {
domDb.remove(transaction, new NodeRef(doc.getDocId(), node.getNodeId()), address);
} else {
domDb.remove(transaction, new NodeRef(doc.getDocId(), node.getNodeId()));
}
return null;
}
}.run();
notifyRemoveNode(node, currentPath, content);
final QName qname;
switch(node.getNodeType()) {
case Node.ELEMENT_NODE:
qname = new QName(node.getQName(), ElementValue.ELEMENT);
node.setQName(qname);
final GeneralRangeIndexSpec spec1 = doc.getCollection().getIndexByPathConfiguration(this, currentPath);
if (spec1 != null) {
valueIndex.setDocument(doc);
valueIndex.storeElement((ElementImpl) node, content, spec1.getType(), NativeValueIndex.IndexType.GENERIC, false);
}
final QNameRangeIndexSpec qnSpecElement = doc.getCollection().getIndexByQNameConfiguration(this, qname);
if (qnSpecElement != null) {
valueIndex.setDocument(doc);
valueIndex.storeElement((ElementImpl) node, content, qnSpecElement.getType(), NativeValueIndex.IndexType.QNAME, false);
}
break;
case Node.ATTRIBUTE_NODE:
qname = new QName(node.getQName(), ElementValue.ATTRIBUTE);
node.setQName(qname);
currentPath.addComponent(qname);
// Strange : does it mean that the node is added 2 times under 2 different identities ?
final AttrImpl attr;
attr = (AttrImpl) node;
switch(attr.getType()) {
case AttrImpl.ID:
valueIndex.setDocument(doc);
valueIndex.storeAttribute(attr, attr.getValue(), Type.ID, NativeValueIndex.IndexType.GENERIC, false);
break;
case AttrImpl.IDREF:
valueIndex.setDocument(doc);
valueIndex.storeAttribute(attr, attr.getValue(), Type.IDREF, NativeValueIndex.IndexType.GENERIC, false);
break;
case AttrImpl.IDREFS:
valueIndex.setDocument(doc);
final StringTokenizer tokenizer = new StringTokenizer(attr.getValue(), " ");
while (tokenizer.hasMoreTokens()) {
valueIndex.storeAttribute(attr, tokenizer.nextToken(), Type.IDREF, NativeValueIndex.IndexType.GENERIC, false);
}
break;
default:
}
final RangeIndexSpec spec2 = doc.getCollection().getIndexByPathConfiguration(this, currentPath);
if (spec2 != null) {
valueIndex.setDocument(doc);
valueIndex.storeAttribute(attr, null, spec2, false);
}
final QNameRangeIndexSpec qnSpecAttribute = doc.getCollection().getIndexByQNameConfiguration(this, qname);
if (qnSpecAttribute != null) {
valueIndex.setDocument(doc);
valueIndex.storeAttribute(attr, null, qnSpecAttribute, false);
}
currentPath.removeLastComponent();
break;
case Node.TEXT_NODE:
break;
}
}
use of org.exist.storage.dom.DOMTransaction in project exist by eXist-db.
the class NativeBroker method checkXMLResourceTree.
/**
* consistency Check of the database; useful after XUpdates;
* called by {@link #checkXMLResourceConsistency(DocumentImpl)}
*/
@Override
public void checkXMLResourceTree(final DocumentImpl doc) {
LOG.debug("Checking DOM tree for document {}", doc.getFileURI());
boolean xupdateConsistencyChecks = false;
final Object property = pool.getConfiguration().getProperty(PROPERTY_XUPDATE_CONSISTENCY_CHECKS);
if (property != null) {
xupdateConsistencyChecks = (Boolean) property;
}
if (xupdateConsistencyChecks) {
new DOMTransaction(this, domDb, () -> lockManager.acquireBtreeReadLock(domDb.getLockName())) {
@Override
public Object start() throws ReadOnlyException {
LOG.debug("Pages used: {}", domDb.debugPages(doc, false));
return null;
}
}.run();
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();
final StringBuilder buf = new StringBuilder();
// Pass buf to the following method to get a dump of all node ids in the document
if (!checkNodeTree(iterator, node, buf)) {
LOG.debug("node tree: {}", buf.toString());
throw new RuntimeException("Error in document tree structure");
}
} catch (final IOException e) {
LOG.error(e);
}
}
final NodeRef ref = new NodeRef(doc.getDocId());
final IndexQuery idx = new IndexQuery(IndexQuery.TRUNC_RIGHT, ref);
new DOMTransaction(this, domDb, () -> lockManager.acquireBtreeReadLock(domDb.getLockName())) {
@Override
public Object start() {
try {
domDb.findKeys(idx);
} catch (final BTreeException | IOException e) {
LOG.error("start() - " + "error while removing doc", e);
}
return null;
}
}.run();
}
}
Aggregations