blob: d6124aa9f27f0f0acf31eff929e17662056c11b3 [file] [log] [blame]
/*
* 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.solr.core;
import java.lang.invoke.MethodHandles;
import java.util.Arrays;
import java.util.Locale;
import org.apache.lucene.codecs.Codec;
import org.apache.lucene.codecs.DocValuesFormat;
import org.apache.lucene.codecs.PostingsFormat;
import org.apache.lucene.codecs.lucene87.Lucene87Codec;
import org.apache.lucene.codecs.lucene87.Lucene87Codec.Mode;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.schema.SchemaField;
import org.apache.solr.util.plugin.SolrCoreAware;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Per-field CodecFactory implementation, extends Lucene's
* and returns postings format implementations according to the
* schema configuration.
* <br>
* Also, a string argument with name <code>compressionMode</code> can be
* provided to chose between the different compression options for
* stored fields
*
* @lucene.experimental
*/
public class SchemaCodecFactory extends CodecFactory implements SolrCoreAware {
/**
* Key to use in init arguments to set the compression mode in the codec.
*/
public static final String COMPRESSION_MODE = "compressionMode";
public static final Mode SOLR_DEFAULT_COMPRESSION_MODE = Mode.BEST_SPEED;
private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private Codec codec;
private volatile SolrCore core;
// TODO: we need to change how solr does this?
// rather than a string like "Direct" you need to be able to pass parameters
// and everything to a field in the schema, e.g. we should provide factories for
// the Lucene's core formats (Memory, Direct, ...) and such.
//
// So I think a FieldType should return PostingsFormat, not a String.
// how it constructs this from the XML... i don't care.
@Override
public void inform(SolrCore core) {
this.core = core;
}
@Override
@SuppressWarnings({"rawtypes"})
public void init(NamedList args) {
super.init(args);
assert codec == null;
String compressionModeStr = (String)args.get(COMPRESSION_MODE);
Mode compressionMode;
if (compressionModeStr != null) {
try {
compressionMode = Mode.valueOf(compressionModeStr.toUpperCase(Locale.ROOT));
} catch (IllegalArgumentException e) {
throw new SolrException(ErrorCode.SERVER_ERROR,
"Invalid compressionMode: '" + compressionModeStr +
"'. Value must be one of " + Arrays.toString(Mode.values()));
}
log.debug("Using compressionMode: {}", compressionMode);
} else {
compressionMode = SOLR_DEFAULT_COMPRESSION_MODE;
log.debug("Using default compressionMode: {}", compressionMode);
}
codec = new Lucene87Codec(compressionMode) {
@Override
public PostingsFormat getPostingsFormatForField(String field) {
final SchemaField schemaField = core.getLatestSchema().getFieldOrNull(field);
if (schemaField != null) {
String postingsFormatName = schemaField.getType().getPostingsFormat();
if (postingsFormatName != null) {
return PostingsFormat.forName(postingsFormatName);
}
}
return super.getPostingsFormatForField(field);
}
@Override
public DocValuesFormat getDocValuesFormatForField(String field) {
final SchemaField schemaField = core.getLatestSchema().getFieldOrNull(field);
if (schemaField != null) {
String docValuesFormatName = schemaField.getType().getDocValuesFormat();
if (docValuesFormatName != null) {
return DocValuesFormat.forName(docValuesFormatName);
}
}
return super.getDocValuesFormatForField(field);
}
};
}
@Override
public Codec getCodec() {
assert core != null : "inform must be called first";
return codec;
}
}