mirror of https://github.com/apache/lucene.git
SOLR-243: Add configurable IndexReaderFactory so that alternate IndexReader implementations can be specified via solrconfig.xml.
git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@782660 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
5f02ccf9ec
commit
0502d82893
|
@ -235,6 +235,9 @@ New Features
|
|||
59. SOLR-1189: Support providing username and password for basic HTTP authentication in Java replication
|
||||
(Matthew Gregg, shalin)
|
||||
|
||||
60. SOLR-243: Add configurable IndexReaderFactory so that alternate IndexReader implementations
|
||||
can be specified via solrconfig.xml. (Andrzej Bialecki, hossman, Mark Miller, John Wang)
|
||||
|
||||
Optimizations
|
||||
----------------------
|
||||
1. SOLR-374: Use IndexReader.reopen to save resources by re-using parts of the
|
||||
|
|
|
@ -436,9 +436,16 @@
|
|||
<copyField source="features" dest="text"/>
|
||||
<copyField source="includes" dest="text"/>
|
||||
|
||||
<!-- Above, multiple specific fields are copied to the [text] field.
|
||||
Another option is to use the dynamic field syntax. A maxChars to
|
||||
copy setting is also available. -->
|
||||
|
||||
<!-- <copyField source="*" dest="text" maxChars="3000"/> -->
|
||||
|
||||
|
||||
<copyField source="manu" dest="manu_exact"/>
|
||||
|
||||
<copyField source="name" dest="spell"/>
|
||||
<copyField source="name" dest="spell"/>
|
||||
|
||||
<!-- Similarity is the scoring routine for each document vs. a query.
|
||||
A custom similarity may be specified here, but the default is fine
|
||||
|
|
|
@ -206,6 +206,13 @@
|
|||
|
||||
</updateHandler>
|
||||
|
||||
<!-- Use the following format to specify a custom IndexReaderFactory - allows for alternate
|
||||
IndexReader implementations.
|
||||
<indexReaderFactory name="IndexReaderFactory" class="package.class">
|
||||
Parameters as required by the implementation
|
||||
</indexReaderFactory >
|
||||
-->
|
||||
|
||||
|
||||
<query>
|
||||
<!-- Maximum number of clauses in a boolean query... can affect
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package org.apache.solr.core;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
import org.apache.solr.util.plugin.NamedListInitializedPlugin;
|
||||
|
||||
/**
|
||||
* Factory used to build a new IndexReader instance.
|
||||
*/
|
||||
public abstract class IndexReaderFactory implements NamedListInitializedPlugin {
|
||||
|
||||
/**
|
||||
* <code>init</code> will be called just once, immediately after creation.
|
||||
* <p>
|
||||
* The args are user-level initialization parameters that may be specified
|
||||
* when declaring an indexReaderFactory in solrconfig.xml
|
||||
*/
|
||||
public void init(NamedList args) {
|
||||
/* :NOOP: */
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new IndexReader instance using the given Directory.
|
||||
*
|
||||
* @param indexDir indexDir index location
|
||||
* @param readOnly return readOnly IndexReader
|
||||
* @return An IndexReader instance
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract IndexReader newReader(Directory indexDir, boolean readOnly)
|
||||
throws IOException;
|
||||
}
|
|
@ -97,6 +97,7 @@ public final class SolrCore implements SolrInfoMBean {
|
|||
private final Map<String, SolrInfoMBean> infoRegistry;
|
||||
private IndexDeletionPolicyWrapper solrDelPolicy;
|
||||
private DirectoryFactory directoryFactory;
|
||||
private IndexReaderFactory indexReaderFactory;
|
||||
|
||||
public long getStartTime() { return startTime; }
|
||||
|
||||
|
@ -223,6 +224,10 @@ public final class SolrCore implements SolrInfoMBean {
|
|||
return directoryFactory;
|
||||
}
|
||||
|
||||
public IndexReaderFactory getIndexReaderFactory() {
|
||||
return indexReaderFactory;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
@ -341,6 +346,24 @@ public final class SolrCore implements SolrInfoMBean {
|
|||
directoryFactory = dirFactory;
|
||||
}
|
||||
|
||||
private void initIndexReaderFactory() {
|
||||
String xpath = "indexReaderFactory";
|
||||
Node node = (Node) solrConfig.evaluate(xpath, XPathConstants.NODE);
|
||||
IndexReaderFactory indexReaderFactory;
|
||||
if (node != null) {
|
||||
Map<String, IndexReaderFactory> registry = new HashMap<String, IndexReaderFactory>();
|
||||
NamedListPluginLoader<IndexReaderFactory> indexReaderFactoryLoader = new NamedListPluginLoader<IndexReaderFactory>(
|
||||
"[solrconfig.xml] " + xpath, registry);
|
||||
|
||||
indexReaderFactory = indexReaderFactoryLoader.loadSingle(solrConfig
|
||||
.getResourceLoader(), node);
|
||||
} else {
|
||||
indexReaderFactory = new StandardIndexReaderFactory();
|
||||
}
|
||||
|
||||
this.indexReaderFactory = indexReaderFactory;
|
||||
}
|
||||
|
||||
// protect via synchronized(SolrCore.class)
|
||||
private static Set<String> dirs = new HashSet<String>();
|
||||
|
||||
|
@ -355,6 +378,7 @@ public final class SolrCore implements SolrInfoMBean {
|
|||
boolean removeLocks = solrConfig.unlockOnStartup;
|
||||
|
||||
initDirectoryFactory();
|
||||
initIndexReaderFactory();
|
||||
|
||||
if (indexExists && firstTime && removeLocks) {
|
||||
// to remove locks, the directory must already exist... so we create it
|
||||
|
@ -1048,21 +1072,22 @@ public final class SolrCore implements SolrInfoMBean {
|
|||
try {
|
||||
newestSearcher = getNewestSearcher(false);
|
||||
String newIndexDir = getNewIndexDir();
|
||||
if (newestSearcher != null) {
|
||||
File indexDirFile = new File(getIndexDir()).getCanonicalFile();
|
||||
File newIndexDirFile = new File(newIndexDir).getCanonicalFile();
|
||||
|
||||
if (newestSearcher != null && solrConfig.reopenReaders
|
||||
&& indexDirFile.equals(newIndexDirFile)) {
|
||||
IndexReader currentReader = newestSearcher.get().getReader();
|
||||
if(solrConfig.reopenReaders && new File(getIndexDir()).getCanonicalFile().equals(new File(newIndexDir).getCanonicalFile())) {
|
||||
IndexReader newReader = currentReader.reopen();
|
||||
IndexReader newReader = currentReader.reopen();
|
||||
|
||||
if(newReader == currentReader) {
|
||||
currentReader.incRef();
|
||||
}
|
||||
|
||||
tmp = new SolrIndexSearcher(this, schema, "main", newReader, true, true);
|
||||
} else {
|
||||
tmp = new SolrIndexSearcher(this, schema, "main", getDirectoryFactory().open(newIndexDir), true, true);
|
||||
if (newReader == currentReader) {
|
||||
currentReader.incRef();
|
||||
}
|
||||
|
||||
tmp = new SolrIndexSearcher(this, schema, "main", newReader, true, true);
|
||||
} else {
|
||||
tmp = new SolrIndexSearcher(this, schema, "main", getDirectoryFactory().open(newIndexDir), true, true);
|
||||
IndexReader reader = getIndexReaderFactory().newReader(getDirectoryFactory().open(newIndexDir), true);
|
||||
tmp = new SolrIndexSearcher(this, schema, "main", reader, true, true);
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
synchronized(searcherLock) {
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package org.apache.solr.core;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.store.Directory;
|
||||
|
||||
/**
|
||||
* Default IndexReaderFactory implementation. Returns a standard Lucene
|
||||
* IndexReader.
|
||||
*
|
||||
* @see IndexReader#open(Directory)
|
||||
*/
|
||||
public class StandardIndexReaderFactory extends IndexReaderFactory {
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.apache.solr.core.IndexReaderFactory#newReader(org.apache.lucene.store.Directory, boolean)
|
||||
*/
|
||||
public IndexReader newReader(Directory indexDir, boolean readOnly)
|
||||
throws IOException {
|
||||
return IndexReader.open(indexDir, readOnly);
|
||||
}
|
||||
}
|
|
@ -24,7 +24,6 @@ import org.apache.lucene.index.TermDocs;
|
|||
import org.apache.lucene.search.*;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.lucene.store.FSDirectory;
|
||||
import org.apache.lucene.util.PriorityQueue;
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
import org.apache.solr.common.util.SimpleOrderedMap;
|
||||
import org.apache.solr.core.SolrConfig;
|
||||
|
@ -33,7 +32,6 @@ import org.apache.solr.core.SolrInfoMBean;
|
|||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.apache.solr.schema.SchemaField;
|
||||
import org.apache.solr.request.UnInvertedField;
|
||||
import org.apache.solr.search.function.BoostedQuery;
|
||||
import org.apache.lucene.util.OpenBitSet;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -92,17 +90,23 @@ public class SolrIndexSearcher extends IndexSearcher implements SolrInfoMBean {
|
|||
* @deprecated use alternate constructor
|
||||
*/
|
||||
public SolrIndexSearcher(SolrCore core, IndexSchema schema, String name, String path, boolean enableCache) throws IOException {
|
||||
this(core, schema,name,IndexReader.open(path), true, enableCache);
|
||||
this(core, schema,name, core.getIndexReaderFactory().newReader(core.getDirectoryFactory().open(path), false), true, enableCache);
|
||||
}
|
||||
|
||||
/** Creates a searcher searching the index in the provided directory. */
|
||||
public SolrIndexSearcher(SolrCore core, IndexSchema schema, String name, Directory directory, boolean enableCache) throws IOException {
|
||||
this(core, schema,name,IndexReader.open(directory), true, enableCache);
|
||||
/*
|
||||
* Creates a searcher searching the index in the provided directory. Note:
|
||||
* uses the main IndexReaderFactory for the specified SolrCore.
|
||||
*
|
||||
* @see SolrCore#getMainIndexReaderFactory
|
||||
*/
|
||||
public SolrIndexSearcher(SolrCore core, IndexSchema schema, String name,
|
||||
Directory directory, boolean enableCache) throws IOException {
|
||||
this(core, schema,name, core.getIndexReaderFactory().newReader(directory, false), true, enableCache);
|
||||
}
|
||||
|
||||
/** Creates a searcher searching the index in the provided directory. */
|
||||
public SolrIndexSearcher(SolrCore core, IndexSchema schema, String name, Directory directory, boolean readOnly, boolean enableCache) throws IOException {
|
||||
this(core, schema,name,IndexReader.open(directory, readOnly), true, enableCache);
|
||||
this(core, schema,name, core.getIndexReaderFactory().newReader(directory, readOnly), true, enableCache);
|
||||
}
|
||||
|
||||
/** Creates a searcher searching the provided index. */
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
package org.apache.solr.core;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.store.Directory;
|
||||
import org.apache.solr.util.AbstractSolrTestCase;
|
||||
|
||||
public class AlternateIndexReaderTest extends AbstractSolrTestCase {
|
||||
|
||||
public String getSchemaFile() {
|
||||
return "schema.xml";
|
||||
}
|
||||
|
||||
public String getSolrConfigFile() {
|
||||
return "solrconfig-altdirectory.xml";
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple test to ensure that alternate IndexReaderFactory is being used.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testAltReaderUsed() throws Exception {
|
||||
assertTrue(TestIndexReaderFactory.newReaderCalled);
|
||||
}
|
||||
|
||||
static public class TestIndexReaderFactory extends IndexReaderFactory {
|
||||
|
||||
static boolean newReaderCalled = false;
|
||||
|
||||
public IndexReader newReader(Directory indexDir) throws IOException {
|
||||
TestIndexReaderFactory.newReaderCalled = true;
|
||||
return IndexReader.open(indexDir);
|
||||
}
|
||||
|
||||
public IndexReader newReader(Directory indexDir, boolean readOnly)
|
||||
throws IOException {
|
||||
TestIndexReaderFactory.newReaderCalled = true;
|
||||
return IndexReader.open(indexDir, readOnly);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -134,6 +134,11 @@
|
|||
<!-- Parameters as required by the implementation -->
|
||||
</directoryFactory>
|
||||
|
||||
|
||||
<indexReaderFactory name="IndexReaderFactory" class="org.apache.solr.core.AlternateIndexReaderTest$TestIndexReaderFactory">
|
||||
<!-- Parameters as required by the implementation -->
|
||||
</indexReaderFactory >
|
||||
|
||||
<query>
|
||||
<!-- Maximum number of clauses in a boolean query... can affect
|
||||
range or wildcard queries that expand to big boolean
|
||||
|
|
Loading…
Reference in New Issue