Author: chetanm
Date: Thu Sep 15 07:15:41 2016
New Revision: 1760838

URL: http://svn.apache.org/viewvc?rev=1760838&view=rev
Log:
OAK-4412 - Lucene hybrid index

Introduce ReaderRefreshPolicy to determine when the readers should be refreshed

Added:
    
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/ReaderRefreshPolicy.java
   (with props)
    
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/RefreshIfDirtyPolicy.java
   (with props)
    
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/TimedRefreshPolicy.java
   (with props)
    
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/RefreshPolicyTest.java
   (with props)
    
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/TimedRefreshPolicyTest.java
   (with props)
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/hybrid/DocumentQueue.java
    
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/NRTIndex.java
    
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/NRTIndexFactory.java
    
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/DocumentQueueTest.java
    
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/HybridIndexTest.java
    
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/LocalIndexObserverTest.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=1760838&r1=1760837&r2=1760838&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 Sep 15 07:15:41 2016
@@ -22,7 +22,6 @@ import static com.google.common.base.Pre
 import java.io.IOException;
 import java.util.Collections;
 import java.util.List;
-import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
@@ -34,6 +33,7 @@ import com.google.common.collect.Iterabl
 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;
@@ -58,12 +58,6 @@ public class IndexNode {
         return null;
     }
 
-    /**
-     * Time interval after which readers would be refreshed in case of real 
time index
-     * TODO Make this configurable
-     */
-    private final long refreshDelta = TimeUnit.SECONDS.toMillis(1);
-
     private final List<LuceneIndexReader> readers;
 
     private final String name;
