blob: 53a68a58ae47d0693f2bcbd56fe8f0e1d4153b63 [file] [log] [blame]
using Lucene.Net.Benchmarks.ByTask.Utils;
using Lucene.Net.Codecs;
using Lucene.Net.Index;
using Lucene.Net.Support;
using Lucene.Net.Util;
using System;
using System.IO;
using System.Text;
using Console = Lucene.Net.Util.SystemConsole;
namespace Lucene.Net.Benchmarks.ByTask.Tasks
{
/*
* 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.
*/
/// <summary>
/// Creates an index.
/// </summary>
/// <remarks>
/// Other side effects: index writer object in perfRunData is set.
/// <para/>
/// Relevant properties:
/// <list type="bullet">
/// <item><term>merge.factor</term><description>(default 10)</description></item>
/// <item><term>max.buffered</term><description>(default no flush)</description></item>
/// <item><term>compound</term><description>(default true)</description></item>
/// <item><term>ram.flush.mb</term><description>[default 0]</description></item>
/// <item><term>merge.policy</term><description>(default Lucene.Net.Index.LogByteSizeMergePolicy, Lucene.Net)</description></item>
/// <item><term>merge.scheduler</term><description>(default Lucene.Net.Index.ConcurrentMergeScheduler, Lucene.Net)</description></item>
/// <item><term>concurrent.merge.scheduler.max.thread.count</term><description>(defaults per ConcurrentMergeScheduler)</description></item>
/// <item><term>concurrent.merge.scheduler.max.merge.count</term><description>(defaults per ConcurrentMergeScheduler)</description></item>
/// <item><term>default.codec</term><description></description></item>
/// </list>
/// <para/>
/// This task also supports a "writer.info.stream" property with the following
/// values:
/// <list type="bullet">
/// <item><term>SystemOut</term><description>Sets <see cref="IndexWriterConfig.SetInfoStream(InfoStream)"/> to <see cref="Console.Out"/>.</description></item>
/// <item><term>SystemErr</term><description>Sets <see cref="IndexWriterConfig.SetInfoStream(InfoStream)"/> to <see cref="Console.Error"/></description></item>
/// <item><term>&lt;file_name&gt;</term><description>
/// Attempts to create a file given that name and sets <see cref="IndexWriterConfig.SetInfoStream(InfoStream)"/>
/// to that file. If this denotes an invalid file name, or some error occurs, an exception will be thrown.
/// </description></item>
/// </list>
/// </remarks>
public class CreateIndexTask : PerfTask
{
public CreateIndexTask(PerfRunData runData)
: base(runData)
{
}
public static IndexDeletionPolicy GetIndexDeletionPolicy(Config config)
{
string deletionPolicyName = config.Get("deletion.policy", "Lucene.Net.Index.KeepOnlyLastCommitDeletionPolicy, Lucene.Net");
Type deletionPolicyType = Type.GetType(deletionPolicyName);
if (deletionPolicyType == null)
{
throw new Exception("Unrecognized deletion policy type '" + deletionPolicyName + "'");
}
else if (deletionPolicyType.Equals(typeof(NoDeletionPolicy)))
{
return NoDeletionPolicy.INSTANCE;
}
else
{
try
{
return (IndexDeletionPolicy)Activator.CreateInstance(deletionPolicyType);
}
catch (Exception e)
{
throw new Exception("unable to instantiate class '" + deletionPolicyName + "' as IndexDeletionPolicy", e);
}
}
}
public override int DoLogic()
{
PerfRunData runData = RunData;
Config config = runData.Config;
runData.IndexWriter = ConfigureWriter(config, runData, OpenMode.CREATE, null);
return 1;
}
public static IndexWriterConfig CreateWriterConfig(Config config, PerfRunData runData, OpenMode mode, IndexCommit commit)
{
// :Post-Release-Update-Version.LUCENE_XY:
LuceneVersion version = (LuceneVersion)Enum.Parse(typeof(LuceneVersion), config.Get("writer.version", LuceneVersion.LUCENE_48.ToString()));
IndexWriterConfig iwConf = new IndexWriterConfig(version, runData.Analyzer);
iwConf.OpenMode = mode;
IndexDeletionPolicy indexDeletionPolicy = GetIndexDeletionPolicy(config);
iwConf.IndexDeletionPolicy = indexDeletionPolicy;
if (commit != null)
iwConf.IndexCommit = commit;
string mergeScheduler = config.Get("merge.scheduler",
"Lucene.Net.Index.ConcurrentMergeScheduler, Lucene.Net");
#if !FEATURE_CONCURRENTMERGESCHEDULER
// LUCENENET specific - hack to get our TaskMergeScheduler
// when a ConcurrentMergeScheduler is requested.
if (mergeScheduler.Contains(".ConcurrentMergeScheduler,"))
{
mergeScheduler = "Lucene.Net.Index.TaskMergeScheduler, Lucene.Net";
}
#endif
Type mergeSchedulerType = Type.GetType(mergeScheduler);
if (mergeSchedulerType == null)
{
throw new Exception("Unrecognized merge scheduler type '" + mergeScheduler + "'");
}
else if (mergeSchedulerType.Equals(typeof(NoMergeScheduler)))
{
iwConf.MergeScheduler = NoMergeScheduler.INSTANCE;
}
else
{
try
{
iwConf.MergeScheduler = (IMergeScheduler)Activator.CreateInstance(mergeSchedulerType);
}
catch (Exception e)
{
throw new Exception("unable to instantiate class '" + mergeScheduler + "' as merge scheduler", e);
}
if (mergeScheduler.Equals("Lucene.Net.Index.ConcurrentMergeScheduler", StringComparison.Ordinal))
{
#if FEATURE_CONCURRENTMERGESCHEDULER
ConcurrentMergeScheduler cms = (ConcurrentMergeScheduler)iwConf.MergeScheduler;
int maxThreadCount = config.Get("concurrent.merge.scheduler.max.thread.count", ConcurrentMergeScheduler.DEFAULT_MAX_THREAD_COUNT);
int maxMergeCount = config.Get("concurrent.merge.scheduler.max.merge.count", ConcurrentMergeScheduler.DEFAULT_MAX_MERGE_COUNT);
#else
TaskMergeScheduler cms = (TaskMergeScheduler)iwConf.MergeScheduler;
int maxThreadCount = config.Get("concurrent.merge.scheduler.max.thread.count", 1);
int maxMergeCount = config.Get("concurrent.merge.scheduler.max.merge.count", 2);
#endif
cms.SetMaxMergesAndThreads(maxMergeCount, maxThreadCount);
}
}
string defaultCodec = config.Get("default.codec", null);
if (defaultCodec != null)
{
try
{
Type clazz = Type.GetType(defaultCodec);
iwConf.Codec = (Codec)Activator.CreateInstance(clazz);
}
catch (Exception e)
{
throw new Exception("Couldn't instantiate Codec: " + defaultCodec, e);
}
}
string mergePolicy = config.Get("merge.policy",
"Lucene.Net.Index.LogByteSizeMergePolicy, Lucene.Net");
bool isCompound = config.Get("compound", true);
Type mergePolicyType = Type.GetType(mergePolicy);
if (mergePolicyType == null)
{
throw new Exception("Unrecognized merge policy type '" + mergePolicy + "'");
}
else if (mergePolicyType.Equals(typeof(NoMergePolicy)))
{
iwConf.MergePolicy = isCompound ? NoMergePolicy.COMPOUND_FILES : NoMergePolicy.NO_COMPOUND_FILES;
}
else
{
try
{
iwConf.MergePolicy = (MergePolicy)Activator.CreateInstance(mergePolicyType);
}
catch (Exception e)
{
throw new Exception("unable to instantiate class '" + mergePolicy + "' as merge policy", e);
}
iwConf.MergePolicy.NoCFSRatio = isCompound ? 1.0 : 0.0;
if (iwConf.MergePolicy is LogMergePolicy logMergePolicy)
{
logMergePolicy.MergeFactor = config.Get("merge.factor", OpenIndexTask.DEFAULT_MERGE_PFACTOR);
}
}
double ramBuffer = config.Get("ram.flush.mb", OpenIndexTask.DEFAULT_RAM_FLUSH_MB);
int maxBuffered = config.Get("max.buffered", OpenIndexTask.DEFAULT_MAX_BUFFERED);
if (maxBuffered == IndexWriterConfig.DISABLE_AUTO_FLUSH)
{
iwConf.RAMBufferSizeMB = ramBuffer;
iwConf.MaxBufferedDocs = maxBuffered;
}
else
{
iwConf.MaxBufferedDocs = maxBuffered;
iwConf.RAMBufferSizeMB = ramBuffer;
}
return iwConf;
}
public static IndexWriter ConfigureWriter(Config config, PerfRunData runData, OpenMode mode, IndexCommit commit)
{
IndexWriterConfig iwc = CreateWriterConfig(config, runData, mode, commit);
string infoStreamVal = config.Get("writer.info.stream", null);
if (infoStreamVal != null)
{
if (infoStreamVal.Equals("SystemOut", StringComparison.Ordinal))
{
iwc.SetInfoStream(Console.Out);
}
else if (infoStreamVal.Equals("SystemErr", StringComparison.Ordinal))
{
iwc.SetInfoStream(Console.Error);
}
else
{
FileInfo f = new FileInfo(infoStreamVal);
iwc.SetInfoStream(new StreamWriter(new FileStream(f.FullName, FileMode.Create, FileAccess.Write), Encoding.GetEncoding(0)));
}
}
IndexWriter writer = new IndexWriter(runData.Directory, iwc);
return writer;
}
}
}