You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by ju...@apache.org on 2014/04/16 05:01:50 UTC

svn commit: r1587787 - /jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java

Author: jukka
Date: Wed Apr 16 03:01:50 2014
New Revision: 1587787

URL: http://svn.apache.org/r1587787
Log:
OAK-1722: Use a shared IndexSearcher for performing Lucene queries

Improve concurrency of IndexTracker based on suggestion by Chetan.

Modified:
    jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java

Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java?rev=1587787&r1=1587786&r2=1587787&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java Wed Apr 16 03:01:50 2014
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.oak.plugins.index.lucene;
 
+import static com.google.common.collect.Iterables.addAll;
 import static com.google.common.collect.Lists.newArrayList;
 import static com.google.common.collect.Lists.newArrayListWithCapacity;
 import static com.google.common.collect.Maps.newHashMap;
@@ -39,8 +40,6 @@ import org.apache.jackrabbit.oak.spi.sta
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.Iterables;
-
 class IndexTracker {
 
     /** Logger instance. */
@@ -62,36 +61,60 @@ class IndexTracker {
         indices.clear();
     }
 
-    synchronized void update(NodeState root) {
-        List<Editor> editors = newArrayListWithCapacity(indices.size());
-        for (final String path : indices.keySet()) {
-            List<String> elements = newArrayList();
-            Iterables.addAll(elements, PathUtils.elements(path));
-            elements.add(INDEX_DEFINITIONS_NAME);
-            elements.add(indices.get(path).getName());
-            editors.add(new SubtreeEditor(new DefaultEditor() {
-                @Override
-                public void leave(NodeState before, NodeState after) {
-                    IndexNode index = indices.remove(path);
-                    try {
-                        index.close();
-                    } catch (IOException e) {
-                        log.error("Failed to close Lucene index at " + path, e);
-                    }
+    void update(NodeState root) {
+        Editor editor;
+        NodeState before;
+
+        synchronized (this) {
+            before = this.root;
+            this.root = root;
+
+            List<Editor> editors = newArrayListWithCapacity(indices.size());
+            for (Map.Entry<String, IndexNode> entry : indices.entrySet()) {
+                final String path = entry.getKey();
+                IndexNode index = entry.getValue();
+
+                List<String> elements = newArrayList();
+                addAll(elements, PathUtils.elements(path));
+                elements.add(INDEX_DEFINITIONS_NAME);
+                elements.add(index.getName());
+                editors.add(new SubtreeEditor(
+                        new DefaultEditor() {
+                            @Override
+                            public void leave(NodeState before, NodeState after) {
+                                updateIndex(path, after);
+                            }
+                        },
+                        elements.toArray(new String[elements.size()])));
+            }
+            editor = CompositeEditor.compose(editors);
+        }
 
-                    try {
-                        index = IndexNode.open(index.getName(), after);
-                        if (index != null) {
-                            indices.put(path, index);
-                        }
-                    } catch (IOException e) {
-                        log.error("Failed to open Lucene index at " + path, e);
-                    }
-                }
-            }, elements.toArray(new String[elements.size()])));
+        // outside the synchronization block to avoid blocking index access
+        EditorDiff.process(editor, before, root); // ignore return value
+    }
+
+    private synchronized void updateIndex(String path, NodeState state) {
+        IndexNode index = indices.remove(path);
+        try {
+            if (index != null) {
+                index.close();
+            } else {
+                return; // this tracker has already been closed
+            }
+        } catch (IOException e) {
+            log.error("Failed to close Lucene index at " + path, e);
+        }
+
+        try {
+            // TODO: Use DirectoryReader.openIfChanged()
+            index = IndexNode.open(index.getName(), state);
+            if (index != null) { // the index might no longer exist
+                indices.put(path, index);
+            }
+        } catch (IOException e) {
+            log.error("Failed to open Lucene index at " + path, e);
         }
-        EditorDiff.process(CompositeEditor.compose(editors), this.root, root);
-        this.root = root;
     }
 
     synchronized IndexNode getIndexNode(String path) {