Author: chetanm
Date: Thu Aug  3 06:27:27 2017
New Revision: 1803951

URL: http://svn.apache.org/viewvc?rev=1803951&view=rev
Log:
OAK-6500 - NRTIndex leaks file handles due to unclosed IndexReader

Refactor IndexNode to IndexNodeManager and IndexNode interface. IndexNodeManager
now returns an impl of IndexNode for acquire call

Added:
    
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNodeManager.java
      - copied, changed from r1803824, 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java
    
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNodeManagerTest.java
   (contents, props changed)
      - copied, changed from r1803824, 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNodeTest.java
Removed:
    
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNodeTest.java
Modified:
    
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java
    
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java
    
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java
    
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/MultiplexingLucenePropertyIndexTest.java

Modified: 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java?rev=1803951&r1=1803950&r2=1803951&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java
 Thu Aug  3 06:27:27 2017
@@ -1,236 +1,57 @@
 /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *   http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
  */
-package org.apache.jackrabbit.oak.plugins.index.lucene;
 
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkState;
+package org.apache.jackrabbit.oak.plugins.index.lucene;
 
 import java.io.IOException;
-import java.util.Collections;
 import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
 
 import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
 
-import com.google.common.collect.Iterables;
-import org.apache.jackrabbit.oak.commons.PathUtils;
-import org.apache.jackrabbit.oak.plugins.index.lucene.hybrid.NRTIndex;
-import org.apache.jackrabbit.oak.plugins.index.lucene.hybrid.NRTIndexFactory;
-import 
org.apache.jackrabbit.oak.plugins.index.lucene.hybrid.ReaderRefreshPolicy;
 import org.apache.jackrabbit.oak.plugins.index.lucene.reader.LuceneIndexReader;
-import 
org.apache.jackrabbit.oak.plugins.index.lucene.reader.LuceneIndexReaderFactory;
 import org.apache.jackrabbit.oak.plugins.index.lucene.writer.LuceneIndexWriter;
