blob: a0e99466f49820f160ccdf3348caad0427adb5db [file] [log] [blame]
using System;
using System.Collections.Generic;
/*
* 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.
*/
namespace org.apache.lucene.index
{
using FSDirectory = org.apache.lucene.store.FSDirectory;
/// <summary>
/// Command-line tool that enables listing segments in an
/// index, copying specific segments to another index, and
/// deleting segments from an index.
///
/// <para>This tool does file-level copying of segments files.
/// This means it's unable to split apart a single segment
/// into multiple segments. For example if your index is a
/// single segment, this tool won't help. Also, it does basic
/// file-level copying (using simple
/// File{In,Out}putStream) so it will not work with non
/// FSDirectory Directory impls.</para>
///
/// @lucene.experimental You can easily
/// accidentally remove segments from your index so be
/// careful!
/// </summary>
public class IndexSplitter
{
public SegmentInfos infos;
internal FSDirectory fsDir;
internal File dir;
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public static void main(String[] args) throws Exception
public static void Main(string[] args)
{
if (args.Length < 2)
{
Console.Error.WriteLine("Usage: IndexSplitter <srcDir> -l (list the segments and their sizes)");
Console.Error.WriteLine("IndexSplitter <srcDir> <destDir> <segments>+");
Console.Error.WriteLine("IndexSplitter <srcDir> -d (delete the following segments)");
return;
}
File srcDir = new File(args[0]);
IndexSplitter @is = new IndexSplitter(srcDir);
if (!srcDir.exists())
{
throw new Exception("srcdir:" + srcDir.AbsolutePath + " doesn't exist");
}
if (args[1].Equals("-l"))
{
@is.listSegments();
}
else if (args[1].Equals("-d"))
{
IList<string> segs = new List<string>();
for (int x = 2; x < args.Length; x++)
{
segs.Add(args[x]);
}
@is.remove(segs.ToArray());
}
else
{
File targetDir = new File(args[1]);
IList<string> segs = new List<string>();
for (int x = 2; x < args.Length; x++)
{
segs.Add(args[x]);
}
@is.Split(targetDir, segs.ToArray());
}
}
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public IndexSplitter(java.io.File dir) throws java.io.IOException
public IndexSplitter(File dir)
{
this.dir = dir;
fsDir = FSDirectory.open(dir);
infos = new SegmentInfos();
infos.read(fsDir);
}
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public void listSegments() throws java.io.IOException
public virtual void listSegments()
{
DecimalFormat formatter = new DecimalFormat("###,###.###", DecimalFormatSymbols.getInstance(Locale.ROOT));
for (int x = 0; x < infos.size(); x++)
{
SegmentCommitInfo info = infos.info(x);
string sizeStr = formatter.format(info.sizeInBytes());
Console.WriteLine(info.info.name + " " + sizeStr);
}
}
private int getIdx(string name)
{
for (int x = 0; x < infos.size(); x++)
{
if (name.Equals(infos.info(x).info.name))
{
return x;
}
}
return -1;
}
private SegmentCommitInfo getInfo(string name)
{
for (int x = 0; x < infos.size(); x++)
{
if (name.Equals(infos.info(x).info.name))
{
return infos.info(x);
}
}
return null;
}
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public void remove(String[] segs) throws java.io.IOException
public virtual void remove(string[] segs)
{
foreach (string n in segs)
{
int idx = getIdx(n);
infos.remove(idx);
}
infos.changed();
infos.commit(fsDir);
}
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public void split(java.io.File destDir, String[] segs) throws java.io.IOException
public virtual void Split(File destDir, string[] segs)
{
destDir.mkdirs();
FSDirectory destFSDir = FSDirectory.open(destDir);
SegmentInfos destInfos = new SegmentInfos();
destInfos.counter = infos.counter;
foreach (string n in segs)
{
SegmentCommitInfo infoPerCommit = getInfo(n);
SegmentInfo info = infoPerCommit.info;
// Same info just changing the dir:
SegmentInfo newInfo = new SegmentInfo(destFSDir, info.Version, info.name, info.DocCount, info.UseCompoundFile, info.Codec, info.Diagnostics);
destInfos.add(new SegmentCommitInfo(newInfo, infoPerCommit.DelCount, infoPerCommit.DelGen, infoPerCommit.FieldInfosGen));
// now copy files over
ICollection<string> files = infoPerCommit.files();
foreach (String srcName in files)
{
File srcFile = new File(dir, srcName);
File destFile = new File(destDir, srcName);
copyFile(srcFile, destFile);
}
}
destInfos.changed();
destInfos.commit(destFSDir);
// System.out.println("destDir:"+destDir.getAbsolutePath());
}
private static readonly sbyte[] copyBuffer = new sbyte[32 * 1024];
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: private static void copyFile(java.io.File src, java.io.File dst) throws java.io.IOException
private static void copyFile(File src, File dst)
{
InputStream @in = new FileInputStream(src);
OutputStream @out = new FileOutputStream(dst);
int len;
while ((len = @in.read(copyBuffer)) > 0)
{
@out.write(copyBuffer, 0, len);
}
@in.close();
@out.close();
}
}
}