Permalink
Browse files

[performance] Faster insertion or addition of nodes using update exte…

…nsions: eXist always reindexed the parent node, which should only be required if an index is defined on the parent or any of its ancestors. This caused a major bottleneck.
  • Loading branch information...
1 parent 4a52641 commit 4bcade824108acfbc7912c15c56363d3cc6d0304 @wolfgangmm wolfgangmm committed Feb 26, 2014
View
2 extensions/indexes/lucene/src/org/exist/indexing/lucene/LuceneIndexWorker.java
@@ -202,7 +202,7 @@ public int getMode() {
return this.mode;
}
- public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean includeSelf) {
+ public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean insert, boolean includeSelf) {
if (node.getNodeType() == Node.ATTRIBUTE_NODE)
return null;
if (config == null)
View
2 extensions/indexes/ngram/src/org/exist/indexing/ngram/NGramIndexWorker.java
@@ -512,7 +512,7 @@ public MatchListener getMatchListener(DBBroker broker, NodeProxy proxy, NGramMat
}
@Override
- public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean includeSelf) {
+ public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean insert, boolean includeSelf) {
if (node.getNodeType() == Node.ATTRIBUTE_NODE)
return null;
IndexSpec indexConf = node.getDocument().getCollection().getIndexConfiguration(broker);
View
2 extensions/indexes/range/src/org/exist/indexing/range/RangeIndexWorker.java
@@ -255,7 +255,7 @@ public int getMode() {
}
@Override
- public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean includeSelf) {
+ public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean insert, boolean includeSelf) {
// if (node.getNodeType() == Node.ATTRIBUTE_NODE)
// return null;
if (config == null)
View
4 extensions/indexes/sort/src/org/exist/indexing/sort/SortIndexWorker.java
@@ -362,8 +362,8 @@ public int getMode() {
return mode;
}
- public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean includeSelf) {
- return node;
+ public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean insert, boolean includeSelf) {
+ return insert ? null : node;
}
public StreamListener getListener() {
View
2 extensions/indexes/spatial/src/org/exist/indexing/spatial/AbstractGMLJDBCIndexWorker.java
@@ -222,7 +222,7 @@ public MatchListener getMatchListener(DBBroker broker, NodeProxy proxy) {
return null;
}
- public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean includeSelf) {
+ public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean insert, boolean includeSelf) {
if (!isDocumentGMLAware)
//Not concerned
return null;
View
16 src/org/exist/dom/ElementImpl.java
@@ -475,8 +475,9 @@ public void appendChildren(Txn transaction, NodeList nodes, int child) throws DO
StreamListener listener = null;
//May help getReindexRoot() to make some useful things
broker.getIndexController().setDocument(ownerDocument);
- final StoredNode reindexRoot = broker.getIndexController().getReindexRoot(this, path);
+ StoredNode reindexRoot = broker.getIndexController().getReindexRoot(this, path, true, true);
broker.getIndexController().setMode(StreamListener.STORE);
+ // only reindex if reindexRoot is an ancestor of the current node
if (reindexRoot == null) {
listener = broker.getIndexController().getStreamListener();
}
@@ -1222,7 +1223,7 @@ public void insertBefore(Txn transaction, NodeList nodes, Node refChild) throws
StreamListener listener = null;
//May help getReindexRoot() to make some useful things
broker.getIndexController().setDocument(ownerDocument);
- final StoredNode reindexRoot = broker.getIndexController().getReindexRoot(this, path, true);
+ final StoredNode reindexRoot = broker.getIndexController().getReindexRoot(this, path, true, true);
broker.getIndexController().setMode(StreamListener.STORE);
if (reindexRoot == null) {
listener = broker.getIndexController().getStreamListener();
@@ -1272,7 +1273,8 @@ public void insertAfter(Txn transaction, NodeList nodes, Node refChild) throws D
StreamListener listener = null;
//May help getReindexRoot() to make some useful things
broker.getIndexController().setDocument(ownerDocument);
- final StoredNode reindexRoot = broker.getIndexController().getReindexRoot(this, path, true);
+ final StoredNode reindexRoot = broker.getIndexController().getReindexRoot(this, path, true, true);
+ System.out.println("Reindex root after insert: " + reindexRoot);
broker.getIndexController().setMode(StreamListener.STORE);
if (reindexRoot == null) {
listener = broker.getIndexController().getStreamListener();
@@ -1311,7 +1313,7 @@ public void update(Txn transaction, NodeList newContent) throws DOMException {
try {
broker = ownerDocument.getBrokerPool().get(null);
broker.getIndexController().setDocument(ownerDocument);
- final StoredNode reindexRoot = broker.getIndexController().getReindexRoot(this, path, true);
+ final StoredNode reindexRoot = broker.getIndexController().getReindexRoot(this, path, true, true);
broker.getIndexController().setMode(StreamListener.REMOVE_SOME_NODES);
if (reindexRoot == null) {
listener = broker.getIndexController().getStreamListener();
@@ -1395,7 +1397,7 @@ public StoredNode updateChild(Txn transaction, Node oldChild, Node newChild) thr
//May help getReindexRoot() to make some useful things
broker.getIndexController().setDocument(ownerDocument);
//Check if the change affects any ancestor nodes, which then need to be reindexed later
- StoredNode reindexRoot = broker.getIndexController().getReindexRoot(oldNode, oldPath);
+ StoredNode reindexRoot = broker.getIndexController().getReindexRoot(oldNode, oldPath, false);
//Remove indexes
if (reindexRoot == null)
{reindexRoot = oldNode;}
@@ -1445,7 +1447,7 @@ public Node removeChild(Txn transaction, Node oldChild) throws DOMException {
//May help getReindexRoot() to make some useful things
broker = ownerDocument.getBrokerPool().get(null);
broker.getIndexController().setDocument(ownerDocument);
- final StoredNode reindexRoot = broker.getIndexController().getReindexRoot(oldNode, oldPath);
+ final StoredNode reindexRoot = broker.getIndexController().getReindexRoot(oldNode, oldPath, false);
broker.getIndexController().setMode(StreamListener.REMOVE_SOME_NODES);
if (reindexRoot == null) {
listener = broker.getIndexController().getStreamListener();
@@ -1580,7 +1582,7 @@ public Node replaceChild(Txn transaction, Node newChild, Node oldChild) throws D
try {
broker = ownerDocument.getBrokerPool().get(null);
broker.getIndexController().setDocument(ownerDocument);
- final StoredNode reindexRoot = broker.getIndexController().getReindexRoot(oldNode, oldPath);
+ final StoredNode reindexRoot = broker.getIndexController().getReindexRoot(oldNode, oldPath, false);
broker.getIndexController().setMode(StreamListener.REMOVE_SOME_NODES);
if (reindexRoot == null) {
listener = broker.getIndexController().getStreamListener();
View
2 src/org/exist/fulltext/FTIndexWorker.java
@@ -126,7 +126,7 @@ public int getMode() {
return mode;
}
- public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean includeSelf) {
+ public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean insert, boolean includeSelf) {
if (node.getNodeType() == Node.ATTRIBUTE_NODE)
{return null;}
final IndexSpec indexConf = node.getDocument().getCollection().getIndexConfiguration(broker);
View
21 src/org/exist/indexing/IndexController.java
@@ -224,36 +224,33 @@ public void reindex(Txn transaction, StoredNode reindexRoot, int mode) {
/**
* When adding or removing nodes to or from the document tree, it might become
* necessary to re-index some parts of the tree, in particular if indexes are defined
- * on mixed content nodes. This method will call
- * {@link IndexWorker#getReindexRoot(org.exist.dom.StoredNode, org.exist.storage.NodePath, boolean)}
- * on each configured index. It will then return the top-most root.
+ * on mixed content nodes. This method will return the top-most root.
*
* @param node the node to be modified.
* @param path the NodePath of the node
* @return the top-most root node to be re-indexed
*/
- public StoredNode getReindexRoot(StoredNode node, NodePath path) {
- return getReindexRoot(node, path, false);
+ public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean insert) {
+ return getReindexRoot(node, path, insert, false);
}
/**
* When adding or removing nodes to or from the document tree, it might become
* necessary to re-index some parts of the tree, in particular if indexes are defined
- * on mixed content nodes. This method will call
- * {@link IndexWorker#getReindexRoot(org.exist.dom.StoredNode, org.exist.storage.NodePath, boolean)}
- * on each configured index. It will then return the top-most root.
+ * on mixed content nodes. This method will return the top-most root.
*
* @param node the node to be modified.
* @param path path the NodePath of the node
* @param includeSelf if set to true, the current node itself will be included in the check
* @return the top-most root node to be re-indexed
*/
- public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean includeSelf) {
+ public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean insert, boolean includeSelf) {
StoredNode next, top = null;
for (final IndexWorker indexWorker : indexWorkers.values()) {
- next = indexWorker.getReindexRoot(node, path, includeSelf);
- if (next != null && (top == null || top.getNodeId().isDescendantOf(next.getNodeId())))
- {top = next;}
+ next = indexWorker.getReindexRoot(node, path, insert, includeSelf);
+ if (next != null && (top == null || top.getNodeId().isDescendantOf(next.getNodeId()))) {
+ top = next;
+ }
}
if (top != null && top.getNodeId().equals(node.getNodeId()))
{top = node;}
View
9 src/org/exist/indexing/IndexWorker.java
@@ -128,16 +128,17 @@ Object configure(IndexController controller, NodeList configNodes,
/**
* When adding or removing nodes to or from the document tree, it might become
* necessary to re-index some parts of the tree, in particular if indexes are defined
- * on mixed content nodes. This method will call
- * {@link IndexWorker#getReindexRoot(org.exist.dom.StoredNode, org.exist.storage.NodePath, boolean)}
- * on each configured index. It will then return the top-most root.
+ * on mixed content nodes. It will then return the top-most root.
*
* @param node the node to be modified.
* @param path path the NodePath of the node
+ * @param insert true if a node is being inserted or appended. In this case, the method
+ * will be called with the parent node as first argument. Usually a reindex is
+ * not required unless the index is defined on the parent node or an ancestor of it.
* @param includeSelf if set to true, the current node itself will be included in the check
* @return the top-most root node to be reindexed
*/
- StoredNode getReindexRoot(StoredNode node, NodePath path, boolean includeSelf);
+ StoredNode getReindexRoot(StoredNode node, NodePath path, boolean insert, boolean includeSelf);
/**
* Return a stream listener to index the current document in the current mode.
View
2 src/org/exist/storage/statistics/IndexStatisticsWorker.java
@@ -92,7 +92,7 @@ public int getMode() {
return mode;
}
- public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean includeSelf) {
+ public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean insert, boolean includeSelf) {
return null;
}
View
5 src/org/exist/storage/structural/NativeStructuralIndexWorker.java
@@ -364,8 +364,9 @@ public int getMode() {
return mode;
}
- public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean includeSelf) {
- return node;
+ public StoredNode getReindexRoot(StoredNode node, NodePath path, boolean insert, boolean includeSelf) {
+ // if a node is inserted, we do not need to reindex the parent
+ return insert ? null : node;
}
private NativeStructuralStreamListener listener = new NativeStructuralStreamListener();

0 comments on commit 4bcade8

Please sign in to comment.