-import org.apache.jackrabbit.oak.spi.state.NodeState;
-import org.apache.jackrabbit.oak.commons.benchmark.PerfLogger;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.MultiReader;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.suggest.analyzing.AnalyzingInfixSuggester;
 import org.apache.lucene.store.Directory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class IndexNode {
-    /**
-     * Name of the hidden node under which information about the checkpoints
-     * seen and indexed by each async indexer is kept.
-     */
-    static final String ASYNC = ":async";
-
-    private static final AtomicInteger INDEX_NODE_COUNTER = new 
AtomicInteger();
-
-    private static final PerfLogger PERF_LOGGER =
-            new PerfLogger(LoggerFactory.getLogger(IndexNode.class.getName() + 
".perf"));
-
-    static IndexNode open(String indexPath, NodeState root, NodeState 
defnNodeState,
-                          LuceneIndexReaderFactory readerFactory, @Nullable 
NRTIndexFactory nrtFactory)
-            throws IOException {
-        IndexDefinition definition = new IndexDefinition(root, defnNodeState, 
indexPath);
-        List<LuceneIndexReader> readers = 
readerFactory.createReaders(definition, defnNodeState, indexPath);
-        NRTIndex nrtIndex = nrtFactory != null ? 
nrtFactory.createIndex(definition) : null;
-        if (!readers.isEmpty() || (nrtIndex != null && 
!hasAsyncIndexerRun(root))){
-            return new IndexNode(PathUtils.getName(indexPath), definition, 
readers, nrtIndex);
-        }
-        return null;
-    }
-
-    static boolean hasAsyncIndexerRun(NodeState root) {
-        return root.hasChildNode(ASYNC);
-    }
-
-    private static final Logger log = LoggerFactory.getLogger(IndexNode.class);
-
-    private final List<LuceneIndexReader> readers;
 
-    private final String name;
+public interface IndexNode {
 
-    private final IndexDefinition definition;
+    void release();
 
-    private final ReadWriteLock lock = new ReentrantReadWriteLock();
+    IndexSearcher getSearcher();
 
-    private volatile IndexSearcher indexSearcher;
+    IndexDefinition getDefinition();
 
-    private final NRTIndex nrtIndex;
+    List<LuceneIndexReader> getPrimaryReaders();
 
-    private final ReaderRefreshPolicy refreshPolicy;
-
-    private final Runnable refreshCallback = new Runnable() {
-        @Override
-        public void run() {
-            refreshReaders();
-        }
-    };
-
-    private boolean closed = false;
-
-    private List<LuceneIndexReader> nrtReaders;
-
-    private final int indexNodeId = INDEX_NODE_COUNTER.incrementAndGet();
-
-    IndexNode(String name, IndexDefinition definition, List<LuceneIndexReader> 
readers, @Nullable NRTIndex nrtIndex)
-            throws IOException {
-        checkArgument(!readers.isEmpty() || nrtIndex != null);
-        this.name = name;
-        this.definition = definition;
-        this.readers = readers;
-        this.nrtIndex = nrtIndex;
-        this.nrtReaders = getNRTReaders();
-        this.indexSearcher = new IndexSearcher(createReader(nrtReaders));
-        this.refreshPolicy = nrtIndex != null ? nrtIndex.getRefreshPolicy() : 
ReaderRefreshPolicy.NEVER;
-    }
-
-    String getName() {
-        return name;
-    }
-
-    IndexDefinition getDefinition() {
-        return definition;
-    }
+    @CheckForNull
+    Directory getSuggestDirectory();
 
-    public IndexSearcher getSearcher() {
-        return indexSearcher;
-    }
+    List<LuceneIndexReader> getNRTReaders();
 
     @CheckForNull
-    Directory getSuggestDirectory() {
-        return readers.isEmpty() ? null : 
getDefaultReader().getSuggestDirectory();
-    }
+    AnalyzingInfixSuggester getLookup();
 
-    @CheckForNull
-    AnalyzingInfixSuggester getLookup() {
-        return readers.isEmpty() ? null : getDefaultReader().getLookup();
-    }
-
-    boolean acquire() {
-        lock.readLock().lock();
-        if (closed) {
-            lock.readLock().unlock();
-            return false;
-        } else {
-            boolean success = false;
-            try {
-                refreshPolicy.refreshOnReadIfRequired(refreshCallback);
-                success = true;
-                return true;
-            } finally {
-                if (!success) {
-                    lock.readLock().unlock();
-                }
-            }
-        }
-    }
-
-    public void release() {
-        lock.readLock().unlock();
-    }
-
-    public int getIndexNodeId() {
-        return indexNodeId;
-    }
-
-    void close() throws IOException {
-        lock.writeLock().lock();
-        try {
-            checkState(!closed);
-            closed = true;
-        } finally {
-            lock.writeLock().unlock();
-        }
-
-        //Do not close the NRTIndex here as it might be in use
-        //by newer IndexNode. Just close the readers obtained from
-        //them
-        for (LuceneIndexReader reader : Iterables.concat(readers, nrtReaders)){
-           reader.close();
-        }
-    }
-
-    List<LuceneIndexReader> getPrimaryReaders() {
-        return readers;
-    }
+    int getIndexNodeId();
 
     @CheckForNull
-    public LuceneIndexWriter getLocalWriter() throws IOException{
-        return nrtIndex != null ? nrtIndex.getWriter() : null;
-    }
-
-    public void refreshReadersOnWriteIfRequired() {
-        refreshPolicy.refreshOnWriteIfRequired(refreshCallback);
-    }
-
-    private void refreshReaders(){
-        long start = PERF_LOGGER.start();
-        List<LuceneIndexReader> newNRTReaders = getNRTReaders();
-        //The list reference would differ if index got updated
-        //so if they are same no need to reinitialize the searcher
-        if (newNRTReaders != nrtReaders) {
-            nrtReaders = newNRTReaders;
-            indexSearcher = new IndexSearcher(createReader(nrtReaders));
-            PERF_LOGGER.end(start, 0, "Refreshed reader for index [{}]", 
definition);
-        }
-    }
-
-    private LuceneIndexReader getDefaultReader(){
-        //TODO This is still required to support Suggester, Spellcheck etc 
OAK-4643
-        return readers.get(0);
-    }
-
-    private IndexReader createReader(List<LuceneIndexReader> nrtReaders) {
-        if (readers.size() == 1 && nrtReaders.isEmpty()){
-            return readers.get(0).getReader();
-        }
-        if (nrtReaders.size() == 1 && readers.isEmpty()){
-            return nrtReaders.get(0).getReader();
-        }
-        IndexReader[] readerArr = new IndexReader[readers.size() + 
nrtReaders.size()];
-        int i = 0;
-        for (LuceneIndexReader r : Iterables.concat(readers, nrtReaders)){
-            readerArr[i++] = r.getReader();
-        }
-        return new MultiReader(readerArr, true);
-    }
-
-    List<LuceneIndexReader> getNRTReaders() {
-        return nrtIndex != null ? nrtIndex.getReaders() : 
Collections.<LuceneIndexReader>emptyList();
-    }
-
+    LuceneIndexWriter getLocalWriter() throws IOException;
 
+    void refreshReadersOnWriteIfRequired();
 }

Copied: 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNodeManager.java
 (from r1803824, 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java)
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNodeManager.java?p2=jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNodeManager.java&p1=jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java&r1=1803824&r2=1803951&rev=1803951&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNodeManager.java
 Thu Aug  3 06:27:27 2017
@@ -48,7 +48,7 @@ import org.apache.lucene.store.Directory
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class IndexNode {
+public class IndexNodeManager {
     /**
      * Name of the hidden node under which information about the checkpoints
      * seen and indexed by each async indexer is kept.
@@ -58,16 +58,16 @@ public class IndexNode {
     private static final AtomicInteger INDEX_NODE_COUNTER = new 
AtomicInteger();
 
     private static final PerfLogger PERF_LOGGER =
-            new PerfLogger(LoggerFactory.getLogger(IndexNode.class.getName() + 
".perf"));
+            new 
PerfLogger(LoggerFactory.getLogger(IndexNodeManager.class.getName() + ".perf"));
 
-    static IndexNode open(String indexPath, NodeState root, NodeState 
defnNodeState,
-                          LuceneIndexReaderFactory readerFactory, @Nullable 
NRTIndexFactory nrtFactory)
+    static IndexNodeManager open(String indexPath, NodeState root, NodeState 
defnNodeState,
+                                 LuceneIndexReaderFactory readerFactory, 
@Nullable NRTIndexFactory nrtFactory)
             throws IOException {
         IndexDefinition definition = new IndexDefinition(root, defnNodeState, 
indexPath);
         List<LuceneIndexReader> readers = 
readerFactory.createReaders(definition, defnNodeState, indexPath);
         NRTIndex nrtIndex = nrtFactory != null ? 
nrtFactory.createIndex(definition) : null;
         if (!readers.isEmpty() || (nrtIndex != null && 
!hasAsyncIndexerRun(root))){
-            return new IndexNode(PathUtils.getName(indexPath), definition, 
readers, nrtIndex);
+            return new IndexNodeManager(PathUtils.getName(indexPath), 
definition, readers, nrtIndex);
         }
         return null;
     }
@@ -76,7 +76,7 @@ public class IndexNode {
         return root.hasChildNode(ASYNC);
     }
 
-    private static final Logger log = LoggerFactory.getLogger(IndexNode.class);
+    private static final Logger log = 
LoggerFactory.getLogger(IndexNodeManager.class);
 
     private final List<LuceneIndexReader> readers;
 
@@ -105,7 +105,7 @@ public class IndexNode {
 
     private final int indexNodeId = INDEX_NODE_COUNTER.incrementAndGet();
 
-    IndexNode(String name, IndexDefinition definition, List<LuceneIndexReader> 
readers, @Nullable NRTIndex nrtIndex)
+    IndexNodeManager(String name, IndexDefinition definition, 
List<LuceneIndexReader> readers, @Nullable NRTIndex nrtIndex)
             throws IOException {
         checkArgument(!readers.isEmpty() || nrtIndex != null);
         this.name = name;
@@ -125,31 +125,27 @@ public class IndexNode {
         return definition;
     }
 
-    public IndexSearcher getSearcher() {
-        return indexSearcher;
-    }
-
     @CheckForNull
-    Directory getSuggestDirectory() {
+    private Directory getSuggestDirectory() {
         return readers.isEmpty() ? null : 
getDefaultReader().getSuggestDirectory();
     }
 
     @CheckForNull
-    AnalyzingInfixSuggester getLookup() {
+    private AnalyzingInfixSuggester getLookup() {
         return readers.isEmpty() ? null : getDefaultReader().getLookup();
     }
 
-    boolean acquire() {
+    IndexNode acquire() {
         lock.readLock().lock();
         if (closed) {
             lock.readLock().unlock();
-            return false;
+            return null;
         } else {
             boolean success = false;
             try {
                 refreshPolicy.refreshOnReadIfRequired(refreshCallback);
                 success = true;
-                return true;
+                return new IndexNodeImpl(indexSearcher);
             } finally {
                 if (!success) {
                     lock.readLock().unlock();
@@ -158,11 +154,11 @@ public class IndexNode {
         }
     }
 
-    public void release() {
+    private void release() {
         lock.readLock().unlock();
     }
 
-    public int getIndexNodeId() {
+    private int getIndexNodeId() {
         return indexNodeId;
     }
 
@@ -183,16 +179,16 @@ public class IndexNode {
         }
     }
 
-    List<LuceneIndexReader> getPrimaryReaders() {
+    private List<LuceneIndexReader> getPrimaryReaders() {
         return readers;
     }
 
     @CheckForNull
-    public LuceneIndexWriter getLocalWriter() throws IOException{
+    private LuceneIndexWriter getLocalWriter() throws IOException{
         return nrtIndex != null ? nrtIndex.getWriter() : null;
     }
 
-    public void refreshReadersOnWriteIfRequired() {
+    private void refreshReadersOnWriteIfRequired() {
         refreshPolicy.refreshOnWriteIfRequired(refreshCallback);
     }
 
@@ -228,9 +224,66 @@ public class IndexNode {
         return new MultiReader(readerArr, true);
     }
 
-    List<LuceneIndexReader> getNRTReaders() {
+    private List<LuceneIndexReader> getNRTReaders() {
         return nrtIndex != null ? nrtIndex.getReaders() : 
Collections.<LuceneIndexReader>emptyList();
     }
 
+    private class IndexNodeImpl implements IndexNode {
+        private final IndexSearcher searcher;
+
+        private IndexNodeImpl(IndexSearcher searcher) {
+            this.searcher = searcher;
+        }
+
+        @Override
+        public void release() {
+            IndexNodeManager.this.release();
+        }
+
+        @Override
+        public IndexSearcher getSearcher() {
+            return searcher;
+        }
+
+        @Override
+        public IndexDefinition getDefinition() {
+            return definition;
+        }
+
+        @Override
+        public List<LuceneIndexReader> getPrimaryReaders() {
+            return IndexNodeManager.this.getPrimaryReaders();
+        }
+
+        @Override
+        public Directory getSuggestDirectory() {
+            return IndexNodeManager.this.getSuggestDirectory();
+        }
+
+        @Override
+        public List<LuceneIndexReader> getNRTReaders() {
+            return IndexNodeManager.this.nrtReaders;
+        }
+
+        @Override
+        public AnalyzingInfixSuggester getLookup() {
+            return IndexNodeManager.this.getLookup();
+        }
+
+        @Override
+        public int getIndexNodeId() {
+            return IndexNodeManager.this.getIndexNodeId();
+        }
+
+        @Override
+        public LuceneIndexWriter getLocalWriter() throws IOException {
+            return IndexNodeManager.this.getLocalWriter();
+        }
+
+        @Override
+        public void refreshReadersOnWriteIfRequired() {
+            IndexNodeManager.this.refreshReadersOnWriteIfRequired();
+        }
+    }
 
 }

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=1803951&r1=1803950&r2=1803951&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
 Thu Aug  3 06:27:27 2017
@@ -16,7 +16,7 @@
  */
 package org.apache.jackrabbit.oak.plugins.index.lucene;
 
-import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Predicates.in;
 import static com.google.common.base.Predicates.not;
 import static com.google.common.base.Predicates.notNull;
@@ -69,7 +69,7 @@ public class IndexTracker {
 
     private NodeState root = EMPTY_NODE;
 
-    private volatile Map<String, IndexNode> indices = emptyMap();
+    private volatile Map<String, IndexNodeManager> indices = emptyMap();
 
     private volatile boolean refresh;
 
@@ -91,10 +91,10 @@ public class IndexTracker {
     }
 
     synchronized void close() {
-        Map<String, IndexNode> indices = this.indices;
+        Map<String, IndexNodeManager> indices = this.indices;
         this.indices = emptyMap();
 
-        for (Map.Entry<String, IndexNode> entry : indices.entrySet()) {
+        for (Map.Entry<String, IndexNodeManager> entry : indices.entrySet()) {
             try {
                 entry.getValue().close();
             } catch (IOException e) {
@@ -115,8 +115,8 @@ public class IndexTracker {
     }
 
     private synchronized void diffAndUpdate(final NodeState root) {
-        Map<String, IndexNode> original = indices;
-        final Map<String, IndexNode> updates = newHashMap();
+        Map<String, IndexNodeManager> original = indices;
+        final Map<String, IndexNodeManager> updates = newHashMap();
 
         Set<String> indexPaths = Sets.newHashSet();
         indexPaths.addAll(original.keySet());
@@ -129,7 +129,7 @@ public class IndexTracker {
                 public void leave(NodeState before, NodeState after) {
                     try {
                         long start = PERF_LOGGER.start();
-                        IndexNode index = IndexNode.open(path, root, after, 
readerFactory, nrtFactory);
+                        IndexNodeManager index = IndexNodeManager.open(path, 
root, after, readerFactory, nrtFactory);
                         PERF_LOGGER.end(start, -1, "[{}] Index found to be 
updated. Reopening the IndexNode", path);
                         updates.put(path, index); // index can be null
                     } catch (IOException e) {
@@ -143,7 +143,7 @@ public class IndexTracker {
         this.root = root;
 
         if (!updates.isEmpty()) {
-            indices = ImmutableMap.<String, IndexNode>builder()
+            indices = ImmutableMap.<String, IndexNodeManager>builder()
                     .putAll(filterKeys(original, not(in(updates.keySet()))))
                     .putAll(filterValues(updates, notNull()))
                     .build();
@@ -155,7 +155,7 @@ public class IndexTracker {
             //Given that Tracker is now invoked from a BackgroundObserver
             //not a high concern
             for (String path : updates.keySet()) {
-                IndexNode index = original.get(path);
+                IndexNodeManager index = original.get(path);
                 try {
                     if (index != null) {
                         index.close();
@@ -172,9 +172,10 @@ public class IndexTracker {
     }
 
     public IndexNode acquireIndexNode(String path) {
-        IndexNode index = indices.get(path);
-        if (index != null && index.acquire()) {
-            return index;
+        IndexNodeManager index = indices.get(path);
+        IndexNode indexNode = index != null ? index.acquire() : null;
+        if (indexNode != null) {
+            return indexNode;
         } else {
             return findIndexNode(path);
         }
@@ -182,7 +183,7 @@ public class IndexTracker {
 
     @CheckForNull
     public IndexDefinition getIndexDefinition(String indexPath){
-        IndexNode node = indices.get(indexPath);
+        IndexNodeManager node = indices.get(indexPath);
         if (node != null){
             //Accessing the definition should not require
             //locking as its immutable state
@@ -207,10 +208,10 @@ public class IndexTracker {
         // Retry the lookup from acquireIndexNode now that we're
         // synchronized. The acquire() call is guaranteed to succeed
         // since the close() method is also synchronized.
-        IndexNode index = indices.get(path);
+        IndexNodeManager index = indices.get(path);
         if (index != null) {
-            checkState(index.acquire());
-            return index;
+            IndexNode indexNode = index.acquire();
+            return checkNotNull(indexNode);
         }
 
         if (badIndexTracker.isIgnoredBadIndex(path)){
@@ -224,15 +225,16 @@ public class IndexTracker {
 
         try {
             if (isLuceneIndexNode(node)) {
-                index = IndexNode.open(path, root, node, readerFactory, 
nrtFactory);
+                index = IndexNodeManager.open(path, root, node, readerFactory, 
nrtFactory);
                 if (index != null) {
-                    checkState(index.acquire());
-                    indices = ImmutableMap.<String, IndexNode>builder()
+                    IndexNode indexNode = index.acquire();
+                    checkNotNull(indexNode);
+                    indices = ImmutableMap.<String, IndexNodeManager>builder()
                             .putAll(indices)
                             .put(path, index)
                             .build();
                     badIndexTracker.markGoodIndex(path);
-                    return index;
+                    return indexNode;
                 }
             } else if (node.exists()) {
                 log.warn("Cannot open Lucene Index at path {} as the index is 
not of type {}", path, TYPE_LUCENE);

Copied: 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNodeManagerTest.java
 (from r1803824, 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNodeTest.java)
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNodeManagerTest.java?p2=jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNodeManagerTest.java&p1=jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNodeTest.java&r1=1803824&r2=1803951&rev=1803951&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNodeTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNodeManagerTest.java
 Thu Aug  3 06:27:27 2017
@@ -54,7 +54,7 @@ import static org.junit.Assert.fail;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 
-public class IndexNodeTest {
+public class IndexNodeManagerTest {
     @Rule
     public TemporaryFolder temporaryFolder = new TemporaryFolder(new 
File("target"));
 
@@ -81,20 +81,23 @@ public class IndexNodeTest {
 
     @Test
     public void nullIndexNode() throws Exception{
-        assertNull(IndexNode.open("/foo", root, builder.getNodeState(), 
readerFactory, null));
-        assertNull(IndexNode.open("/foo", root, builder.getNodeState(), 
readerFactory, nrtFactory));
+        assertNull(IndexNodeManager.open("/foo", root, builder.getNodeState(), 
readerFactory, null));
+        assertNull(IndexNodeManager.open("/foo", root, builder.getNodeState(), 
readerFactory, nrtFactory));
     }
 
     @Test
     public void nonNullIndex_OnlyNRT() throws Exception{
-        IndexNode node = IndexNode.open("/foo", root, createNRTIndex(), 
readerFactory, nrtFactory);
+        IndexNodeManager nodeManager = IndexNodeManager.open("/foo", root, 
createNRTIndex(), readerFactory, nrtFactory);
+        IndexNode node = nodeManager.acquire();
         assertNotNull(node.getSearcher());
         TopDocs docs = node.getSearcher().search(new TermQuery(new Term(PATH, 
"/content/en")), 100);
         assertEquals(0, docs.totalHits);
+        node.release();
 
         node.getLocalWriter().updateDocument("/content/en", 
newDoc("/content/en"));
         node.refreshReadersOnWriteIfRequired();
 
+        node = nodeManager.acquire();
         docs = node.getSearcher().search(new TermQuery(new Term(PATH, 
"/content/en")), 100);
         assertEquals(1, docs.totalHits);
     }
@@ -103,8 +106,8 @@ public class IndexNodeTest {
     public void nullIndex_NonFreshIndex() throws Exception{
         NodeBuilder builder = createNRTIndex().builder();
         NodeBuilder rootBuilder = root.builder();
-        rootBuilder.child(IndexNode.ASYNC);
-        assertNull(IndexNode.open("/foo", rootBuilder.getNodeState(), 
builder.getNodeState(), readerFactory, nrtFactory));
+        rootBuilder.child(IndexNodeManager.ASYNC);
+        assertNull(IndexNodeManager.open("/foo", rootBuilder.getNodeState(), 
builder.getNodeState(), readerFactory, nrtFactory));
     }
 
     @Test
@@ -114,7 +117,7 @@ public class IndexNodeTest {
         NRTIndex nrtIndex = nrtFactory.createIndex(definition);
         NRTIndex mock = spy(nrtIndex);
         doReturn(new FailingPolicy()).when(mock).getRefreshPolicy();
-        IndexNode node = new IndexNode("/foo", definition, 
Collections.<LuceneIndexReader>emptyList(), mock);
+        IndexNodeManager node = new IndexNodeManager("/foo", definition, 
Collections.<LuceneIndexReader>emptyList(), mock);
 
         try {
             node.acquire();

Propchange: 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNodeManagerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java?rev=1803951&r1=1803950&r2=1803951&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexPlannerTest.java
 Thu Aug  3 06:27:27 2017
@@ -847,11 +847,11 @@ public class IndexPlannerTest {
     //------ END - Suggestion/spellcheck plan tests
 
     private IndexNode createIndexNode(IndexDefinition defn, long numOfDocs) 
throws IOException {
-        return new IndexNode("foo", defn, new 
TestReaderFactory(createSampleDirectory(numOfDocs)).createReaders(defn, 
EMPTY_NODE, "foo"), null);
+        return new IndexNodeManager("foo", defn, new 
TestReaderFactory(createSampleDirectory(numOfDocs)).createReaders(defn, 
EMPTY_NODE, "foo"), null).acquire();
     }
 
     private IndexNode createIndexNode(IndexDefinition defn) throws IOException 
{
-        return new IndexNode("foo", defn, new 
TestReaderFactory(createSampleDirectory()).createReaders(defn, EMPTY_NODE, 
"foo"), null);
+        return new IndexNodeManager("foo", defn, new 
TestReaderFactory(createSampleDirectory()).createReaders(defn, EMPTY_NODE, 
"foo"), null).acquire();
     }
 
     private FilterImpl createFilter(String nodeTypeName) {

Modified: 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/MultiplexingLucenePropertyIndexTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/MultiplexingLucenePropertyIndexTest.java?rev=1803951&r1=1803950&r2=1803951&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/MultiplexingLucenePropertyIndexTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/MultiplexingLucenePropertyIndexTest.java
 Thu Aug  3 06:27:27 2017
@@ -140,12 +140,12 @@ public class MultiplexingLucenePropertyI
         LuceneIndexReaderFactory readerFactory = new 
DefaultIndexReaderFactory(mip, null);
         List<LuceneIndexReader> readers = readerFactory.createReaders(defn, 
builder.getNodeState(),"/foo");
 
-        IndexNode node = new IndexNode("foo", defn, readers, null);
+        IndexNodeManager node = new IndexNodeManager("foo", defn, readers, 
null);
 
         //3 Obtain the plan
         FilterImpl filter = createFilter("nt:base");
         filter.restrictProperty("foo", Operator.EQUAL, 
PropertyValues.newString("bar"));
-        IndexPlanner planner = new IndexPlanner(node, "/foo", filter, 
Collections.<QueryIndex.OrderEntry>emptyList());
+        IndexPlanner planner = new IndexPlanner(node.acquire(), "/foo", 
filter, Collections.<QueryIndex.OrderEntry>emptyList());
         QueryIndex.IndexPlan plan = planner.getPlan();
 
         //Count should be sum of both readers


Reply via email to