Author: chetanm
Date: Thu Sep 15 07:22:24 2016
New Revision: 1760879
URL: http://svn.apache.org/viewvc?rev=1760879&view=rev
Log:
OAK-4412 - Lucene hybrid index
Handle the case where IndexSearcher gets refreshed in between cursor traversal
due to change in NRT index. For such case we keep reference to the searcher and
not reset the lastDoc upon each nrt change. This should be ok as backing reader
would remain valid till change in IndexNode when NRTIndex is closed
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/LucenePropertyIndex.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=1760879&r1=1760878&r2=1760879&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:22:24 2016
@@ -22,6 +22,7 @@ import static com.google.common.base.Pre
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;
@@ -47,6 +48,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class IndexNode {
+ private static final AtomicInteger INDEX_NODE_COUNTER = new
AtomicInteger();
static IndexNode open(String indexPath, NodeState root, NodeState
defnNodeState,
LuceneIndexReaderFactory readerFactory, @Nullable
NRTIndexFactory nrtFactory)
@@ -87,6 +89,8 @@ public class IndexNode {
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());
@@ -134,6 +138,10 @@ public class IndexNode {
lock.readLock().unlock();
}
+ public int getIndexNodeId() {
+ return indexNodeId;
+ }
+
void close() throws IOException {
lock.writeLock().lock();
try {
@@ -146,7 +154,7 @@ public class IndexNode {
//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,
getNRTReaders())){
+ for (LuceneIndexReader reader : Iterables.concat(readers, nrtReaders)){
reader.close();
}
}
Modified:
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java?rev=1760879&r1=1760878&r2=1760879&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
(original)
+++
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndex.java
Thu Sep 15 07:22:24 2016
@@ -306,13 +306,15 @@ public class LucenePropertyIndex impleme
private ScoreDoc lastDoc;
private int nextBatchSize = LUCENE_QUERY_BATCH_SIZE;
private boolean noDocs = false;
- private long lastSearchIndexerVersion;
+ private IndexSearcher indexSearcher;
+ private int indexNodeId = -1;
@Override
protected LuceneResultRow computeNext() {
while (!queue.isEmpty() || loadDocs()) {
return queue.remove();
}
+ releaseSearcher();
return endOfData();
}
@@ -366,7 +368,7 @@ public class LucenePropertyIndex impleme
final IndexNode indexNode = acquireIndexNode(plan);
checkState(indexNode != null);
try {
- IndexSearcher searcher = indexNode.getSearcher();
+ IndexSearcher searcher = getCurrentSearcher(indexNode);
LuceneRequestFacade luceneRequestFacade =
getLuceneRequest(plan, augmentorFactory, searcher.getIndexReader());
if (luceneRequestFacade.getLuceneRequest() instanceof
Query) {
Query query = (Query)
luceneRequestFacade.getLuceneRequest();
@@ -377,8 +379,6 @@ public class LucenePropertyIndex impleme
query = customScoreQuery;
}
- checkForIndexVersionChange(searcher);
-
TopDocs docs;
long start = PERF_LOGGER.start();
while (true) {
@@ -521,15 +521,34 @@ public class LucenePropertyIndex impleme
return !queue.isEmpty();
}
+ private IndexSearcher getCurrentSearcher(IndexNode indexNode) {
+ //The searcher once obtained is held till either cursor is
finished
+ //or if the index gets updated. It needs to be ensured that
+ //searcher is obtained via this method only in this iterator
+
+ //Refresh the searcher if change in indexNode is detected
+ //For NRT case its fine to keep a reference to searcher i.e.
not
+ //acquire it for every loadDocs call otherwise with frequent
change
+ //the reset of lastDoc would happen very frequently.
+ //Upon IndexNode change i.e. when new async index update is
detected
+ //the searcher would be refreshed as done earlier
+ if (indexNodeId != indexNode.getIndexNodeId()){
+ //if already initialized then log about change
+ if (indexNodeId > 0){
+ LOG.debug("Change in index version detected. Query
would be performed without offset");
+ }
- private void checkForIndexVersionChange(IndexSearcher searcher) {
- long currentVersion = getVersion(searcher);
- if (currentVersion != lastSearchIndexerVersion && lastDoc !=
null) {
+ //TODO Add testcase for this scenario
+ indexSearcher = indexNode.getSearcher();
+ indexNodeId = indexNode.getIndexNodeId();
lastDoc = null;
- LOG.debug("Change in index version detected {} => {}.
Query would be performed without " +
- "offset", currentVersion,
lastSearchIndexerVersion);
}
- this.lastSearchIndexerVersion = currentVersion;
+ return indexSearcher;
+ }
+
+ private void releaseSearcher() {
+ //For now nullifying it.
+ indexSearcher = null;
}
};
SizeEstimator sizeEstimator = new SizeEstimator() {