mirror of https://github.com/apache/lucene.git
SOLR-1942: Ability to specify codec per field
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1127313 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
9b31ee389f
commit
530b894c60
|
@ -88,6 +88,15 @@ public class CodecProvider {
|
||||||
return codec;
|
return codec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> iff a codec with the given name is registered
|
||||||
|
* @param name codec name
|
||||||
|
* @return <code>true</code> iff a codec with the given name is registered, otherwise <code>false</code>.
|
||||||
|
*/
|
||||||
|
public synchronized boolean isCodecRegistered(String name) {
|
||||||
|
return codecs.containsKey(name);
|
||||||
|
}
|
||||||
|
|
||||||
public SegmentInfosWriter getSegmentInfosWriter() {
|
public SegmentInfosWriter getSegmentInfosWriter() {
|
||||||
return infosWriter;
|
return infosWriter;
|
||||||
}
|
}
|
||||||
|
@ -145,6 +154,14 @@ public class CodecProvider {
|
||||||
return codec;
|
return codec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>true</code> if this provider has a Codec registered for this
|
||||||
|
* field.
|
||||||
|
*/
|
||||||
|
public synchronized boolean hasFieldCodec(String name) {
|
||||||
|
return perFieldMap.containsKey(name);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the default {@link Codec} for this {@link CodecProvider}
|
* Returns the default {@link Codec} for this {@link CodecProvider}
|
||||||
*
|
*
|
||||||
|
|
|
@ -1382,6 +1382,11 @@ public abstract class LuceneTestCase extends Assert {
|
||||||
return codec.name;
|
return codec.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized boolean hasFieldCodec(String name) {
|
||||||
|
return true; // we have a codec for every field
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized String toString() {
|
public synchronized String toString() {
|
||||||
return "RandomCodecProvider: " + previousMappings.toString();
|
return "RandomCodecProvider: " + previousMappings.toString();
|
||||||
|
|
|
@ -144,6 +144,11 @@ New Features
|
||||||
fq={!join from=name to=parent}eyes:blue
|
fq={!join from=name to=parent}eyes:blue
|
||||||
(yonik)
|
(yonik)
|
||||||
|
|
||||||
|
* SOLR-1942: Added the ability to select codec per fieldType in schema.xml
|
||||||
|
as well as support custom CodecProviders in solrconfig.xml.
|
||||||
|
NOTE: IndexReaderFactory now has a codecProvider that should be passed
|
||||||
|
to IndexReader.open (in the case you have a custom IndexReaderFactory).
|
||||||
|
(simonw via rmuir)
|
||||||
|
|
||||||
|
|
||||||
Optimizations
|
Optimizations
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
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 org.apache.lucene.index.codecs.CodecProvider;
|
||||||
|
import org.apache.solr.common.util.NamedList;
|
||||||
|
import org.apache.solr.util.plugin.NamedListInitializedPlugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory for plugging in a custom {@link CodecProvider}
|
||||||
|
*/
|
||||||
|
public abstract class CodecProviderFactory implements NamedListInitializedPlugin {
|
||||||
|
public void init(NamedList args) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract CodecProvider create();
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ package org.apache.solr.core;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.apache.lucene.index.IndexReader;
|
import org.apache.lucene.index.IndexReader;
|
||||||
|
import org.apache.lucene.index.codecs.CodecProvider;
|
||||||
import org.apache.lucene.store.Directory;
|
import org.apache.lucene.store.Directory;
|
||||||
import org.apache.solr.common.util.NamedList;
|
import org.apache.solr.common.util.NamedList;
|
||||||
import org.apache.solr.util.plugin.NamedListInitializedPlugin;
|
import org.apache.solr.util.plugin.NamedListInitializedPlugin;
|
||||||
|
@ -28,6 +29,7 @@ import org.apache.solr.util.plugin.NamedListInitializedPlugin;
|
||||||
*/
|
*/
|
||||||
public abstract class IndexReaderFactory implements NamedListInitializedPlugin {
|
public abstract class IndexReaderFactory implements NamedListInitializedPlugin {
|
||||||
protected int termInfosIndexDivisor = 1;//IndexReader.DEFAULT_TERMS_INDEX_DIVISOR; Set this once Lucene makes this public.
|
protected int termInfosIndexDivisor = 1;//IndexReader.DEFAULT_TERMS_INDEX_DIVISOR; Set this once Lucene makes this public.
|
||||||
|
protected CodecProvider provider;
|
||||||
/**
|
/**
|
||||||
* Potentially initializes {@link #termInfosIndexDivisor}. Overriding classes should call super.init() in order
|
* Potentially initializes {@link #termInfosIndexDivisor}. Overriding classes should call super.init() in order
|
||||||
* to make sure termInfosIndexDivisor is set.
|
* to make sure termInfosIndexDivisor is set.
|
||||||
|
@ -63,4 +65,11 @@ public abstract class IndexReaderFactory implements NamedListInitializedPlugin {
|
||||||
*/
|
*/
|
||||||
public abstract IndexReader newReader(Directory indexDir, boolean readOnly)
|
public abstract IndexReader newReader(Directory indexDir, boolean readOnly)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the codec provider for this IndexReaderFactory
|
||||||
|
*/
|
||||||
|
public void setCodecProvider(CodecProvider provider) {
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
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.util.Collection;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.lucene.index.codecs.Codec;
|
||||||
|
import org.apache.lucene.index.codecs.CodecProvider;
|
||||||
|
import org.apache.lucene.index.codecs.SegmentInfosReader;
|
||||||
|
import org.apache.lucene.index.codecs.SegmentInfosWriter;
|
||||||
|
import org.apache.solr.schema.IndexSchema;
|
||||||
|
import org.apache.solr.schema.SchemaField;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects a codec based on a {@link IndexSchema}. This {@link CodecProvider}
|
||||||
|
* also supports dynamic fields such that not all field codecs need to be known
|
||||||
|
* in advance
|
||||||
|
*/
|
||||||
|
final class SchemaCodecProvider extends CodecProvider {
|
||||||
|
private final IndexSchema schema;
|
||||||
|
private final CodecProvider delegate;
|
||||||
|
|
||||||
|
SchemaCodecProvider(IndexSchema schema, CodecProvider delegate) {
|
||||||
|
this.schema = schema;
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Codec lookup(String name) {
|
||||||
|
synchronized (delegate) {
|
||||||
|
return delegate.lookup(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFieldCodec(String name) {
|
||||||
|
synchronized (delegate) {
|
||||||
|
if (!delegate.hasFieldCodec(name)) {
|
||||||
|
final SchemaField fieldOrNull = schema.getFieldOrNull(name);
|
||||||
|
if (fieldOrNull == null) {
|
||||||
|
throw new IllegalArgumentException("no such field " + name);
|
||||||
|
}
|
||||||
|
String codecName = fieldOrNull.getType().getCodec();
|
||||||
|
if (codecName == null) {
|
||||||
|
codecName = delegate.getDefaultFieldCodec();
|
||||||
|
}
|
||||||
|
delegate.setFieldCodec(name, codecName);
|
||||||
|
return codecName;
|
||||||
|
}
|
||||||
|
return delegate.getFieldCodec(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return delegate.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void register(Codec codec) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unregister(Codec codec) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<String> getAllExtensions() {
|
||||||
|
return delegate.getAllExtensions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SegmentInfosWriter getSegmentInfosWriter() {
|
||||||
|
return delegate.getSegmentInfosWriter();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SegmentInfosReader getSegmentInfosReader() {
|
||||||
|
return delegate.getSegmentInfosReader();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return delegate.equals(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFieldCodec(String field, String codec) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDefaultFieldCodec() {
|
||||||
|
return delegate.getDefaultFieldCodec();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCodecRegistered(String name) {
|
||||||
|
synchronized (delegate) {
|
||||||
|
return delegate.isCodecRegistered(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDefaultFieldCodec(String codec) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasFieldCodec(String fieldName) {
|
||||||
|
synchronized (delegate) {
|
||||||
|
if (!delegate.hasFieldCodec(fieldName)) {
|
||||||
|
final SchemaField fieldOrNull = schema.getFieldOrNull(fieldName);
|
||||||
|
if (fieldOrNull == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String codecName = fieldOrNull.getType().getCodec();
|
||||||
|
if (codecName == null) {
|
||||||
|
codecName = delegate.getDefaultFieldCodec();
|
||||||
|
}
|
||||||
|
delegate.setFieldCodec(fieldName, codecName);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "SchemaCodecProvider(" + delegate.toString() + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> listAll() {
|
||||||
|
synchronized (delegate) {
|
||||||
|
return delegate.listAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -39,6 +39,8 @@ import org.apache.solr.spelling.QueryConverter;
|
||||||
import org.apache.solr.highlight.SolrHighlighter;
|
import org.apache.solr.highlight.SolrHighlighter;
|
||||||
import org.apache.lucene.search.BooleanQuery;
|
import org.apache.lucene.search.BooleanQuery;
|
||||||
import org.apache.lucene.index.IndexDeletionPolicy;
|
import org.apache.lucene.index.IndexDeletionPolicy;
|
||||||
|
import org.apache.lucene.index.codecs.Codec;
|
||||||
|
import org.apache.lucene.index.codecs.CodecProvider;
|
||||||
import org.apache.lucene.util.Version;
|
import org.apache.lucene.util.Version;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -202,6 +204,7 @@ public class SolrConfig extends Config {
|
||||||
|
|
||||||
loadPluginInfo(DirectoryFactory.class,"directoryFactory",false, true);
|
loadPluginInfo(DirectoryFactory.class,"directoryFactory",false, true);
|
||||||
loadPluginInfo(IndexDeletionPolicy.class,"mainIndex/deletionPolicy",false, true);
|
loadPluginInfo(IndexDeletionPolicy.class,"mainIndex/deletionPolicy",false, true);
|
||||||
|
loadPluginInfo(CodecProviderFactory.class,"mainIndex/codecProviderFactory",false, false);
|
||||||
loadPluginInfo(IndexReaderFactory.class,"indexReaderFactory",false, true);
|
loadPluginInfo(IndexReaderFactory.class,"indexReaderFactory",false, true);
|
||||||
loadPluginInfo(UpdateRequestProcessorChain.class,"updateRequestProcessorChain",false, false);
|
loadPluginInfo(UpdateRequestProcessorChain.class,"updateRequestProcessorChain",false, false);
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@ package org.apache.solr.core;
|
||||||
import org.apache.lucene.index.IndexDeletionPolicy;
|
import org.apache.lucene.index.IndexDeletionPolicy;
|
||||||
import org.apache.lucene.index.IndexReader;
|
import org.apache.lucene.index.IndexReader;
|
||||||
import org.apache.lucene.index.IndexWriter;
|
import org.apache.lucene.index.IndexWriter;
|
||||||
|
import org.apache.lucene.index.codecs.Codec;
|
||||||
|
import org.apache.lucene.index.codecs.CodecProvider;
|
||||||
import org.apache.lucene.search.BooleanQuery;
|
import org.apache.lucene.search.BooleanQuery;
|
||||||
import org.apache.lucene.store.Directory;
|
import org.apache.lucene.store.Directory;
|
||||||
import org.apache.solr.common.SolrException;
|
import org.apache.solr.common.SolrException;
|
||||||
|
@ -93,6 +95,7 @@ public final class SolrCore implements SolrInfoMBean {
|
||||||
private IndexDeletionPolicyWrapper solrDelPolicy;
|
private IndexDeletionPolicyWrapper solrDelPolicy;
|
||||||
private DirectoryFactory directoryFactory;
|
private DirectoryFactory directoryFactory;
|
||||||
private IndexReaderFactory indexReaderFactory;
|
private IndexReaderFactory indexReaderFactory;
|
||||||
|
private final CodecProvider codecProvider;
|
||||||
|
|
||||||
public long getStartTime() { return startTime; }
|
public long getStartTime() { return startTime; }
|
||||||
|
|
||||||
|
@ -330,6 +333,7 @@ public final class SolrCore implements SolrInfoMBean {
|
||||||
indexReaderFactory = new StandardIndexReaderFactory();
|
indexReaderFactory = new StandardIndexReaderFactory();
|
||||||
}
|
}
|
||||||
this.indexReaderFactory = indexReaderFactory;
|
this.indexReaderFactory = indexReaderFactory;
|
||||||
|
this.indexReaderFactory.setCodecProvider(codecProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
// protect via synchronized(SolrCore.class)
|
// protect via synchronized(SolrCore.class)
|
||||||
|
@ -366,7 +370,7 @@ public final class SolrCore implements SolrInfoMBean {
|
||||||
log.warn(logid+"Solr index directory '" + new File(indexDir) + "' doesn't exist."
|
log.warn(logid+"Solr index directory '" + new File(indexDir) + "' doesn't exist."
|
||||||
+ " Creating new index...");
|
+ " Creating new index...");
|
||||||
|
|
||||||
SolrIndexWriter writer = new SolrIndexWriter("SolrCore.initIndex", indexDir, getDirectoryFactory(), true, schema, solrConfig.mainIndexConfig, solrDelPolicy);
|
SolrIndexWriter writer = new SolrIndexWriter("SolrCore.initIndex", indexDir, getDirectoryFactory(), true, schema, solrConfig.mainIndexConfig, solrDelPolicy, codecProvider);
|
||||||
writer.close();
|
writer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -493,6 +497,7 @@ public final class SolrCore implements SolrInfoMBean {
|
||||||
|
|
||||||
initDeletionPolicy();
|
initDeletionPolicy();
|
||||||
|
|
||||||
|
this.codecProvider = initCodecProvider(solrConfig, schema);
|
||||||
initIndex();
|
initIndex();
|
||||||
|
|
||||||
initWriters();
|
initWriters();
|
||||||
|
@ -555,6 +560,19 @@ public final class SolrCore implements SolrInfoMBean {
|
||||||
resourceLoader.inform(infoRegistry);
|
resourceLoader.inform(infoRegistry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CodecProvider initCodecProvider(SolrConfig solrConfig, IndexSchema schema) {
|
||||||
|
final PluginInfo info = solrConfig.getPluginInfo(CodecProviderFactory.class.getName());
|
||||||
|
CodecProvider cp;
|
||||||
|
if (info != null) {
|
||||||
|
CodecProviderFactory factory = (CodecProviderFactory) schema.getResourceLoader().newInstance(info.className);
|
||||||
|
factory.init(info.initArgs);
|
||||||
|
cp = factory.create();
|
||||||
|
} else {
|
||||||
|
// make sure we use the default if nothing is configured
|
||||||
|
cp = CodecProvider.getDefault();
|
||||||
|
}
|
||||||
|
return new SchemaCodecProvider(schema, cp);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the request processors
|
* Load the request processors
|
||||||
|
@ -1618,6 +1636,10 @@ public final class SolrCore implements SolrInfoMBean {
|
||||||
}
|
}
|
||||||
return lst;
|
return lst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CodecProvider getCodecProvider() {
|
||||||
|
return codecProvider;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,6 @@ public class StandardIndexReaderFactory extends IndexReaderFactory {
|
||||||
@Override
|
@Override
|
||||||
public IndexReader newReader(Directory indexDir, boolean readOnly)
|
public IndexReader newReader(Directory indexDir, boolean readOnly)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
return IndexReader.open(indexDir, null, readOnly, termInfosIndexDivisor);
|
return IndexReader.open(indexDir, null, readOnly, termInfosIndexDivisor, provider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,6 +167,12 @@ public abstract class FieldType extends FieldProperties {
|
||||||
initArgs.remove("positionIncrementGap");
|
initArgs.remove("positionIncrementGap");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final String codec = initArgs.get("codec");
|
||||||
|
if (codec != null) {
|
||||||
|
this.codec = codec;
|
||||||
|
initArgs.remove("codec");
|
||||||
|
}
|
||||||
|
|
||||||
if (initArgs.size() > 0) {
|
if (initArgs.size() > 0) {
|
||||||
throw new RuntimeException("schema fieldtype " + typeName
|
throw new RuntimeException("schema fieldtype " + typeName
|
||||||
+ "("+ this.getClass().getName() + ")"
|
+ "("+ this.getClass().getName() + ")"
|
||||||
|
@ -537,6 +543,15 @@ public abstract class FieldType extends FieldProperties {
|
||||||
this.similarity = similarity;
|
this.similarity = similarity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The codec ID used for this field type
|
||||||
|
*/
|
||||||
|
protected String codec;
|
||||||
|
|
||||||
|
public String getCodec() {
|
||||||
|
return codec;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* calls back to TextResponseWriter to write the field value
|
* calls back to TextResponseWriter to write the field value
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -18,7 +18,10 @@
|
||||||
package org.apache.solr.update;
|
package org.apache.solr.update;
|
||||||
|
|
||||||
import org.apache.lucene.index.*;
|
import org.apache.lucene.index.*;
|
||||||
|
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
|
||||||
|
import org.apache.lucene.index.codecs.CodecProvider;
|
||||||
import org.apache.lucene.store.*;
|
import org.apache.lucene.store.*;
|
||||||
|
import org.apache.lucene.util.Version;
|
||||||
import org.apache.solr.common.SolrException;
|
import org.apache.solr.common.SolrException;
|
||||||
import org.apache.solr.core.DirectoryFactory;
|
import org.apache.solr.core.DirectoryFactory;
|
||||||
import org.apache.solr.schema.IndexSchema;
|
import org.apache.solr.schema.IndexSchema;
|
||||||
|
@ -27,6 +30,7 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
@ -79,16 +83,21 @@ public class SolrIndexWriter extends IndexWriter {
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SolrIndexWriter(String name, String path, DirectoryFactory dirFactory, boolean create, IndexSchema schema, SolrIndexConfig config, IndexDeletionPolicy delPolicy) throws IOException {
|
public SolrIndexWriter(String name, String path, DirectoryFactory dirFactory, boolean create, IndexSchema schema, SolrIndexConfig config, IndexDeletionPolicy delPolicy, CodecProvider codecProvider) throws IOException {
|
||||||
super(
|
super(
|
||||||
getDirectory(path, dirFactory, config),
|
getDirectory(path, dirFactory, config),
|
||||||
config.toIndexWriterConfig(schema).
|
config.toIndexWriterConfig(schema).
|
||||||
setOpenMode(create ? IndexWriterConfig.OpenMode.CREATE : IndexWriterConfig.OpenMode.APPEND).
|
setOpenMode(create ? IndexWriterConfig.OpenMode.CREATE : IndexWriterConfig.OpenMode.APPEND).
|
||||||
setIndexDeletionPolicy(delPolicy)
|
setIndexDeletionPolicy(delPolicy).setCodecProvider(codecProvider)
|
||||||
);
|
);
|
||||||
log.debug("Opened Writer " + name);
|
log.debug("Opened Writer " + name);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
||||||
|
setInfoStream(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setInfoStream(SolrIndexConfig config)
|
||||||
|
throws IOException {
|
||||||
String infoStreamFile = config.infoStreamFile;
|
String infoStreamFile = config.infoStreamFile;
|
||||||
if (infoStreamFile != null) {
|
if (infoStreamFile != null) {
|
||||||
File f = new File(infoStreamFile);
|
File f = new File(infoStreamFile);
|
||||||
|
|
|
@ -98,7 +98,7 @@ public abstract class UpdateHandler implements SolrInfoMBean {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SolrIndexWriter createMainIndexWriter(String name, boolean removeAllExisting) throws IOException {
|
protected SolrIndexWriter createMainIndexWriter(String name, boolean removeAllExisting) throws IOException {
|
||||||
return new SolrIndexWriter(name,core.getNewIndexDir(), core.getDirectoryFactory(), removeAllExisting, schema, core.getSolrConfig().mainIndexConfig, core.getDeletionPolicy());
|
return new SolrIndexWriter(name,core.getNewIndexDir(), core.getDirectoryFactory(), removeAllExisting, schema, core.getSolrConfig().mainIndexConfig, core.getDeletionPolicy(), core.getCodecProvider());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final Term idTerm(String readableId) {
|
protected final Term idTerm(String readableId) {
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<schema name="codec" version="1.2">
|
||||||
|
<types>
|
||||||
|
<fieldType name="string_pulsing" class="solr.StrField" codec="Pulsing"/>
|
||||||
|
<fieldType name="string_simpletext" class="solr.StrField" codec="SimpleText"/>
|
||||||
|
<fieldType name="string_standard" class="solr.StrField" codec="Standard"/>
|
||||||
|
<fieldType name="string" class="solr.StrField" />
|
||||||
|
|
||||||
|
</types>
|
||||||
|
<fields>
|
||||||
|
<field name="string_pulsing_f" type="string_pulsing" indexed="true" stored="true" />
|
||||||
|
<field name="string_simpletext_f" type="string_simpletext" indexed="true" stored="true" />
|
||||||
|
<field name="string_standard_f" type="string_standard" indexed="true" stored="true" />
|
||||||
|
<field name="string_f" type="string" indexed="true" stored="true" />
|
||||||
|
<dynamicField name="*_simple" type="string_simpletext" indexed="true" stored="true"/>
|
||||||
|
<dynamicField name="*_pulsing" type="string_pulsing" indexed="true" stored="true"/>
|
||||||
|
<dynamicField name="*_standard" type="string_standard" indexed="true" stored="true"/>
|
||||||
|
|
||||||
|
</fields>
|
||||||
|
<defaultSearchField>string_f</defaultSearchField>
|
||||||
|
<uniqueKey>string_f</uniqueKey>
|
||||||
|
</schema>
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<config>
|
||||||
|
<luceneMatchVersion>${tests.luceneMatchVersion:LUCENE_CURRENT}</luceneMatchVersion>
|
||||||
|
|
||||||
|
<mainIndex>
|
||||||
|
<codecProviderFactory class="org.apache.solr.core.MockCodecProviderFactory">
|
||||||
|
<str name="defaultCodec">Pulsing</str>
|
||||||
|
<lst name="codecs">
|
||||||
|
<str name="codec">org.apache.lucene.index.codecs.simpletext.SimpleTextCodec</str>
|
||||||
|
<str name="codec">org.apache.lucene.index.codecs.preflex.PreFlexCodec</str>
|
||||||
|
</lst>
|
||||||
|
</codecProviderFactory>
|
||||||
|
</mainIndex>
|
||||||
|
|
||||||
|
<requestHandler name="standard" class="solr.StandardRequestHandler"></requestHandler>
|
||||||
|
</config>
|
|
@ -120,7 +120,7 @@ public class BasicFunctionalityTest extends SolrTestCaseJ4 {
|
||||||
// test merge factor picked up
|
// test merge factor picked up
|
||||||
SolrCore core = h.getCore();
|
SolrCore core = h.getCore();
|
||||||
|
|
||||||
SolrIndexWriter writer = new SolrIndexWriter("testWriter",core.getNewIndexDir(), core.getDirectoryFactory(), false, core.getSchema(), core.getSolrConfig().mainIndexConfig, core.getDeletionPolicy());
|
SolrIndexWriter writer = new SolrIndexWriter("testWriter",core.getNewIndexDir(), core.getDirectoryFactory(), false, core.getSchema(), core.getSolrConfig().mainIndexConfig, core.getDeletionPolicy(), core.getCodecProvider());
|
||||||
assertEquals("Mergefactor was not picked up", ((LogMergePolicy) writer.getConfig().getMergePolicy()).getMergeFactor(), 8);
|
assertEquals("Mergefactor was not picked up", ((LogMergePolicy) writer.getConfig().getMergePolicy()).getMergeFactor(), 8);
|
||||||
writer.close();
|
writer.close();
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class BasicZkTest extends AbstractZkTestCase {
|
||||||
SolrCore core = h.getCore();
|
SolrCore core = h.getCore();
|
||||||
SolrIndexWriter writer = new SolrIndexWriter("testWriter", core
|
SolrIndexWriter writer = new SolrIndexWriter("testWriter", core
|
||||||
.getNewIndexDir(), core.getDirectoryFactory(), false, core.getSchema(),
|
.getNewIndexDir(), core.getDirectoryFactory(), false, core.getSchema(),
|
||||||
core.getSolrConfig().mainIndexConfig, core.getDeletionPolicy());
|
core.getSolrConfig().mainIndexConfig, core.getDeletionPolicy(), core.getCodecProvider());
|
||||||
assertEquals("Mergefactor was not picked up", ((LogMergePolicy)writer.getConfig().getMergePolicy()).getMergeFactor(), 8);
|
assertEquals("Mergefactor was not picked up", ((LogMergePolicy)writer.getConfig().getMergePolicy()).getMergeFactor(), 8);
|
||||||
writer.close();
|
writer.close();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
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 org.apache.lucene.index.codecs.Codec;
|
||||||
|
import org.apache.lucene.index.codecs.CodecProvider;
|
||||||
|
import org.apache.lucene.index.codecs.pulsing.PulsingCodec;
|
||||||
|
import org.apache.lucene.index.codecs.standard.StandardCodec;
|
||||||
|
import org.apache.solr.common.util.NamedList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CodecProviderFactory for testing, it inits a CP with Standard and Pulsing,
|
||||||
|
* and also adds any codecs specified by classname in solrconfig.
|
||||||
|
*/
|
||||||
|
public class MockCodecProviderFactory extends CodecProviderFactory {
|
||||||
|
private String defaultCodec;
|
||||||
|
private NamedList codecs;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(NamedList args) {
|
||||||
|
super.init(args);
|
||||||
|
defaultCodec = (String) args.get("defaultCodec");
|
||||||
|
codecs = (NamedList) args.get("codecs");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CodecProvider create() {
|
||||||
|
CodecProvider cp = new CodecProvider();
|
||||||
|
cp.register(new StandardCodec());
|
||||||
|
cp.register(new PulsingCodec(1));
|
||||||
|
if (codecs != null) {
|
||||||
|
for (Object codec : codecs.getAll("name")) {
|
||||||
|
if (!cp.isCodecRegistered((String)codec)) {
|
||||||
|
try {
|
||||||
|
Class<? extends Codec> clazz = Class.forName((String)codec).asSubclass(Codec.class);
|
||||||
|
cp.register(clazz.newInstance());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (defaultCodec != null) {
|
||||||
|
cp.setDefaultFieldCodec(defaultCodec);
|
||||||
|
}
|
||||||
|
return cp;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
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.util.Map;
|
||||||
|
|
||||||
|
import org.apache.lucene.index.codecs.CodecProvider;
|
||||||
|
import org.apache.lucene.index.codecs.standard.StandardCodec;
|
||||||
|
import org.apache.solr.SolrTestCaseJ4;
|
||||||
|
import org.apache.solr.schema.SchemaField;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
|
public class TestCodecProviderSupport extends SolrTestCaseJ4 {
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void beforeClass() throws Exception {
|
||||||
|
initCore("solrconfig_codec.xml", "schema_codec.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCodecs() {
|
||||||
|
CodecProvider codecProvider = h.getCore().getCodecProvider();
|
||||||
|
Map<String, SchemaField> fields = h.getCore().getSchema().getFields();
|
||||||
|
SchemaField schemaField = fields.get("string_pulsing_f");
|
||||||
|
assertEquals("Pulsing", codecProvider.getFieldCodec(schemaField.getName()));
|
||||||
|
schemaField = fields.get("string_simpletext_f");
|
||||||
|
assertEquals("SimpleText",
|
||||||
|
codecProvider.getFieldCodec(schemaField.getName()));
|
||||||
|
schemaField = fields.get("string_standard_f");
|
||||||
|
assertEquals("Standard", codecProvider.getFieldCodec(schemaField.getName()));
|
||||||
|
schemaField = fields.get("string_f");
|
||||||
|
assertEquals("Pulsing", codecProvider.getFieldCodec(schemaField.getName()));
|
||||||
|
|
||||||
|
assertTrue(codecProvider.hasFieldCodec("string_simpletext_f"));
|
||||||
|
assertTrue(codecProvider.hasFieldCodec("string_standard_f"));
|
||||||
|
assertTrue(codecProvider.hasFieldCodec("string_f"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDynamicFields() {
|
||||||
|
CodecProvider codecProvider = h.getCore().getCodecProvider();
|
||||||
|
|
||||||
|
assertTrue(codecProvider.hasFieldCodec("bar_simple"));
|
||||||
|
assertTrue(codecProvider.hasFieldCodec("bar_pulsing"));
|
||||||
|
assertTrue(codecProvider.hasFieldCodec("bar_standard"));
|
||||||
|
|
||||||
|
assertEquals("SimpleText", codecProvider.getFieldCodec("foo_simple"));
|
||||||
|
assertEquals("Pulsing", codecProvider.getFieldCodec("foo_pulsing"));
|
||||||
|
assertEquals("Standard", codecProvider.getFieldCodec("foo_standard"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testUnmodifiable() {
|
||||||
|
CodecProvider codecProvider = h.getCore().getCodecProvider();
|
||||||
|
try {
|
||||||
|
codecProvider.setDefaultFieldCodec("foo");
|
||||||
|
fail("should be unmodifiable");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
codecProvider.setFieldCodec("foo", "bar");
|
||||||
|
fail("should be unmodifiable");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
codecProvider.register(new StandardCodec());
|
||||||
|
fail("should be unmodifiable");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
codecProvider.unregister(new StandardCodec());
|
||||||
|
fail("should be unmodifiable");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testUnknownField() {
|
||||||
|
CodecProvider codecProvider = h.getCore().getCodecProvider();
|
||||||
|
try {
|
||||||
|
codecProvider.getFieldCodec("notexisting");
|
||||||
|
fail("field is not existing");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue