/**
* 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.update;
import org.apache.lucene.index.*;
import org.apache.lucene.util.Version;
import org.apache.solr.core.SolrConfig;
import org.apache.solr.core.PluginInfo;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.util.SolrPluginUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
//
// For performance reasons, we don't want to re-read
// config params each time an index writer is created.
// This config object encapsulates IndexWriter config params.
//
/**
* @version $Id: SolrIndexConfig.java 1197159 2011-11-03 14:40:25Z mvg $
*/
public class SolrIndexConfig {
public static final Logger log = LoggerFactory.getLogger(SolrIndexConfig.class);
public static final String defaultsName ="indexDefaults";
final String defaultMergePolicyClassName;
public static final String DEFAULT_MERGE_SCHEDULER_CLASSNAME = ConcurrentMergeScheduler.class.getName();
static final SolrIndexConfig defaultDefaults = new SolrIndexConfig();
private SolrIndexConfig() {
luceneVersion = Version.LUCENE_31;
useCompoundFile = true;
maxBufferedDocs = -1;
maxMergeDocs = -1;
mergeFactor = -1;
ramBufferSizeMB = 16;
maxFieldLength = -1;
writeLockTimeout = -1;
lockType = null;
termIndexInterval = IndexWriterConfig.DEFAULT_TERM_INDEX_INTERVAL;
mergePolicyInfo = null;
mergeSchedulerInfo = null;
defaultMergePolicyClassName = TieredMergePolicy.class.getName();
}
public final Version luceneVersion;
public final boolean useCompoundFile;
public final int maxBufferedDocs;
public final int maxMergeDocs;
public final int mergeFactor;
public final double ramBufferSizeMB;
public final int maxFieldLength;
public final int writeLockTimeout;
public final String lockType;
public final PluginInfo mergePolicyInfo;
public final PluginInfo mergeSchedulerInfo;
public final int termIndexInterval;
public String infoStreamFile = null;
public SolrIndexConfig(SolrConfig solrConfig, String prefix, SolrIndexConfig def) {
if (prefix == null)
prefix = defaultsName;
if (def == null)
def = defaultDefaults;
luceneVersion = solrConfig.luceneMatchVersion;
defaultMergePolicyClassName = luceneVersion.onOrAfter(Version.LUCENE_33) ? TieredMergePolicy.class.getName() : LogByteSizeMergePolicy.class.getName();
useCompoundFile=solrConfig.getBool(prefix+"/useCompoundFile", def.useCompoundFile);
maxBufferedDocs=solrConfig.getInt(prefix+"/maxBufferedDocs",def.maxBufferedDocs);
maxMergeDocs=solrConfig.getInt(prefix+"/maxMergeDocs",def.maxMergeDocs);
mergeFactor=solrConfig.getInt(prefix+"/mergeFactor",def.mergeFactor);
ramBufferSizeMB = solrConfig.getDouble(prefix+"/ramBufferSizeMB", def.ramBufferSizeMB);
maxFieldLength=solrConfig.getInt(prefix+"/maxFieldLength",def.maxFieldLength);
writeLockTimeout=solrConfig.getInt(prefix+"/writeLockTimeout", def.writeLockTimeout);
lockType=solrConfig.get(prefix+"/lockType", def.lockType);
String str = solrConfig.get(prefix+"/mergeScheduler/text()",null);
if(str != null && str.trim().length() >0){
//legacy handling <mergeScheduler>[classname]</mergeScheduler>
//remove in Solr2.0
log.warn("deprecated syntax : <mergeScheduler>[classname]</mergeScheduler>");
Map<String,String> atrs = new HashMap<String, String>();
atrs.put("class",str.trim());
mergeSchedulerInfo = new PluginInfo("mergeScheduler",atrs,null,null);
} else {
mergeSchedulerInfo = getPluginInfo(prefix + "/mergeScheduler", solrConfig, def.mergeSchedulerInfo);
}
str = solrConfig.get(prefix+"/mergePolicy/text()",null);
if(str != null && str.trim().length() >0){
//legacy handling <mergePolicy>[classname]</mergePolicy>
//remove in Solr2.0
log.warn("deprecated syntax : <mergePolicy>[classname]</mergePolicy>");
Map<String,String> atrs = new HashMap<String, String>();
atrs.put("class",str.trim());
mergePolicyInfo = new PluginInfo("mergePolicy",atrs,null,null);
} else {
mergePolicyInfo = getPluginInfo(prefix + "/mergePolicy", solrConfig, def.mergePolicyInfo);
}
Object luceneAutoCommit = solrConfig.get(prefix + "/luceneAutoCommit", null);
if(luceneAutoCommit != null) {
log.warn("found deprecated option : luceneAutoCommit no longer has any affect - it is always false");
}
termIndexInterval = solrConfig.getInt(prefix + "/termIndexInterval", def.termIndexInterval);
boolean infoStreamEnabled = solrConfig.getBool(prefix + "/infoStream", false);
if(infoStreamEnabled) {
infoStreamFile= solrConfig.get(prefix + "/infoStream/@file", null);
log.info("IndexWriter infoStream debug log is enabled: " + infoStreamFile);
}
}
private PluginInfo getPluginInfo(String path, SolrConfig solrConfig, PluginInfo def) {
List<PluginInfo> l = solrConfig.readPluginInfos(path, false, true);
return l.isEmpty() ? def : l.get(0);
}
public IndexWriterConfig toIndexWriterConfig(IndexSchema schema) {
IndexWriterConfig iwc = new IndexWriterConfig(luceneVersion, schema.getAnalyzer());
if (maxBufferedDocs != -1)
iwc.setMaxBufferedDocs(maxBufferedDocs);
if (ramBufferSizeMB != -1)
iwc.setRAMBufferSizeMB(ramBufferSizeMB);
if (termIndexInterval != -1)
iwc.setTermIndexInterval(termIndexInterval);
if (writeLockTimeout != -1)
iwc.setWriteLockTimeout(writeLockTimeout);
iwc.setSimilarity(schema.getSimilarity());
iwc.setMergePolicy(buildMergePolicy(schema));
iwc.setMergeScheduler(buildMergeScheduler(schema));
return iwc;
}
private MergePolicy buildMergePolicy(IndexSchema schema) {
MergePolicy policy;
String mpClassName = mergePolicyInfo == null ? defaultMergePolicyClassName : mergePolicyInfo.className;
try {
policy = (MergePolicy) schema.getResourceLoader().newInstance(mpClassName, null, new Class[]{IndexWriter.class}, new Object[]{this});
} catch (Exception e) {
policy = (MergePolicy) schema.getResourceLoader().newInstance(mpClassName);
}
if (policy instanceof LogMergePolicy) {
LogMergePolicy logMergePolicy = (LogMergePolicy) policy;
if (maxMergeDocs != -1)
logMergePolicy.setMaxMergeDocs(maxMergeDocs);
logMergePolicy.setUseCompoundFile(useCompoundFile);
if (mergeFactor != -1)
logMergePolicy.setMergeFactor(mergeFactor);
} else if (policy instanceof TieredMergePolicy) {
TieredMergePolicy tieredMergePolicy = (TieredMergePolicy) policy;
tieredMergePolicy.setUseCompoundFile(useCompoundFile);
if (mergeFactor != -1) {
tieredMergePolicy.setMaxMergeAtOnce(mergeFactor);
tieredMergePolicy.setSegmentsPerTier(mergeFactor);
}
} else {
log.warn("Use of compound file format or mergefactor cannot be configured if merge policy is not an instance of LogMergePolicy or TieredMergePolicy. The configured policy's defaults will be used.");
}
if (mergePolicyInfo != null)
SolrPluginUtils.invokeSetters(policy, mergePolicyInfo.initArgs);
return policy;
}
private MergeScheduler buildMergeScheduler(IndexSchema schema) {
String msClassName = mergeSchedulerInfo == null ? SolrIndexConfig.DEFAULT_MERGE_SCHEDULER_CLASSNAME : mergeSchedulerInfo.className;
MergeScheduler scheduler = (MergeScheduler) schema.getResourceLoader().newInstance(msClassName);
if (mergeSchedulerInfo != null)
SolrPluginUtils.invokeSetters(scheduler, mergeSchedulerInfo.initArgs);
return scheduler;
}
}