@@ -76,9 +70,9 @@ public class IndexNode {
 
     private final NRTIndex nrtIndex;
 
-    private boolean closed = false;
+    private final ReaderRefreshPolicy refreshPolicy;
 
-    private long lastRefreshTime;
+    private boolean closed = false;
 
     IndexNode(String name, IndexDefinition definition, List<LuceneIndexReader> 
readers, @Nullable NRTIndex nrtIndex)
             throws IOException {
@@ -88,6 +82,7 @@ public class IndexNode {
         this.readers = readers;
         this.nrtIndex = nrtIndex;
         this.indexSearcher = new IndexSearcher(createReader());
+        this.refreshPolicy = nrtIndex != null ? nrtIndex.getRefreshPolicy() : 
ReaderRefreshPolicy.NEVER;
     }
 
     String getName() {
@@ -116,6 +111,7 @@ public class IndexNode {
             lock.readLock().unlock();
             return false;
         } else {
+            refreshReadersIfRequired();
             return true;
         }
     }
@@ -146,21 +142,12 @@ public class IndexNode {
         return nrtIndex != null ? nrtIndex.getWriter() : null;
     }
 
-    public void refreshReaders(long currentTime) {
-        //TODO [hybrid] Refreshing currently requires updates to happen
-        //However if no update happened after last update the refresh would not
-        //happen and result would remain stale upto next async cycle. Possibly
-        //introduce a refresh policy
-        if (currentTime - lastRefreshTime > refreshDelta){
-            lastRefreshTime = currentTime;
+    public void refreshReadersIfRequired() {
+        if (refreshPolicy.shouldRefresh()){
             indexSearcher = new IndexSearcher(createReader());
         }
     }
 
-    public long getRefreshDelta() {
-        return refreshDelta;
-    }
-
     private LuceneIndexReader getDefaultReader(){
         //TODO This is still required to support Suggester, Spellcheck etc 
OAK-4643
         return readers.get(0);

Modified: 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/DocumentQueue.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/DocumentQueue.java?rev=1760838&r1=1760837&r2=1760838&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/DocumentQueue.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/DocumentQueue.java
 Thu Sep 15 07:15:41 2016
@@ -34,19 +34,17 @@ import org.apache.jackrabbit.oak.commons
 import org.apache.jackrabbit.oak.plugins.index.lucene.IndexNode;
 import org.apache.jackrabbit.oak.plugins.index.lucene.IndexTracker;
 import org.apache.jackrabbit.oak.plugins.index.lucene.writer.LuceneIndexWriter;
-import org.apache.jackrabbit.oak.stats.Clock;
 import org.apache.lucene.index.IndexableField;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import static com.google.common.base.Preconditions.checkState;
 
-class DocumentQueue implements Closeable{
+public class DocumentQueue implements Closeable{
     private static final LuceneDoc STOP = LuceneDoc.forUpdate("", "", 
Collections.<IndexableField>emptyList());
     private final Logger log = LoggerFactory.getLogger(getClass());
     private final IndexTracker tracker;
     private final BlockingQueue<LuceneDoc> docsQueue;
-    private final Clock clock;
     private final Executor executor;
     private volatile boolean stopped;
 
@@ -93,10 +91,9 @@ class DocumentQueue implements Closeable
         }
     };
 
-    DocumentQueue(int maxQueueSize, IndexTracker tracker, Clock clock, 
Executor executor) {
+    public DocumentQueue(int maxQueueSize, IndexTracker tracker, Executor 
executor) {
         this.docsQueue = new LinkedBlockingDeque<>(maxQueueSize);
         this.tracker = tracker;
-        this.clock = clock;
         this.executor = executor;
     }
 
@@ -139,8 +136,7 @@ class DocumentQueue implements Closeable
             } else {
                 writer.updateDocument(doc.docPath, doc.doc);
             }
-            //TODO Support for immediate refresh
-            indexNode.refreshReaders(clock.getTime());
+            indexNode.refreshReadersIfRequired();
         } catch (Exception e) {
             //For now we just log it. Later we need to see if frequent error 
then to
             //temporarily disable indexing for this index

Modified: 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/NRTIndex.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/NRTIndex.java?rev=1760838&r1=1760837&r2=1760838&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/NRTIndex.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/NRTIndex.java
 Thu Sep 15 07:15:41 2016
@@ -62,6 +62,7 @@ public class NRTIndex implements Closeab
     private final IndexDefinition definition;
     private final IndexCopier indexCopier;
     private final LuceneIndexReader previousReader;
+    private final ReaderRefreshPolicy refreshPolicy;
 
     private IndexWriter indexWriter;
     private NRTIndexWriter nrtIndexWriter;
@@ -69,9 +70,11 @@ public class NRTIndex implements Closeab
     private Directory directory;
     private boolean closed;
 
-    public NRTIndex(IndexDefinition definition, IndexCopier indexCopier, 
@Nullable NRTIndex previous) {
+    public NRTIndex(IndexDefinition definition, IndexCopier indexCopier,
+                    ReaderRefreshPolicy refreshPolicy, @Nullable NRTIndex 
previous) {
         this.definition = definition;
         this.indexCopier = indexCopier;
+        this.refreshPolicy = refreshPolicy;
         this.previousReader = previous != null ? previous.getPrimaryReader() : 
null;
     }
 
@@ -103,6 +106,10 @@ public class NRTIndex implements Closeab
         return readers;
     }
 
+    public ReaderRefreshPolicy getRefreshPolicy() {
+        return refreshPolicy;
+    }
+
     public void close() throws IOException {
         if (closed) {
             return;
@@ -194,7 +201,7 @@ public class NRTIndex implements Closeab
         }
     }
 
-    private static class NRTIndexWriter implements LuceneIndexWriter {
+    private class NRTIndexWriter implements LuceneIndexWriter {
         private final IndexWriter indexWriter;
 
         public NRTIndexWriter(IndexWriter indexWriter) {
@@ -207,6 +214,7 @@ public class NRTIndex implements Closeab
             //instead they are just added. This would cause duplicates
             //That should be taken care at query side via unique cursor
             indexWriter.addDocument(doc);
+            refreshPolicy.updated();
         }
 
         @Override

Modified: 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/NRTIndexFactory.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/NRTIndexFactory.java?rev=1760838&r1=1760837&r2=1760838&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/NRTIndexFactory.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/NRTIndexFactory.java
 Thu Sep 15 07:15:41 2016
@@ -22,6 +22,7 @@ package org.apache.jackrabbit.oak.plugin
 import java.io.Closeable;
 import java.io.IOException;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 import javax.annotation.CheckForNull;
 
@@ -29,6 +30,7 @@ import com.google.common.collect.LinkedL
 import com.google.common.collect.ListMultimap;
 import org.apache.jackrabbit.oak.plugins.index.lucene.IndexCopier;
 import org.apache.jackrabbit.oak.plugins.index.lucene.IndexDefinition;
+import org.apache.jackrabbit.oak.stats.Clock;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -39,9 +41,17 @@ public class NRTIndexFactory implements
     private final Logger log = LoggerFactory.getLogger(getClass());
     private final ListMultimap<String, NRTIndex> indexes = 
LinkedListMultimap.create();
     private final IndexCopier indexCopier;
+    private final Clock clock;
+    private final long refreshDeltaInSecs;
 
     public NRTIndexFactory(IndexCopier indexCopier) {
+        this(indexCopier, Clock.SIMPLE, 1);
+    }
+
+    public NRTIndexFactory(IndexCopier indexCopier, Clock clock, long 
refreshDeltaInSecs) {
         this.indexCopier = checkNotNull(indexCopier);
+        this.clock = clock;
+        this.refreshDeltaInSecs = refreshDeltaInSecs;
     }
 
     //This would not be invoked concurrently
@@ -52,7 +62,7 @@ public class NRTIndexFactory implements
             return null;
         }
         String indexPath = definition.getIndexPathFromConfig();
-        NRTIndex current = new NRTIndex(definition, indexCopier, 
getPrevious(indexPath));
+        NRTIndex current = new NRTIndex(definition, indexCopier, 
getRefreshPolicy(definition), getPrevious(indexPath));
         indexes.put(indexPath, current);
         closeLast(indexPath);
         return current;
@@ -91,4 +101,8 @@ public class NRTIndexFactory implements
         checkArgument(existing.size() <= 2, "Found [%s] more than 3 index", 
existing.size());
         return existing.get(existing.size() - 1);
     }
+
+    private ReaderRefreshPolicy getRefreshPolicy(IndexDefinition definition) {
+        return new TimedRefreshPolicy(clock, TimeUnit.SECONDS, 
refreshDeltaInSecs);
+    }
 }

Added: 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/ReaderRefreshPolicy.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/ReaderRefreshPolicy.java?rev=1760838&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/ReaderRefreshPolicy.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/ReaderRefreshPolicy.java
 Thu Sep 15 07:15:41 2016
@@ -0,0 +1,53 @@
+/*
+ * 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
+ *
+ * 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.hybrid;
+
+public interface ReaderRefreshPolicy {
+    ReaderRefreshPolicy NEVER = new ReaderRefreshPolicy() {
+        @Override
+        public boolean shouldRefresh() {
+            return false;
+        }
+
+        @Override
+        public void updated() {
+
+        }
+    };
+
+    /**
+     * Returns  true if refresh is to be done and
+     * resets the internal state. The caller which
+     * gets the true answer would be responsible for
+     * refreshing the readers.
+     *
+     * <p>For e.g. once updated the first call to
+     * this method would return true and subsequent
+     * calls return false
+     *
+     * @return true if refresh is to be done
+     */
+    boolean shouldRefresh();
+
+    /**
+     * Invoked when index gets updated
+     */
+    void updated();
+}

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

Added: 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/RefreshIfDirtyPolicy.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/RefreshIfDirtyPolicy.java?rev=1760838&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/RefreshIfDirtyPolicy.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/RefreshIfDirtyPolicy.java
 Thu Sep 15 07:15:41 2016
@@ -0,0 +1,35 @@
+/*
+ * 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
+ *
+ * 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.hybrid;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class RefreshIfDirtyPolicy implements ReaderRefreshPolicy {
+    private final AtomicBoolean dirty = new AtomicBoolean();
+    @Override
+    public boolean shouldRefresh() {
+        return dirty.compareAndSet(true, false);
+    }
+
+    @Override
+    public void updated() {
+        dirty.set(true);
+    }
+}

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

Added: 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/TimedRefreshPolicy.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/TimedRefreshPolicy.java?rev=1760838&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/TimedRefreshPolicy.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/TimedRefreshPolicy.java
 Thu Sep 15 07:15:41 2016
@@ -0,0 +1,55 @@
+/*
+ * 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
+ *
+ * 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.hybrid;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.jackrabbit.oak.stats.Clock;
+
+public class TimedRefreshPolicy implements ReaderRefreshPolicy {
+    private final AtomicBoolean dirty = new AtomicBoolean();
+    private final Clock clock;
+    private final long refreshDelta;
+    private volatile long lastRefreshTime;
+
+    public TimedRefreshPolicy(Clock clock, TimeUnit unit, long refreshDelta) {
+        this.clock = clock;
+        this.refreshDelta = unit.toMillis(refreshDelta);
+    }
+
+    @Override
+    public boolean shouldRefresh() {
+        if (dirty.get()){
+            long currentTime = clock.getTime();
+            if (currentTime - lastRefreshTime > refreshDelta
+                    && dirty.compareAndSet(true, false)){
+                lastRefreshTime = currentTime;
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void updated() {
+        dirty.set(true);
+    }
+}

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

Modified: 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/DocumentQueueTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/DocumentQueueTest.java?rev=1760838&r1=1760837&r2=1760838&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/DocumentQueueTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/DocumentQueueTest.java
 Thu Sep 15 07:15:41 2016
@@ -22,6 +22,7 @@ package org.apache.jackrabbit.oak.plugin
 import java.io.File;
 import java.io.IOException;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
@@ -76,6 +77,8 @@ public class DocumentQueueTest {
 
     private IndexTracker tracker = new IndexTracker();
     private NRTIndexFactory indexFactory;
+    private Clock clock = new Clock.Virtual();
+    private long refreshDelta = TimeUnit.SECONDS.toMillis(1);
 
     @Before
     public void setUp() throws IOException {
@@ -92,7 +95,7 @@ public class DocumentQueueTest {
 
     @Test
     public void dropDocOnLimit() throws Exception{
-        DocumentQueue queue = new DocumentQueue(2, tracker, Clock.SIMPLE, 
NOOP_EXECUTOR);
+        DocumentQueue queue = new DocumentQueue(2, tracker, NOOP_EXECUTOR);
         assertTrue(queue.add(LuceneDoc.forDelete("foo", "bar")));
         assertTrue(queue.add(LuceneDoc.forDelete("foo", "bar")));
 
@@ -102,14 +105,14 @@ public class DocumentQueueTest {
 
     @Test
     public void noIssueIfNoIndex() throws Exception{
-        DocumentQueue queue = new DocumentQueue(2, tracker, Clock.SIMPLE, 
sameThreadExecutor());
+        DocumentQueue queue = new DocumentQueue(2, tracker, 
sameThreadExecutor());
         assertTrue(queue.add(LuceneDoc.forDelete("foo", "bar")));
         assertTrue(queue.getQueuedDocs().isEmpty());
     }
 
     @Test
     public void closeQueue() throws Exception{
-        DocumentQueue queue = new DocumentQueue(2, tracker, Clock.SIMPLE, 
sameThreadExecutor());
+        DocumentQueue queue = new DocumentQueue(2, tracker, 
sameThreadExecutor());
         queue.close();
 
         try {
@@ -123,7 +126,7 @@ public class DocumentQueueTest {
     @Test
     public void noIssueIfNoWriter() throws Exception{
         NodeState indexed = createAndPopulateAsyncIndex();
-        DocumentQueue queue = new DocumentQueue(2, tracker, Clock.SIMPLE, 
sameThreadExecutor());
+        DocumentQueue queue = new DocumentQueue(2, tracker, 
sameThreadExecutor());
 
         tracker.update(indexed);
         assertTrue(queue.add(LuceneDoc.forDelete("/oak:index/fooIndex", 
"bar")));
@@ -134,7 +137,7 @@ public class DocumentQueueTest {
         IndexTracker tracker = createTracker();
         NodeState indexed = createAndPopulateAsyncIndex();
         tracker.update(indexed);
-        DocumentQueue queue = new DocumentQueue(2, tracker, Clock.SIMPLE, 
sameThreadExecutor());
+        DocumentQueue queue = new DocumentQueue(2, tracker, 
sameThreadExecutor());
 
         Document d1 = new Document();
         d1.add(newPathField("/a/b"));
@@ -148,69 +151,63 @@ public class DocumentQueueTest {
 
     @Test
     public void indexRefresh() throws Exception{
-        IndexTracker tracker = createTracker();
+        tracker = createTracker();
         NodeState indexed = createAndPopulateAsyncIndex();
         tracker.update(indexed);
 
-        Clock clock = new Clock.Virtual();
-        clock.waitUntil(System.currentTimeMillis());
+        clock.waitUntil(refreshDelta);
 
-        DocumentQueue queue = new DocumentQueue(2, tracker, clock, 
sameThreadExecutor());
+        DocumentQueue queue = new DocumentQueue(2, tracker, 
sameThreadExecutor());
 
-        IndexNode indexNode = tracker.acquireIndexNode("/oak:index/fooIndex");
-        TopDocs td = doSearch(indexNode, "bar");
+        TopDocs td = doSearch("bar");
         assertEquals(1, td.totalHits);
 
         addDoc(queue, "/a/b", "bar");
 
         //First update would be picked as base time was zero which would now
         //get initialized
-        td = doSearch(indexNode, "bar");
+        td = doSearch("bar");
         assertEquals(2, td.totalHits);
 
         addDoc(queue, "/a/c", "bar");
 
         //Now it would not update as refresh interval has not exceeded
-        td = doSearch(indexNode, "bar");
+        td = doSearch("bar");
         assertEquals(2, td.totalHits);
 
-        //Get past the delta time
-        clock.waitUntil(clock.getTime() + indexNode.getRefreshDelta() + 1);
-
         addDoc(queue, "/a/d", "bar");
 
+        //Get past the delta time
+        clock.waitUntil(clock.getTime() + refreshDelta + 1);
+
         //Now it should show updated result
-        td = doSearch(indexNode, "bar");
+        td = doSearch("bar");
         assertEquals(4, td.totalHits);
 
         //Phase 2 - Check affect of async index update cycle
         //With that there should only be 2 copies of NRTIndex kept
         indexed = doAsyncIndex(indexed, "a2", "bar");
 
-        indexNode.release();
         tracker.update(indexed);
-        indexNode = tracker.acquireIndexNode("/oak:index/fooIndex");
 
         //Now result would be latest from async + last local
-        td = doSearch(indexNode, "bar");
+        td = doSearch("bar");
         assertEquals(5, td.totalHits);
 
         //Now there would be to NRTIndex - previous and current
         //so add to current and query again
         addDoc(queue, "/a/e", "bar");
-        td = doSearch(indexNode, "bar");
+        td = doSearch("bar");
         assertEquals(6, td.totalHits);
 
         //Now do another async update
         indexed = doAsyncIndex(indexed, "a3", "bar");
 
-        indexNode.release();
         tracker.update(indexed);
-        indexNode = tracker.acquireIndexNode("/oak:index/fooIndex");
 
         //Now total count would be 4
         //3 from async and 1 from current
-        td = doSearch(indexNode, "bar");
+        td = doSearch("bar");
         assertEquals(4, td.totalHits);
     }
 
@@ -222,8 +219,13 @@ public class DocumentQueueTest {
         return asyncHook.processCommit(current, after, newCommitInfo());
     }
 
-    private TopDocs doSearch(IndexNode indexNode, String fooValue) throws 
IOException {
-        return indexNode.getSearcher().search(new TermQuery(new Term("foo", 
fooValue)), 10);
+    private TopDocs doSearch(String fooValue) throws IOException {
+        IndexNode indexNode = tracker.acquireIndexNode("/oak:index/fooIndex");
+        try {
+            return indexNode.getSearcher().search(new TermQuery(new 
Term("foo", fooValue)), 10);
+        } finally {
+            indexNode.release();
+        }
     }
 
     private void addDoc(DocumentQueue queue, String docPath, String fooValue) {
@@ -235,7 +237,7 @@ public class DocumentQueueTest {
 
     private IndexTracker createTracker() throws IOException {
         IndexCopier indexCopier = new IndexCopier(sameThreadExecutor(), 
temporaryFolder.getRoot());
-        indexFactory = new NRTIndexFactory(indexCopier);
+        indexFactory = new NRTIndexFactory(indexCopier, clock, 
TimeUnit.MILLISECONDS.toSeconds(refreshDelta));
         return new IndexTracker(
                 new DefaultIndexReaderFactory(defaultMountInfoProvider(), 
indexCopier),
                 indexFactory

Modified: 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/HybridIndexTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/HybridIndexTest.java?rev=1760838&r1=1760837&r2=1760838&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/HybridIndexTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/HybridIndexTest.java
 Thu Sep 15 07:15:41 2016
@@ -83,12 +83,11 @@ public class HybridIndexTest extends Abs
     private Clock clock = new Clock.Virtual();
     private Whiteboard wb;
 
-    //TODO [hybrid] this needs to be obtained from NRTIndexFactory
     private long refreshDelta = TimeUnit.SECONDS.toMillis(1);
 
     @Override
     protected ContentRepository createRepository() {
-        IndexCopier copier = null;
+        IndexCopier copier;
         try {
             copier = new IndexCopier(executorService, 
temporaryFolder.getRoot());
         } catch (IOException e) {
@@ -96,7 +95,7 @@ public class HybridIndexTest extends Abs
         }
         MountInfoProvider mip = defaultMountInfoProvider();
 
-        NRTIndexFactory nrtIndexFactory = new NRTIndexFactory(copier);
+        NRTIndexFactory nrtIndexFactory = new NRTIndexFactory(copier, clock, 
TimeUnit.MILLISECONDS.toSeconds(refreshDelta));
         LuceneIndexReaderFactory indexReaderFactory = new 
DefaultIndexReaderFactory(mip, copier);
         IndexTracker tracker = new 
IndexTracker(indexReaderFactory,nrtIndexFactory);
         LuceneIndexProvider provider = new LuceneIndexProvider(tracker);
@@ -107,7 +106,7 @@ public class HybridIndexTest extends Abs
                 null,
                 mip);
 
-        queue = new DocumentQueue(100, tracker, clock, sameThreadExecutor());
+        queue = new DocumentQueue(100, tracker, sameThreadExecutor());
         LocalIndexObserver localIndexObserver = new LocalIndexObserver(queue);
 
         nodeStore = new MemoryNodeStore();
@@ -154,13 +153,12 @@ public class HybridIndexTest extends Abs
         //Now let some time elapse such that readers can be refreshed
         clock.waitUntil(clock.getTime() + refreshDelta + 1);
 
-        //TODO This extra push would not be required once refresh also account 
for time
+        //Now recently added stuff should be visible without async indexing run
+        assertQuery("select [jcr:path] from [nt:base] where [foo] = 'bar'", 
of("/a", "/b"));
+
         createPath("/c").setProperty("foo", "bar");
         root.commit();
 
-        //Now recently added stuff should be visible without async indexing run
-        assertQuery("select [jcr:path] from [nt:base] where [foo] = 'bar'", 
of("/a", "/b", "/c"));
-
         //Post async index it should still be upto date
         runAsyncIndex();
         assertQuery("select [jcr:path] from [nt:base] where [foo] = 'bar'", 
of("/a", "/b", "/c"));

Modified: 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/LocalIndexObserverTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/LocalIndexObserverTest.java?rev=1760838&r1=1760837&r2=1760838&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/LocalIndexObserverTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/LocalIndexObserverTest.java
 Thu Sep 15 07:15:41 2016
@@ -26,7 +26,6 @@ import org.apache.jackrabbit.oak.core.Si
 import org.apache.jackrabbit.oak.plugins.index.lucene.IndexTracker;
 import org.apache.jackrabbit.oak.spi.commit.CommitContext;
 import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
-import org.apache.jackrabbit.oak.stats.Clock;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -47,7 +46,7 @@ public class LocalIndexObserverTest {
 
     @Before
     public void setUp(){
-        collectingQueue = new DocumentQueue(10, tracker, Clock.SIMPLE, 
NOOP_EXECUTOR);
+        collectingQueue = new DocumentQueue(10, tracker, NOOP_EXECUTOR);
         observer = new LocalIndexObserver(collectingQueue);
     }
 

Added: 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/RefreshPolicyTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/RefreshPolicyTest.java?rev=1760838&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/RefreshPolicyTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/RefreshPolicyTest.java
 Thu Sep 15 07:15:41 2016
@@ -0,0 +1,54 @@
+/*
+ * 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
+ *
+ * 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.hybrid;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class RefreshPolicyTest {
+
+    @Test
+    public void refreshIfDirty() throws Exception{
+        ReaderRefreshPolicy policy = new RefreshIfDirtyPolicy();
+        assertFalse(policy.shouldRefresh());
+
+        policy.updated();
+        assertTrue(policy.shouldRefresh());
+
+        //Second call should return false
+        assertFalse(policy.shouldRefresh());
+
+        policy.updated();
+        assertTrue(policy.shouldRefresh());
+    }
+
+    @Test
+    public void refreshNever() throws Exception{
+        ReaderRefreshPolicy policy = ReaderRefreshPolicy.NEVER;
+
+        assertFalse(policy.shouldRefresh());
+
+        policy.updated();
+        assertFalse(policy.shouldRefresh());
+    }
+
+}
\ No newline at end of file

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

Added: 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/TimedRefreshPolicyTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/TimedRefreshPolicyTest.java?rev=1760838&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/TimedRefreshPolicyTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/hybrid/TimedRefreshPolicyTest.java
 Thu Sep 15 07:15:41 2016
@@ -0,0 +1,75 @@
+/*
+ * 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
+ *
+ * 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.hybrid;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.jackrabbit.oak.stats.Clock;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class TimedRefreshPolicyTest {
+    private Clock clock = new Clock.Virtual();
+
+    @Test
+    public void dirtyAndFirstCheck() throws Exception{
+        clock.waitUntil(System.currentTimeMillis());
+        ReaderRefreshPolicy policy = new TimedRefreshPolicy(clock, 
TimeUnit.SECONDS, 1);
+        assertFalse(policy.shouldRefresh());
+
+        policy.updated();
+        assertTrue(policy.shouldRefresh());
+        assertFalse(policy.shouldRefresh());
+    }
+
+    @Test
+    public void dirtyAndNotElapsedTimed() throws Exception{
+        clock.waitUntil(System.currentTimeMillis());
+        ReaderRefreshPolicy policy = new TimedRefreshPolicy(clock, 
TimeUnit.SECONDS, 1);
+
+        policy.updated();
+        assertTrue(policy.shouldRefresh());
+        assertFalse(policy.shouldRefresh());
+
+        policy.updated();
+        //Given time has not elapsed it should still be false
+        assertFalse(policy.shouldRefresh());
+    }
+
+    @Test
+    public void dirtyAndElapsedTime() throws Exception{
+        clock.waitUntil(System.currentTimeMillis());
+        ReaderRefreshPolicy policy = new TimedRefreshPolicy(clock, 
TimeUnit.SECONDS, 1);
+
+        policy.updated();
+        assertTrue(policy.shouldRefresh());
+        assertFalse(policy.shouldRefresh());
+
+        policy.updated();
+        //Given time has not elapsed it should still be false
+        assertFalse(policy.shouldRefresh());
+
+        clock.waitUntil(System.currentTimeMillis() + 
TimeUnit.SECONDS.toMillis(1) + 1);
+        assertTrue(policy.shouldRefresh());
+        assertFalse(policy.shouldRefresh());
+    }
+
+}
\ No newline at end of file

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



Reply via email to