/** * 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; } }