jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mreut...@apache.org
Subject svn commit: r706649 - in /jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene: MultiIndex.java SearchIndex.java
Date Tue, 21 Oct 2008 15:07:08 GMT
Author: mreutegg
Date: Tue Oct 21 08:07:08 2008
New Revision: 706649

URL: http://svn.apache.org/viewvc?rev=706649&view=rev
Log:
JCR-1820: Ensure queries are not blocked during large updates

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java?rev=706649&r1=706648&r2=706649&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java
Tue Oct 21 08:07:08 2008
@@ -35,7 +35,6 @@
 import org.apache.lucene.document.Document;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.Term;
-import org.apache.commons.collections.iterators.EmptyIterator;
 
 import javax.jcr.RepositoryException;
 import java.io.IOException;
@@ -50,6 +49,7 @@
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Collection;
+import java.util.Collections;
 
 /**
  * A <code>MultiIndex</code> consists of a {@link VolatileIndex} and multiple
@@ -406,14 +406,18 @@
      * Atomically updates the index by removing some documents and adding
      * others.
      *
-     * @param remove Iterator of <code>UUID</code>s that identify documents to
+     * @param remove collection of <code>UUID</code>s that identify documents
to
      *               remove
-     * @param add    Iterator of <code>Document</code>s to add. Calls to
-     *               <code>next()</code> on this iterator may return
-     *               <code>null</code>, to indicate that a node could not be
-     *               indexed successfully.
-     */
-    synchronized void update(Iterator remove, Iterator add) throws IOException {
+     * @param add    collection of <code>Document</code>s to add. Some of the
+     *               elements in this collection may be <code>null</code>, to
+     *               indicate that a node could not be indexed successfully.
+     */
+    synchronized void update(Collection remove, Collection add) throws IOException {
+        // make sure a reader is available during long updates
+        if (add.size() > handler.getBufferSize()) {
+            getIndexReader().release();
+        }
+
         synchronized (updateMonitor) {
             updateInProgress = true;
         }
@@ -422,11 +426,11 @@
             executeAndLog(new Start(transactionId));
 
             boolean flush = false;
-            while (remove.hasNext()) {
-                executeAndLog(new DeleteNode(transactionId, (UUID) remove.next()));
+            for (Iterator it = remove.iterator(); it.hasNext(); ) {
+                executeAndLog(new DeleteNode(transactionId, (UUID) it.next()));
             }
-            while (add.hasNext()) {
-                Document doc = (Document) add.next();
+            for (Iterator it = add.iterator(); it.hasNext(); ) {
+                Document doc = (Document) it.next();
                 if (doc != null) {
                     executeAndLog(new AddNode(transactionId, doc));
                     // commit volatile index if needed
@@ -456,8 +460,7 @@
      *                     index.
      */
     void addDocument(Document doc) throws IOException {
-        List add = Arrays.asList(new Document[]{doc});
-        update(EmptyIterator.INSTANCE, add.iterator());
+        update(Collections.EMPTY_LIST, Arrays.asList(new Document[]{doc}));
     }
 
     /**
@@ -467,8 +470,7 @@
      * @throws IOException if an error occurs while deleting the document.
      */
     void removeDocument(UUID uuid) throws IOException {
-        List remove = Arrays.asList(new UUID[]{uuid});
-        update(remove.iterator(), EmptyIterator.INSTANCE);
+        update(Arrays.asList(new UUID[]{uuid}), Collections.EMPTY_LIST);
     }
 
     /**
@@ -1196,8 +1198,7 @@
             }
 
             try {
-                update(finished.keySet().iterator(),
-                        finished.values().iterator());
+                update(finished.keySet(), finished.values());
             } catch (IOException e) {
                 // update failed
                 log.warn("Failed to update index with deferred text extraction", e);

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java?rev=706649&r1=706648&r2=706649&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
Tue Oct 21 08:07:08 2008
@@ -56,7 +56,10 @@
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.Fieldable;
-import org.apache.commons.collections.iterators.AbstractIteratorDecorator;
+import org.apache.commons.collections.iterators.TransformIterator;
+import org.apache.commons.collections.collection.TransformedCollection;
+import org.apache.commons.collections.IteratorUtils;
+import org.apache.commons.collections.Transformer;
 import org.xml.sax.SAXException;
 import org.w3c.dom.Element;
 
@@ -77,6 +80,7 @@
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Collection;
 
 /**
  * Implements a {@link org.apache.jackrabbit.core.query.QueryHandler} using
@@ -522,7 +526,7 @@
 
     /**
      * This implementation forwards the call to
-     * {@link MultiIndex#update(java.util.Iterator, java.util.Iterator)} and
+     * {@link MultiIndex#update(Collection, Collection)} and
      * transforms the two iterators to the required types.
      *
      * @param remove uuids of nodes to remove.
@@ -536,62 +540,66 @@
             throws RepositoryException, IOException {
         checkOpen();
         final Map aggregateRoots = new HashMap();
-        final Set removedNodeIds = new HashSet();
-        final Set addedNodeIds = new HashSet();
-        index.update(new AbstractIteratorDecorator(remove) {
-            public Object next() {
-                NodeId nodeId = (NodeId) super.next();
-                removedNodeIds.add(nodeId);
-                return nodeId.getUUID();
-            }
-        }, new AbstractIteratorDecorator(add) {
-            public Object next() {
-                NodeState state = (NodeState) super.next();
-                if (state == null) {
-                    return null;
-                }
-                addedNodeIds.add(state.getNodeId());
-                removedNodeIds.remove(state.getNodeId());
-                Document doc = null;
-                try {
-                    doc = createDocument(state, getNamespaceMappings(),
-                            index.getIndexFormatVersion());
-                    retrieveAggregateRoot(state, aggregateRoots);
-                } catch (RepositoryException e) {
-                    log.warn("Exception while creating document for node: "
-                            + state.getNodeId() + ": " + e.toString());
-                }
-                return doc;
-            }
-        });
+        final HashSet removedUUIDs = new HashSet();
+        final Set addedUUIDs = new HashSet();
+
+        index.update(IteratorUtils.toList(new TransformIterator(remove,
+                new Transformer() {
+                    public Object transform(Object input) {
+                        UUID uuid = ((NodeId) input).getUUID();
+                        removedUUIDs.add(uuid);
+                        return uuid;
+                    }
+                })), IteratorUtils.toList(new TransformIterator(add,
+                new Transformer() {
+                    public Object transform(Object input) {
+                        NodeState state = (NodeState) input;
+                        if (state == null) {
+                            return null;
+                        }
+                        UUID uuid = state.getNodeId().getUUID();
+                        addedUUIDs.add(uuid);
+                        removedUUIDs.remove(uuid);
+                        Document doc = null;
+                        try {
+                            doc = createDocument(state, getNamespaceMappings(),
+                                    index.getIndexFormatVersion());
+                            retrieveAggregateRoot(state, aggregateRoots);
+                        } catch (RepositoryException e) {
+                            log.warn("Exception while creating document for node: "
+                                    + state.getNodeId() + ": " + e.toString());
+                        }
+                        return doc;
+                    }
+                })));
 
         // remove any aggregateRoot nodes that are new
         // and therefore already up-to-date
-        aggregateRoots.keySet().removeAll(addedNodeIds);
+        aggregateRoots.keySet().removeAll(addedUUIDs);
 
-        // based on removed NodeIds get affected aggregate root nodes
-        retrieveAggregateRoot(removedNodeIds, aggregateRoots);
+        // based on removed UUIDs get affected aggregate root nodes
+        retrieveAggregateRoot(removedUUIDs, aggregateRoots);
 
         // update aggregates if there are any affected
         if (aggregateRoots.size() > 0) {
-            index.update(new AbstractIteratorDecorator(
-                    aggregateRoots.keySet().iterator()) {
-                public Object next() {
-                    return ((NodeId) super.next()).getUUID();
-                }
-            }, new AbstractIteratorDecorator(aggregateRoots.values().iterator()) {
-                public Object next() {
-                    NodeState state = (NodeState) super.next();
-                    try {
-                        return createDocument(state, getNamespaceMappings(),
-                                index.getIndexFormatVersion());
-                    } catch (RepositoryException e) {
-                        log.warn("Exception while creating document for node: "
-                                + state.getNodeId() + ": " + e.toString());
-                    }
-                    return null;
-                }
-            });
+            Collection modified = TransformedCollection.decorate(
+                    new ArrayList(),
+                    new Transformer() {
+                        public Object transform(Object input) {
+                            NodeState state = (NodeState) input;
+                            try {
+                                return createDocument(state,
+                                        getNamespaceMappings(),
+                                        index.getIndexFormatVersion());
+                            } catch (RepositoryException e) {
+                                log.warn("Exception while creating document for node: "
+                                        + state.getNodeId() + ": " + e.toString());
+                            }
+                            return null;
+                        }
+                    });
+            modified.addAll(aggregateRoots.values());
+            index.update(aggregateRoots.keySet(), modified);
         }
     }
 
@@ -1143,7 +1151,7 @@
      *
      * @param state the node state for which we want to retrieve the aggregate
      *              root.
-     * @param map   aggregate roots are collected in this map. Key=NodeId,
+     * @param map   aggregate roots are collected in this map. Key=UUID,
      *              value=NodeState.
      */
     protected void retrieveAggregateRoot(NodeState state, Map map) {
@@ -1156,7 +1164,7 @@
                 for (int i = 0; i < aggregateRules.length; i++) {
                     NodeState root = aggregateRules[i].getAggregateRoot(state);
                     if (root != null) {
-                        map.put(root.getNodeId(), root);
+                        map.put(root.getNodeId().getUUID(), root);
                         break;
                     }
                 }
@@ -1168,14 +1176,14 @@
     }
 
     /**
-     * Retrieves the root of the indexing aggregate for <code>removedNodeIds</code>
+     * Retrieves the root of the indexing aggregate for <code>removedUUIDs</code>
      * and puts it into <code>map</code>.
      *
-     * @param removedNodeIds the ids of removed nodes.
+     * @param removedUUIDs   the UUIDs of removed nodes.
      * @param map            aggregate roots are collected in this map.
-     *                       Key=NodeId, value=NodeState.
+     *                       Key=UUID, value=NodeState.
      */
-    protected void retrieveAggregateRoot(Set removedNodeIds, Map map) {
+    protected void retrieveAggregateRoot(Set removedUUIDs, Map map) {
         if (indexingConfig != null) {
             AggregateRule[] aggregateRules = indexingConfig.getAggregateRules();
             if (aggregateRules == null) {
@@ -1191,17 +1199,17 @@
                     TermDocs tDocs = reader.termDocs();
                     try {
                         ItemStateManager ism = getContext().getItemStateManager();
-                        Iterator it = removedNodeIds.iterator();
+                        Iterator it = removedUUIDs.iterator();
                         while (it.hasNext()) {
-                            NodeId id = (NodeId) it.next();
+                            UUID uuid = (UUID) it.next();
                             aggregateUUIDs = aggregateUUIDs.createTerm(
-                                    id.getUUID().toString());
+                                    uuid.toString());
                             tDocs.seek(aggregateUUIDs);
                             while (tDocs.next()) {
                                 Document doc = reader.document(tDocs.doc(), FieldSelectors.UUID);
-                                String uuid = doc.get(FieldNames.UUID);
-                                NodeId nId = new NodeId(UUID.fromString(uuid));
-                                map.put(nId, ism.getItemState(nId));
+                                NodeId nId = new NodeId(UUID.fromString(
+                                        doc.get(FieldNames.UUID)));
+                                map.put(nId.getUUID(), ism.getItemState(nId));
                                 found++;
                             }
                         }



Mime
View raw message