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 ch...@apache.org on 2014/10/31 07:26:55 UTC
svn commit: r1635686 - in /jackrabbit/oak/branches/1.0: ./
oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/
oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/
oak-lucene/src/test/java/org/apache/jackra...
Author: chetanm
Date: Fri Oct 31 06:26:55 2014
New Revision: 1635686
URL: http://svn.apache.org/r1635686
Log:
OAK-1724 - Enable copying of Lucene index to local file system for read queries
Merging 1634505,1634513
Added:
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/CopyOnReadStatsMBean.java
- copied unchanged from r1634513, jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/CopyOnReadStatsMBean.java
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/IndexCopier.java
- copied, changed from r1634505, jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/IndexCopier.java
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/
- copied from r1634505, jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/
Modified:
jackrabbit/oak/branches/1.0/ (props changed)
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProvider.java
jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderService.java
jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java
Propchange: jackrabbit/oak/branches/1.0/
------------------------------------------------------------------------------
Merged /jackrabbit/oak/trunk:r1634505,1634513
Modified: jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java?rev=1635686&r1=1635685&r2=1635686&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java (original)
+++ jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexNode.java Fri Oct 31 06:26:55 2014
@@ -27,6 +27,10 @@ import java.io.IOException;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
+import javax.annotation.Nullable;
+
+import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.index.lucene.util.IndexCopier;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.ReadOnlyBuilder;
import org.apache.lucene.index.DirectoryReader;
@@ -37,13 +41,16 @@ import org.apache.lucene.store.FSDirecto
class IndexNode {
- static IndexNode open(String name, NodeState defnNodeState)
+ static IndexNode open(String indexPath, NodeState defnNodeState,@Nullable IndexCopier cloner)
throws IOException {
Directory directory = null;
IndexDefinition definition = new IndexDefinition(new ReadOnlyBuilder(defnNodeState));
NodeState data = defnNodeState.getChildNode(INDEX_DATA_CHILD_NAME);
if (data.exists()) {
directory = new OakDirectory(new ReadOnlyBuilder(data), definition);
+ if (cloner != null){
+ directory = cloner.wrap(indexPath, definition, directory);
+ }
} else if (PERSISTENCE_FILE.equalsIgnoreCase(defnNodeState.getString(PERSISTENCE_NAME))) {
String path = defnNodeState.getString(PERSISTENCE_PATH);
if (path != null && new File(path).exists()) {
@@ -53,7 +60,7 @@ class IndexNode {
if (directory != null) {
try {
- IndexNode index = new IndexNode(name, definition, directory);
+ IndexNode index = new IndexNode(PathUtils.getName(indexPath), definition, directory);
directory = null; // closed in Index.close()
return index;
} finally {
Modified: jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java?rev=1635686&r1=1635685&r2=1635686&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java (original)
+++ jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexTracker.java Fri Oct 31 06:26:55 2014
@@ -35,6 +35,7 @@ import java.util.Map;
import java.util.Set;
import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.index.lucene.util.IndexCopier;
import org.apache.jackrabbit.oak.spi.commit.CompositeEditor;
import org.apache.jackrabbit.oak.spi.commit.DefaultEditor;
import org.apache.jackrabbit.oak.spi.commit.Editor;
@@ -53,10 +54,20 @@ class IndexTracker {
private static final Logger log =
LoggerFactory.getLogger(IndexTracker.class);
+ private final IndexCopier cloner;
+
private NodeState root = EMPTY_NODE;
private volatile Map<String, IndexNode> indices = emptyMap();
+ IndexTracker() {
+ this(null);
+ }
+
+ IndexTracker(IndexCopier cloner){
+ this.cloner = cloner;
+ }
+
synchronized void close() {
Map<String, IndexNode> indices = this.indices;
this.indices = emptyMap();
@@ -77,14 +88,13 @@ class IndexTracker {
List<Editor> editors = newArrayListWithCapacity(original.size());
for (Map.Entry<String, IndexNode> entry : original.entrySet()) {
final String path = entry.getKey();
- final String name = entry.getValue().getName();
editors.add(new SubtreeEditor(new DefaultEditor() {
@Override
public void leave(NodeState before, NodeState after) {
try {
// TODO: Use DirectoryReader.openIfChanged()
- IndexNode index = IndexNode.open(name, after);
+ IndexNode index = IndexNode.open(path, after, cloner);
updates.put(path, index); // index can be null
} catch (IOException e) {
log.error("Failed to open Lucene index at " + path, e);
@@ -102,6 +112,8 @@ class IndexTracker {
.putAll(filterValues(updates, notNull()))
.build();
+ //TODO This might take some time as close need to acquire the
+ //write lock which might be held by current running searches
for (String path : updates.keySet()) {
IndexNode index = original.get(path);
try {
@@ -141,10 +153,9 @@ class IndexTracker {
node = node.getChildNode(name);
}
- final String indexName = PathUtils.getName(path);
try {
if (isLuceneIndexNode(node)) {
- index = IndexNode.open(indexName, node);
+ index = IndexNode.open(path, node, cloner);
if (index != null) {
checkState(index.acquire());
indices = ImmutableMap.<String, IndexNode>builder()
Modified: jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProvider.java?rev=1635686&r1=1635685&r2=1635686&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProvider.java (original)
+++ jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProvider.java Fri Oct 31 06:26:55 2014
@@ -38,12 +38,20 @@ import com.google.common.collect.Immutab
*/
public class LuceneIndexProvider implements QueryIndexProvider, Observer, Closeable {
- protected final IndexTracker tracker = new IndexTracker();
+ protected final IndexTracker tracker;
protected volatile Analyzer analyzer = LuceneIndexConstants.ANALYZER;
protected volatile NodeAggregator aggregator = null;
+ public LuceneIndexProvider() {
+ this(new IndexTracker());
+ }
+
+ public LuceneIndexProvider(IndexTracker tracker) {
+ this.tracker = tracker;
+ }
+
public void close() {
tracker.close();
}
Modified: jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderService.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderService.java?rev=1635686&r1=1635685&r2=1635686&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderService.java (original)
+++ jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexProviderService.java Fri Oct 31 06:26:55 2014
@@ -19,12 +19,15 @@
package org.apache.jackrabbit.oak.plugins.index.lucene;
+import java.io.File;
import java.util.List;
import java.util.Map;
import javax.management.NotCompliantMBeanException;
+import com.google.common.base.Strings;
import com.google.common.collect.Lists;
+import org.apache.commons.io.FilenameUtils;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -37,9 +40,12 @@ import org.apache.jackrabbit.oak.commons
import org.apache.jackrabbit.oak.osgi.OsgiWhiteboard;
import org.apache.jackrabbit.oak.plugins.index.aggregate.AggregateIndexProvider;
import org.apache.jackrabbit.oak.plugins.index.aggregate.NodeAggregator;
+import org.apache.jackrabbit.oak.plugins.index.lucene.util.IndexCopier;
import org.apache.jackrabbit.oak.spi.commit.Observer;
import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
import org.apache.jackrabbit.oak.spi.whiteboard.Registration;
+import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard;
+import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardExecutor;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.util.InfoStream;
import org.osgi.framework.BundleContext;
@@ -47,15 +53,18 @@ import org.osgi.framework.ServiceRegistr
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static com.google.common.base.Preconditions.checkNotNull;
import static org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardUtils.registerMBean;
@SuppressWarnings("UnusedDeclaration")
@Component(metatype = true, label = "Apache Jackrabbit Oak LuceneIndexProvider")
public class LuceneIndexProviderService {
+ public static final String REPOSITORY_HOME = "repository.home";
private LuceneIndexProvider indexProvider;
private final List<ServiceRegistration> regs = Lists.newArrayList();
+ private final List<Registration> oakRegs = Lists.newArrayList();
private final Logger log = LoggerFactory.getLogger(getClass());
@@ -80,12 +89,30 @@ public class LuceneIndexProviderService
"controlled via changing log level for category 'oak.lucene' to debug")
private static final String PROP_DEBUG = "debug";
- private Registration mbeanReg;
+ @Property(
+ boolValue = false,
+ label = "Enable CopyOnRead",
+ description = "Enable copying of Lucene index to local file system to improve query performance"
+ )
+ private static final String PROP_COPY_ON_READ = "enableCopyOnReadSupport";
+
+ @Property(
+ label = "Local index storage path",
+ description = "Local file system path where Lucene indexes would be copied when CopyOnRead is enabled. " +
+ "If not specified then indexes would be stored under 'index' dir under Repository Home"
+ )
+ private static final String PROP_LOCAL_INDEX_DIR = "localIndexDir";
+
+ private Whiteboard whiteboard;
+
+ private WhiteboardExecutor executor;
@Activate
private void activate(BundleContext bundleContext, Map<String, ?> config)
throws NotCompliantMBeanException {
- indexProvider = new LuceneIndexProvider();
+ whiteboard = new OsgiWhiteboard(bundleContext);
+
+ indexProvider = new LuceneIndexProvider(createTracker(bundleContext, config));
initializeLogging(config);
initialize();
@@ -94,11 +121,11 @@ public class LuceneIndexProviderService
regs.add(bundleContext.registerService(QueryIndexProvider.class.getName(), aggregate, null));
regs.add(bundleContext.registerService(Observer.class.getName(), indexProvider, null));
- mbeanReg = registerMBean(new OsgiWhiteboard(bundleContext),
+ oakRegs.add(registerMBean(whiteboard,
LuceneIndexMBean.class,
new LuceneIndexMBeanImpl(indexProvider.getTracker()),
LuceneIndexMBean.TYPE,
- "Lucene Index statistics");
+ "Lucene Index statistics"));
}
@Deactivate
@@ -107,8 +134,8 @@ public class LuceneIndexProviderService
reg.unregister();
}
- if(mbeanReg != null){
- mbeanReg.unregister();
+ for (Registration reg : oakRegs){
+ reg.unregister();
}
if (indexProvider != null) {
@@ -116,6 +143,10 @@ public class LuceneIndexProviderService
indexProvider = null;
}
+ if (executor != null){
+ executor.stop();
+ }
+
InfoStream.setDefault(InfoStream.NO_OUTPUT);
}
@@ -143,6 +174,38 @@ public class LuceneIndexProviderService
}
}
+ private IndexTracker createTracker(BundleContext bundleContext, Map<String, ?> config) {
+ boolean enableCopyOnRead = PropertiesUtil.toBoolean(config.get(PROP_COPY_ON_READ), false);
+ if (enableCopyOnRead){
+ String indexDirPath = PropertiesUtil.toString(config.get(PROP_LOCAL_INDEX_DIR), null);
+ if (Strings.isNullOrEmpty(indexDirPath)) {
+ String repoHome = bundleContext.getProperty(REPOSITORY_HOME);
+ if (repoHome != null){
+ indexDirPath = FilenameUtils.concat(repoHome, "index");
+ }
+ }
+
+ checkNotNull(indexDirPath, "Index directory cannot be determined as neither index " +
+ "directory path [%s] nor repository home [%s] defined", PROP_LOCAL_INDEX_DIR, REPOSITORY_HOME);
+
+ File indexDir = new File(indexDirPath);
+ executor = new WhiteboardExecutor();
+ executor.start(whiteboard);
+ IndexCopier copier = new IndexCopier(executor, indexDir);
+ log.info("Enabling CopyOnRead support. Index files would be copied under {}", indexDir.getAbsolutePath());
+
+ oakRegs.add(registerMBean(whiteboard,
+ CopyOnReadStatsMBean.class,
+ copier,
+ CopyOnReadStatsMBean.TYPE,
+ "CopyOnRead support statistics"));
+
+ return new IndexTracker(copier);
+ }
+
+ return new IndexTracker();
+ }
+
protected void bindNodeAggregator(NodeAggregator aggregator) {
this.nodeAggregator = aggregator;
initialize();
Copied: jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/IndexCopier.java (from r1634505, jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/IndexCopier.java)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/IndexCopier.java?p2=jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/IndexCopier.java&p1=jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/IndexCopier.java&r1=1634505&r2=1635686&rev=1635686&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/IndexCopier.java (original)
+++ jackrabbit/oak/branches/1.0/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/util/IndexCopier.java Fri Oct 31 06:26:55 2014
@@ -22,14 +22,30 @@ package org.apache.jackrabbit.oak.plugin
import java.io.File;
import java.io.IOException;
import java.util.Collection;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.common.hash.Hashing;
+import org.apache.commons.io.FileUtils;
+import org.apache.jackrabbit.oak.commons.IOUtils;
+import org.apache.jackrabbit.oak.plugins.index.lucene.CopyOnReadStatsMBean;
import org.apache.jackrabbit.oak.plugins.index.lucene.IndexDefinition;
import org.apache.lucene.store.BaseDirectory;
import org.apache.lucene.store.Directory;
@@ -43,13 +59,19 @@ import org.slf4j.LoggerFactory;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Maps.newConcurrentMap;
-public class IndexCopier {
+public class IndexCopier implements CopyOnReadStatsMBean {
private static final Set<String> REMOTE_ONLY = ImmutableSet.of("segments.gen");
private final Logger log = LoggerFactory.getLogger(getClass());
private final Executor executor;
private final File indexRootDir;
+ private final AtomicInteger localReadCount = new AtomicInteger();
+ private final AtomicInteger remoteReadCount = new AtomicInteger();
+ private final AtomicLong downloadSize = new AtomicLong();
+ private final AtomicLong downloadTime = new AtomicLong();
+ private final Map<String, String> indexPathMapping = Maps.newConcurrentMap();
+
public IndexCopier(Executor executor, File indexRootDir) {
this.executor = executor;
this.indexRootDir = indexRootDir;
@@ -67,6 +89,7 @@ public class IndexCopier {
if (!indexDir.exists()) {
checkState(indexDir.mkdirs(), "Cannot create directory %s", indexDir);
}
+ indexPathMapping.put(indexPath, indexDir.getAbsolutePath());
return FSDirectory.open(indexDir);
}
@@ -126,6 +149,7 @@ public class IndexCopier {
if (ref.isLocalValid()) {
return files.get(name).openLocalInput(context);
} else {
+ remoteReadCount.incrementAndGet();
return remote.openInput(name, context);
}
}
@@ -151,8 +175,11 @@ public class IndexCopier {
String name = reference.name;
try {
if (!local.fileExists(name)) {
+ long start = System.currentTimeMillis();
remote.copy(local, name, name, IOContext.READ);
reference.markValid();
+ downloadTime.addAndGet(System.currentTimeMillis() - start);
+ downloadSize.addAndGet(remote.fileLength(name));
} else {
long localLength = local.fileLength(name);
long remoteLength = remote.fileLength(name);
@@ -246,6 +273,7 @@ public class IndexCopier {
}
IndexInput openLocalInput( IOContext context) throws IOException {
+ localReadCount.incrementAndGet();
return local.openInput(name, context);
}
@@ -254,4 +282,83 @@ public class IndexCopier {
}
}
}
+
+ //~------------------------------------------< CopyOnReadStatsMBean >
+
+ @Override
+ public TabularData getIndexPathMapping() {
+ TabularDataSupport tds;
+ try{
+ TabularType tt = new TabularType(IndexMappingData.class.getName(),
+ "Lucene Index Stats", IndexMappingData.TYPE, new String[]{"jcrPath"});
+ tds = new TabularDataSupport(tt);
+ for (Map.Entry<String, String> e : indexPathMapping.entrySet()){
+ tds.put(new CompositeDataSupport(IndexMappingData.TYPE,
+ IndexMappingData.FIELD_NAMES,
+ new String[] {e.getKey(), e.getValue()}));
+ }
+ } catch (OpenDataException e){
+ throw new IllegalStateException(e);
+ }
+ return tds;
+ }
+
+ @Override
+ public int getLocalReadCount() {
+ return localReadCount.get();
+ }
+
+ @Override
+ public int getRemoteReadCount() {
+ return remoteReadCount.get();
+ }
+
+ @Override
+ public String getDownloadSize() {
+ return IOUtils.humanReadableByteCount(downloadSize.get());
+ }
+
+ @Override
+ public long getDownloadTime() {
+ return downloadTime.get();
+ }
+
+ @Override
+ public String getLocalIndexSize() {
+ return IOUtils.humanReadableByteCount(FileUtils.sizeOfDirectory(indexRootDir));
+ }
+
+ private static class IndexMappingData {
+ static final String[] FIELD_NAMES = new String[]{
+ "jcrPath",
+ "fsPath",
+ };
+
+ static final String[] FIELD_DESCRIPTIONS = new String[]{
+ "JCR Path",
+ "Filesystem Path",
+ };
+
+ static final OpenType[] FIELD_TYPES = new OpenType[]{
+ SimpleType.STRING,
+ SimpleType.STRING,
+ };
+
+ static final CompositeType TYPE = createCompositeType();
+
+ static CompositeType createCompositeType() {
+ try {
+ return new CompositeType(
+ IndexMappingData.class.getName(),
+ "Composite data type for Index Mapping Data",
+ IndexMappingData.FIELD_NAMES,
+ IndexMappingData.FIELD_DESCRIPTIONS,
+ IndexMappingData.FIELD_TYPES);
+ } catch (OpenDataException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ }
+
}
Modified: jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java?rev=1635686&r1=1635685&r2=1635686&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java (original)
+++ jackrabbit/oak/branches/1.0/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexTest.java Fri Oct 31 06:26:55 2014
@@ -24,6 +24,7 @@ import javax.annotation.Nullable;
import static com.google.common.collect.ImmutableList.copyOf;
import static com.google.common.collect.Iterators.transform;
+import static com.google.common.util.concurrent.MoreExecutors.sameThreadExecutor;
import static javax.jcr.PropertyType.TYPENAME_STRING;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
@@ -43,6 +44,7 @@ import static org.apache.jackrabbit.oak.
import com.google.common.base.Function;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
+import org.apache.jackrabbit.oak.plugins.index.lucene.util.IndexCopier;
import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore;
import org.apache.jackrabbit.oak.query.QueryEngineSettings;
import org.apache.jackrabbit.oak.query.ast.Operator;
@@ -271,6 +273,33 @@ public class LuceneIndexTest {
assertQuery(tracker, indexed, "foo2", "bar2");
}
+ @Test
+ public void luceneWithCopyOnReadDir() throws Exception{
+ NodeBuilder index = builder.child(INDEX_DEFINITIONS_NAME);
+ newLuceneIndexDefinition(index, "lucene",
+ ImmutableSet.of(TYPENAME_STRING));
+
+ NodeState before = builder.getNodeState();
+ builder.setProperty("foo", "bar");
+ NodeState after = builder.getNodeState();
+
+ NodeState indexed = HOOK.processCommit(before, after,CommitInfo.EMPTY);
+
+ File indexRootDir = new File(getIndexDir());
+ IndexTracker tracker = new IndexTracker(new IndexCopier(sameThreadExecutor(), indexRootDir));
+ tracker.update(indexed);
+
+ assertQuery(tracker, indexed, "foo", "bar");
+
+ builder = indexed.builder();
+ builder.setProperty("foo2", "bar2");
+ indexed = HOOK.processCommit(indexed, builder.getNodeState(),CommitInfo.EMPTY);
+ tracker.update(indexed);
+
+ assertQuery(tracker, indexed, "foo2", "bar2");
+ }
+
+
private void assertQuery(IndexTracker tracker, NodeState indexed, String key, String value){
AdvancedQueryIndex queryIndex = new LuceneIndex(tracker, analyzer, null);
FilterImpl filter = createFilter(NT_BASE);